diff options
-rwxr-xr-x | bin/just-lock.py | 44 | ||||
-rw-r--r-- | doc/future-designs/just-lock.md | 8 | ||||
-rw-r--r-- | share/man/just-lock-config.5.md | 15 | ||||
-rw-r--r-- | test/end-to-end/just-lock/file-imports.sh | 6 |
4 files changed, 50 insertions, 23 deletions
diff --git a/bin/just-lock.py b/bin/just-lock.py index 3f1ed1ae..1639a656 100755 --- a/bin/just-lock.py +++ b/bin/just-lock.py @@ -745,8 +745,29 @@ def rewrite_file_repo(repo: Json, remote_type: str, remote_stub: Dict[str, Any], fail("Unsupported remote type!") +def update_pragmas(repo: Json, pragma: Json) -> Json: + """Update the description with any input-provided "absent" and "to_git" + pragmas, as needed: + - for all repositories, merge the "absent" pragma + - for "file"-type repositories, merge the "to_git" pragma""" + existing: Json = dict(repo.get("pragma", {})) # operate on copy + # all repos support "absent pragma" + absent: bool = existing.get("absent", False) or pragma.get("absent", False) + if absent: + existing["absent"] = True + # support "to_git" pragma for "file"-type repos + if repo.get("type") == "file": + to_git = existing.get("to_git", False) or pragma.get("to_git", False) + if to_git: + existing["to_git"] = True + # all other pragmas as kept; if no pragma was set, do not set any + if existing: + repo = dict(repo, **{"pragma": existing}) + return repo + + def rewrite_repo(repo_spec: Json, *, remote_type: str, - remote_stub: Dict[str, Any], assign: Json, absent: bool, + remote_stub: Dict[str, Any], assign: Json, pragma: Json, as_layer: bool, fail_context: str) -> Json: """Rewrite description of imported repositories.""" new_spec: Json = {} @@ -766,8 +787,9 @@ def rewrite_repo(repo_spec: Json, *, remote_type: str, elif repo.get("type") in ["computed", "tree structure"]: target: str = repo.get("repo", None) repo = dict(repo, **{"repo": assign[target]}) - if absent and isinstance(repo, dict): - repo["pragma"] = dict(repo.get("pragma", {}), **{"absent": True}) + # update pragmas, as needed + if isinstance(repo, dict): + repo = update_pragmas(repo, pragma) new_spec["repository"] = repo # rewrite other roots and bindings, if actually needed to be imported if not as_layer: @@ -823,19 +845,13 @@ def handle_import(remote_type: str, remote_stub: Dict[str, Any], % (json.dumps(import_map, indent=2), )) pragma: Json = repo_desc.get("pragma", None) - if pragma is not None and not isinstance(pragma, dict): + if pragma is None: + pragma = {} + elif not isinstance(pragma, dict): fail( fail_context + "Expected \"repos\" entry subfield \"pragma\" to be a map, but found:\n%r" % (json.dumps(pragma, indent=2), )) - absent: bool = False if pragma is None else pragma.get("absent", False) - if absent is None: - absent = False - elif not isinstance(absent, bool): - fail( - fail_context + - "Expected \"repos\" entry pragma \"absent\" to be a bool, but found:\n%r" - % (json.dumps(absent, indent=2), )) # Handle import with renaming foreign_repos: Json = foreign_config.get("repositories", {}) @@ -869,7 +885,7 @@ def handle_import(remote_type: str, remote_stub: Dict[str, Any], remote_type=remote_type, remote_stub=remote_stub, assign=total_assign, - absent=absent, + pragma=pragma, as_layer=False, fail_context=fail_context) for repo in extra_imports: @@ -877,7 +893,7 @@ def handle_import(remote_type: str, remote_stub: Dict[str, Any], remote_type=remote_type, remote_stub=remote_stub, assign=total_assign, - absent=absent, + pragma=pragma, as_layer=True, fail_context=fail_context) diff --git a/doc/future-designs/just-lock.md b/doc/future-designs/just-lock.md index 0ee3bf62..151625c1 100644 --- a/doc/future-designs/just-lock.md +++ b/doc/future-designs/just-lock.md @@ -264,7 +264,9 @@ The type of a _source_ is defined by the string value of the mandatory subfield checkout. The checkout is assumed to be maintained, so that `"file"`-type repositories - marked to be imported can retain their type. + marked to be imported can retain their type. For such transitive dependencies, + one can also set the `"to_git": true` pragma with a corresponding entry in the + usual `"pragma"` field. Proposed format: ``` jsonc @@ -277,7 +279,9 @@ The type of a _source_ is defined by the string value of the mandatory subfield , "repo": "<foreign_name>" // optional; corresponds to `foreign_repository_name` var , "map": {"from_name": "to_name"} // optional; corresponds to `import_map` var (option --map) , "pragma": // optional - {"absent": true} // corresponds to `absent` var (option --absent) + { "absent": true // corresponds to `absent` var (option --absent) + , "to_git": true // any imported "file"-repositories will also be "to_git":true + } } , ... ] diff --git a/share/man/just-lock-config.5.md b/share/man/just-lock-config.5.md index f90378ff..5ae901fb 100644 --- a/share/man/just-lock-config.5.md +++ b/share/man/just-lock-config.5.md @@ -40,16 +40,19 @@ The following fields are supported: and its value is used instead. - *`"map"`* has as value a JSON object with string key-value pairs defining a - mapping between repository names that would be brought in by this import + mapping between repository names that would be brought in by this import (possibly transitively) and already imported repositories. This mapping can be used to avoid additional duplications of repositories from multiple imports. This entry is optional. - - *`"pragma"`* has as value a JSON object. Currently, it supports the key - *`"absent"`* with a boolean value; if this field evaluates to `true`, it - informs that the imported repository and all transitive repositories imported - as a consequence should have the `{"absent": true}` pragma added to their - description in the output configuration. This entry is optional. + - *`"pragma"`* has as value a JSON object. This entry is optional. + If the object contains the `{"absent": true}` object, it informs that the + imported repository and all transitive repositories imported as a + consequence should have the `{"absent": true}` pragma added to their + description. + If the object contains the `{"to_git": true}` object, it informs that all + `"file"`-type repositories brought in as a consequence of this import should + have the `{"to_git": true}` pragma added to their description. Source objects -------------- diff --git a/test/end-to-end/just-lock/file-imports.sh b/test/end-to-end/just-lock/file-imports.sh index 71dc5edc..e61ac834 100644 --- a/test/end-to-end/just-lock/file-imports.sh +++ b/test/end-to-end/just-lock/file-imports.sh @@ -77,7 +77,7 @@ cat > repos.in.json <<EOF } , "imports": [ { "source": "file" - , "repos": [{"alias": "foo"}] + , "repos": [{"alias": "foo", "pragma": {"to_git": true}}] , "path": "${REPO_DIRS}/foo" } , { "source": "file" @@ -94,6 +94,10 @@ echo "${JUST_LOCK}" -C repos.in.json -o repos.json --local-build-root "${LBR}" 2>&1 cat repos.json echo +# Check pragmas for repo "foo" are correctly set +[ $(jq -r '.repositories.foo.repository.pragma.special' repos.json) = "resolve-completely" ] +[ $(jq -r '.repositories.foo.repository.pragma.to_git' repos.json) = true ] +# Check the symlink gets resolved as expected "${JUST_MR}" -L '["env", "PATH='"${PATH}"'"]' --norc --just "${JUST}" --local-build-root "${LBR}" install -o "${OUT}" 2>&1 echo cat "${OUT}/out.txt" |