diff --git a/JSON.md b/JSON.md index bb946f8a..0b61ff1d 100644 --- a/JSON.md +++ b/JSON.md @@ -264,6 +264,9 @@ In `cfbs.json`'s `"steps"`, the build step name must be separated from the rest - Converts the input data for a module into the augments format and merges it with the target augments file. - Source is relative to module directory and target is relative to `out/masterfiles`. - In most cases, the build step should be: `input ./input.json def.json` +- `replace_version ` + - Replace the string inside the file with the version number of that module. + - The module must have a version and the string must occur exactly once in the file. When `def.json` is modified during a `json`, `input`, `directory`, `bundles`, or `policy_files` build step, the values of some lists of strings are deduplicated, when this does not make any difference in behavior. These cases are: diff --git a/cfbs/build.py b/cfbs/build.py index f81771ee..7c8edca7 100644 --- a/cfbs/build.py +++ b/cfbs/build.py @@ -30,6 +30,7 @@ "input": 2, "policy_files": "1+", "bundles": "1+", + "replace_version": 2, # string to replace and filename } @@ -259,6 +260,41 @@ def _perform_build_step(module, step, max_length): merged = augment log.debug("Merged def.json: %s", pretty(merged)) write_json(path, merged) + elif operation == "replace_version": + assert len(args) == 2 + print("%s replace_version '%s'" % (prefix, "' '".join(args))) + file = os.path.join(destination, args[1]) + if not os.path.isfile(file): + user_error( + "No such file '%s' in replace_version for module '%s" + % (file, module["name"]) + ) + try: + with open(file, "r") as f: + content = f.read() + except: + user_error( + "Could not open/read '%s' in replace_version for module '%s" + % (file, module["name"]) + ) + to_replace = args[0] + version = module["version"] + new_content = content.replace(to_replace, version, 1) + if new_content == content: + user_error( + "replace_version requires that '%s' has exactly 1 occurence of '%s' - 0 found" + % (file, to_replace) + ) + if to_replace in new_content: + user_error( + "replace_version requires that '%s' has exactly 1 occurence of '%s' - more than 1 found" + % (file, to_replace) + ) + try: + with open(file, "w") as f: + f.write(new_content) + except: + user_error("Failed to write to '%s'" % (file,)) def perform_build(config) -> int: diff --git a/tests/shell/043_replace_version.sh b/tests/shell/043_replace_version.sh new file mode 100644 index 00000000..b5dfe377 --- /dev/null +++ b/tests/shell/043_replace_version.sh @@ -0,0 +1,27 @@ +set -e +set -x +cd tests/ +mkdir -p ./tmp/ +cd ./tmp/ + +# Set up the project we will build: +cp ../shell/043_replace_version/example-cfbs.json ./cfbs.json +mkdir -p subdir +cp ../shell/043_replace_version/subdir/example.py ./subdir/example.py + +# Before building, version number is 0.0.0: +grep 'print("Version: 0.0.0")' ./subdir/example.py +! grep 'print("Version: 1.2.3")' ./subdir/example.py + +cfbs build + +# After building, input and output should be different: +! diff ./subdir/example.py ./out/masterfiles/services/cfbs/subdir/example.py + +# Check that version number is correct in output: +grep 'print("Version: 1.2.3")' ./out/masterfiles/services/cfbs/subdir/example.py +! grep 'print("Version: 0.0.0")' ./out/masterfiles/services/cfbs/subdir/example.py + +# Also check that the input was not modified: +grep 'print("Version: 0.0.0")' ./subdir/example.py +! grep 'print("Version: 1.2.3")' ./subdir/example.py diff --git a/tests/shell/043_replace_version/example-cfbs.json b/tests/shell/043_replace_version/example-cfbs.json new file mode 100644 index 00000000..54f1e458 --- /dev/null +++ b/tests/shell/043_replace_version/example-cfbs.json @@ -0,0 +1,18 @@ +{ + "name": "Example project", + "description": "Example description", + "type": "policy-set", + "git": true, + "build": [ + { + "name": "./subdir/", + "description": "Local subdirectory added using cfbs command line", + "added_by": "cfbs add", + "version": "1.2.3", + "steps": [ + "copy example.py services/cfbs/subdir/example.py", + "replace_version 0.0.0 services/cfbs/subdir/example.py" + ] + } + ] +} diff --git a/tests/shell/043_replace_version/subdir/example.py b/tests/shell/043_replace_version/subdir/example.py new file mode 100644 index 00000000..48761a74 --- /dev/null +++ b/tests/shell/043_replace_version/subdir/example.py @@ -0,0 +1,2 @@ +if __name__ == "__main__": + print("Version: 0.0.0") diff --git a/tests/shell/all.sh b/tests/shell/all.sh index 259f2963..ed6c5272 100644 --- a/tests/shell/all.sh +++ b/tests/shell/all.sh @@ -46,5 +46,6 @@ bash tests/shell/039_add_added_by_field_update_1.sh bash tests/shell/040_add_added_by_field_update_2.sh bash tests/shell/041_add_multidep.sh bash tests/shell/042_update_from_url.sh +bash tests/shell/043_replace_version.sh echo "All cfbs shell tests completed successfully!"