diff --git a/conans/client/command.py b/conans/client/command.py index 08ce1705ad4..5c482946c73 100644 --- a/conans/client/command.py +++ b/conans/client/command.py @@ -1432,9 +1432,14 @@ def workspace(self, *args): prog="conan workspace") subparsers = parser.add_subparsers(dest='subcommand', help='sub-command help') - install_parser = subparsers.add_parser('install', help='same as a "conan install" command ' - 'but using the workspace data from the file') - install_parser.add_argument('path', help='path to workspace definition file') + install_parser = subparsers.add_parser('install', + help='same as a "conan install" command' + ' but using the workspace data from the file. If' + ' no file is provided, it will look for a file' + ' named "conanws.yml"') + install_parser.add_argument('path', help='path to workspace definition file (it will look' + ' for a "conanws.yml" inside if a directory is' + ' given)') _add_common_install_arguments(install_parser, build_help=_help_build_policies) args = parser.parse_args(*args) diff --git a/conans/model/workspace.py b/conans/model/workspace.py index e8d9762cf3b..3703d0012f8 100644 --- a/conans/model/workspace.py +++ b/conans/model/workspace.py @@ -39,6 +39,7 @@ def root_folder(self): class Workspace(object): + default_filename = "conanws.yml" def generate(self, cwd, graph, output): if self._ws_generator == "cmake": @@ -90,6 +91,10 @@ def __init__(self, path, cache): self._cache = cache self._ws_generator = None self._workspace_packages = OrderedDict() # {reference: LocalPackage} + + if not os.path.isfile(path): + path = os.path.join(path, self.default_filename) + self._base_folder = os.path.dirname(path) try: content = load(path) diff --git a/conans/test/functional/workspace/workspace_test.py b/conans/test/functional/workspace/workspace_test.py index 0373e6ee6a6..03d7485573a 100644 --- a/conans/test/functional/workspace/workspace_test.py +++ b/conans/test/functional/workspace/workspace_test.py @@ -924,3 +924,55 @@ def files(name, depend=None): for p in ("HelloC", "HelloB", "HelloA"): self.assertIn("add_subdirectory(${PACKAGE_%s_SRC} ${PACKAGE_%s_BUILD})" % (p, p), conanws_cmake) + + def test_default_filename(self): + client = TestClient() + path_to_editable = os.path.join(client.current_folder, "A") + + project = dedent(""" + editables: + HelloA/0.1@lasote/stable: + path: {path_to_editable} + layout: layout + workspace_generator: cmake + root: HelloA/0.1@lasote/stable + """.format(path_to_editable=path_to_editable)) + + conanfile = dedent(""" + from conans import ConanFile + + class Lib(ConanFile): + pass + """) + + layout = dedent(""" + [build_folder] + [source_folder] + """) + + client.save({"conanfile.py": conanfile}, path=path_to_editable) + ws_folder = temp_folder() + client.save({os.path.join(ws_folder, Workspace.default_filename): project, + os.path.join(ws_folder, "layout"): layout}) + + # For the right folder, it works + client.run('workspace install "{}"'.format(ws_folder)) + conanws_cmake = load(os.path.join(client.current_folder, "conanworkspace.cmake")) + self.assertIn("macro(conan_workspace_subdirectories)", conanws_cmake) + + # For a non existing folder, it will try to load the default filename (it fails) + non_existing = temp_folder() + client.run('workspace install "{}"'.format(non_existing), assert_error=True) + trial_path = os.path.join(non_existing, Workspace.default_filename) + self.assertIn("ERROR: Couldn't load workspace file in {}".format(trial_path), client.out) + + # For an existing file, it will try to use it (will fail because of the format) + invalid_file = os.path.join(ws_folder, "layout") + client.run('workspace install "{}"'.format(invalid_file), assert_error=True) + self.assertIn("ERROR: There was an error parsing", client.out) + + # For an existing folder, without the default file (it will fail looking for it) + no_default_file = os.path.join(client.current_folder) + client.run('workspace install "{}"'.format(no_default_file), assert_error=True) + trial_path = os.path.join(no_default_file, Workspace.default_filename) + self.assertIn("ERROR: Couldn't load workspace file in {}".format(trial_path), client.out)