conan: [question] ERROR: Attempt to modify locked lib when trying to create recipe revision lockfile

We are following through the examples in https://docs.conan.io/en/latest/versioning/lockfiles/ci.html#package-pipeline and we get to a point where we have already run the “package” lockfile creation steps:

$ cd libb

# Derive one lockfile per profile/configuration
$ conan lock create conanfile.py --name=libb --version=0.2
  --user=user --channel=testing --lockfile=../locks/libb_deps_base.lock
  --lockfile-out=../locks/libb_deps_debug.lock -s build_type=Debug
$ conan lock create conanfile.py --name=libb --version=0.2
  --user=user --channel=testing --lockfile=../locks/libb_deps_base.lock
  --lockfile-out=../locks/libb_deps_release.lock

# Create the package binaries, one with each lockfile
$ conan create . libb/0.2@user/testing --lockfile=../locks/libb_deps_release.lock
$ conan create . libb/0.2@user/testing --lockfile=../locks/libb_deps_debug.lock

and now we were looking at this optional step:

When using revisions (not this example), it is important to capture the recipe revision, and lock it too. We can capture the recipe revision doing an export, creating a new libb_base.lock lockfile:

So we ran in our CI after the steps above:

 conan export . libb/0.2@user/testing --lockfile=../locks/libb_deps_base.lock
  --lockfile-out=../locks/libb_base.lock

But we get this output (note: we used slightly different lockfile output names to be clearer about package versus recipe lockfiles):

2020-12-14 05:31:31 |  [Conan_pipeline_master] $ cmd.exe /C "conan export . libb/0.2@conan/stable --lockfile=package_deps_base.lock --lockfile-out=recipe_base.lock && exit %%ERRORLEVEL%%"
2020-12-14 05:31:33 |  [HOOK - attribute_checker.py] pre_export(): WARN: Conanfile doesn't have 'url'. It is recommended to add it as attribute
2020-12-14 05:31:33 |  [HOOK - attribute_checker.py] pre_export(): WARN: Conanfile doesn't have 'license'. It is recommended to add it as attribute
2020-12-14 05:31:33 |  [HOOK - attribute_checker.py] pre_export(): WARN: Conanfile doesn't have 'description'. It is recommended to add it as attribute
2020-12-14 05:31:33 |  ERROR: Attempt to modify locked libb/0.2 to libb/0.2@conan/stable#e7e83409e3735f8c2a464f151e66f011

Question: Can I ask what we’ve done wrong?

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 19 (7 by maintainers)

Most upvoted comments

Hi @michaelmaguire

Let me try to clarify:

  • https://github.com/conan-io/examples/blob/master/features/lockfiles/ci/build.py#L73 is doing:

    conan lock create conanfile.py --name=libb --version=0.2 "
              "--user=user --channel=testing --lockfile-out=../locks/libb_deps_base.lock --base
    

    That is capturing a “recipes information only” lockfile of the dependencies of libb (in this case liba/0.1)

  • Next step is doing an export of the changes done to lib, under a new 0.2 version:

    conan export . libb/0.2@user/testing --lockfile=../locks/libb_deps_base.lock "
              "--lockfile-out=../locks/libb_base.lock
    

    The export command does not compute the graph, the dependencies or the packages. The output libb_base.lock is still a recipes-only lockfile, with the main change compared to libb_deps_base.lock of having the full reference to libb/0.2@user/testing, including the recipe revision, in the lockfile

  • Next step is to create full configuration lockfiles with:

 conan lock create conanfile.py --name=libb --version=0.2 "
           "--user=user --channel=testing --lockfile=../locks/libb_base.lock --lockfile-out=../locks/libb_deps_debug.lock -s build_type=Debug

This will be creating the complete lockfile, including package-ids, package revisions, locking the binaries that will be used for liba/0.1

So the presented flow is “recipe (local path)” -> “recipe (exported lib/0.2)” -> “package (one per config)”

The example is illustrative of the things that can be done and how lockfiles work. You might skip the first step, export the libb/0.2 changes, then capture the initial “base” lockfile just before capturing the 2 configuration lockfiles from the base one. Just make sure that the lockfile is captured before the unwanted liba/0.2 changes.

Does it make sense now? Thanks!

Hi @michaelmaguire

I think the error comes from the difference in user/channel when you capture the lockfile and when you try to use it. Note that a different user/channel could completely change the dependency graph, so the user/channel used at create should match the one at later step.

So use something like:

$ conan lock create ./conanfile.py --user=conan --channel=stable ...

Then inspect the lockfile json file. You will see that conan/stable is part of the reference. Then when you run

$ conan export . libb/0.2@conan/stable --lockfile=...
# or
$ conan create . libb/0.2@conan/stable --lockfile=...

Please let me know if this makes sense and it works as expected. Thanks!