Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added new lock install <lockfile> command #8021

Merged
merged 7 commits into from Mar 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 10 additions & 1 deletion conans/client/command.py
Expand Up @@ -1884,6 +1884,13 @@ def lock(self, *args):
clean_modified_cmd = subparsers.add_parser('clean-modified', help='Clean modified flags')
clean_modified_cmd.add_argument('lockfile', help='Path to the lockfile')

install_cmd = subparsers.add_parser('install', help='Install a lockfile')
install_cmd.add_argument('lockfile', help='Path to the lockfile')
install_cmd.add_argument("--recipes", action="store_true",
help="Install only recipes, not binaries")
install_cmd.add_argument("-g", "--generator", nargs=1, action=Extender,
help='Generators to use')

create_cmd = subparsers.add_parser('create',
help='Create a lockfile from a conanfile or a reference')
create_cmd.add_argument("path", nargs="?", help="Path to a conanfile")
Expand Down Expand Up @@ -1926,7 +1933,9 @@ def lock(self, *args):
args = parser.parse_args(*args)
self._warn_python_version()

if args.subcommand == "update":
if args.subcommand == "install":
self._conan.lock_install(args.lockfile, generators=args.generator, recipes=args.recipes)
elif args.subcommand == "update":
self._conan.lock_update(args.old_lockfile, args.new_lockfile)
elif args.subcommand == "bundle":
if args.bundlecommand == "create":
Expand Down
37 changes: 37 additions & 0 deletions conans/client/conan_api.py
Expand Up @@ -1342,6 +1342,43 @@ def lock_clean_modified(self, lockfile, cwd=None):
graph_lock.clean_modified()
graph_lock_file.save(lockfile)

@api_method
def lock_install(self, lockfile, remote_name=None, build=None,
generators=None, install_folder=None, cwd=None,
lockfile_out=None, recipes=None):
lockfile = _make_abs_path(lockfile, cwd) if lockfile else None
graph_info = get_graph_info(None, None, cwd, None,
self.app.cache, self.app.out, lockfile=lockfile)

if not generators: # We don't want the default txt
generators = False

install_folder = _make_abs_path(install_folder, cwd)

mkdir(install_folder)
remotes = self.app.load_remotes(remote_name=remote_name)
recorder = ActionRecorder()
graph_lock = graph_info.graph_lock
root_id = graph_lock.root_node_id()
reference = graph_lock.nodes[root_id].ref
if recipes:
graph = self.app.graph_manager.load_graph(reference, create_reference=None,
graph_info=graph_info, build_mode=None,
check_updates=False, update=None,
remotes=remotes, recorder=recorder,
lockfile_node_id=root_id)
print_graph(graph, self.app.out)
else:
deps_install(self.app, ref_or_path=reference, install_folder=install_folder,
remotes=remotes, graph_info=graph_info, build_modes=build,
generators=generators, recorder=recorder, lockfile_node_id=root_id)

if lockfile_out:
lockfile_out = _make_abs_path(lockfile_out, cwd)
graph_lock_file = GraphLockFile(graph_info.profile_host, graph_info.profile_build,
graph_info.graph_lock)
graph_lock_file.save(lockfile_out)

@api_method
def lock_bundle_create(self, lockfiles, lockfile_out, cwd=None):
cwd = cwd or os.getcwd()
Expand Down
2 changes: 1 addition & 1 deletion conans/client/manager.py
Expand Up @@ -35,8 +35,8 @@ def deps_install(app, ref_or_path, install_folder, graph_info, remotes=None, bui
@param generators: List of generators from command line. If False, no generator will be
written
@param no_imports: Install specified packages but avoid running imports

"""

out, user_io, graph_manager, cache = app.out, app.user_io, app.graph_manager, app.cache
remote_manager, hook_manager = app.remote_manager, app.hook_manager
profile_host, profile_build = graph_info.profile_host, graph_info.profile_build
Expand Down
50 changes: 50 additions & 0 deletions conans/test/functional/graph_lock/lock_install_test.py
@@ -0,0 +1,50 @@
from conans.test.utils.tools import TestClient, GenConanfile


def test_install():
client = TestClient()
client.save({"conanfile.py": GenConanfile("pkga", "0.1").with_package_file("file.h", "0.1")})
client.run("create . user/channel")

# Use a consumer with a version range
client.save({"conanfile.py":
GenConanfile("pkgb", "0.1").with_require("pkga/[>=0.1]@user/channel")})
client.run("create . user/channel")
client.run("lock create --reference=pkgb/0.1@user/channel --lockfile-out=lock1.lock")

# We can create a pkga/0.2, but it will not be used
client.save({"conanfile.py": GenConanfile("pkga", "0.2").with_package_file("file.h", "0.2")})
client.run("create . user/channel")

client.run("lock install lock1.lock -g deploy")
assert "pkga/0.1@user/channel from local cache" in client.out
file_h = client.load("pkga/file.h")
assert file_h == "0.1"


def test_install_recipes():
client = TestClient(default_server_user=True)
client.save({"conanfile.py": GenConanfile("pkga", "0.1").with_package_file("file.h", "0.1")})
client.run("create . user/channel")

# Use a consumer with a version range
client.save({"conanfile.py":
GenConanfile("pkgb", "0.1").with_require("pkga/[>=0.1]@user/channel")})
client.run("create . user/channel")
client.run("lock create --reference=pkgb/0.1@user/channel --lockfile-out=lock1.lock")

# We can create a pkga/0.2, but it will not be used
client.save({"conanfile.py": GenConanfile("pkga", "0.2").with_package_file("file.h", "0.2")})
client.run("create . user/channel")

client.run("lock install lock1.lock --recipes")
assert "pkga/0.1@user/channel:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache" in client.out
assert "pkgb/0.1@user/channel:cfd10f60aeaa00f5ca1f90b5fe97c3fe19e7ec23 - Cache" in client.out

client.run("upload * --all -c")
client.run("remove * -f")
client.run("lock install lock1.lock --recipes")

assert "pkga/0.1@user/channel:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Download" in client.out
assert "pkgb/0.1@user/channel:cfd10f60aeaa00f5ca1f90b5fe97c3fe19e7ec23 - Download" in client.out