diff --git a/tests/pkg/assets/install/gold/40-exec.gold b/tests/pkg/assets/install/gold/40-exec.gold new file mode 100644 index 000000000..2fe6c559e --- /dev/null +++ b/tests/pkg/assets/install/gold/40-exec.gold @@ -0,0 +1,5 @@ +exec main.toit +hello from foo 1.2.3 +hello from bar 2.0.1 +hello from target +Exit Code: 0 diff --git a/tests/pkg/git-pkg2-gold-test.toit b/tests/pkg/git-pkg2-gold-test.toit index 3bb77d6fd..d86bbe89c 100644 --- a/tests/pkg/git-pkg2-gold-test.toit +++ b/tests/pkg/git-pkg2-gold-test.toit @@ -5,6 +5,8 @@ import expect show * import host.file import fs +import system + import .gold-tester main args: @@ -47,3 +49,15 @@ test tester/GoldTester: readme-path := fs.join tester.working-dir ".packages" "README.md" expect (file.is-file readme-path) + + foo-path := tester.package-cache-path "pkg/foo" --version="1.2.3" + yaml-path := fs.join foo-path "package.yaml" + expect (file.is-file yaml-path) + stat := file.stat yaml-path + expect-not-null stat + mode := stat[file.ST-MODE] + if system.platform == system.PLATFORM-WINDOWS: + expect (mode & file.WINDOWS-FILE-ATTRIBUTE-READONLY) != 0 + else: + write-bits := 0b010_010_010 + expect-equals 0 (mode & write-bits) diff --git a/tests/pkg/gold-tester.toit b/tests/pkg/gold-tester.toit index b03de6b83..345c5511c 100644 --- a/tests/pkg/gold-tester.toit +++ b/tests/pkg/gold-tester.toit @@ -33,7 +33,7 @@ with-tmp-dir [block]: try: block.call tmp-dir finally: - directory.rmdir --recursive tmp-dir + directory.rmdir --force --recursive tmp-dir class RunResult_: stdout/string @@ -82,6 +82,14 @@ class GoldTester: working-dir -> string: return working-dir_ + package-cache-path pkg-suffix/string --version/string -> string: + bytes := file.read-contents "$working-dir_/.packages/contents.json" + packages := json.decode bytes + packages.do: | pkg-name/string pkg-info/Map | + if pkg-name.ends-with pkg-suffix: + return fs.join working-dir_ ".packages" pkg-info[version] + unreachable + normalize str/string -> string: str = str.replace --all "localhost:$port_" "localhost:<[*PORT*]>" // In lock files, the ':' is replaced with '_'. diff --git a/tests/pkg/install-gold-test.toit b/tests/pkg/install-gold-test.toit index 20689b71f..4d37042f8 100644 --- a/tests/pkg/install-gold-test.toit +++ b/tests/pkg/install-gold-test.toit @@ -20,24 +20,13 @@ test tester/GoldTester: ["exec", "main.toit"], ] - contents := file.read-contents "$tester.working-dir/.packages/contents.json" - mapping/Map := json.decode contents - - foo-url/string? := null - bar-url/string? := null - mapping.do --keys: | key | - if key.ends-with "pkg/foo": foo-url = key - if key.ends-with "pkg/bar": bar-url = key - foo-version := "1.2.3" - foo-rel-path := mapping[foo-url][foo-version] - foo-path := "$tester.working-dir/.packages/$foo-rel-path" + foo-path := tester.package-cache-path "pkg/foo" --version=foo-version expect (file.is-directory foo-path) directory.rmdir --recursive --force foo-path bar-version := "2.0.1" - bar-rel-path := mapping[bar-url][bar-version] - bar-path := "$tester.working-dir/.packages/$bar-rel-path" + bar-path := tester.package-cache-path "pkg/bar" --version=bar-version expect (file.is-directory bar-path) directory.rmdir --recursive --force bar-path @@ -49,19 +38,15 @@ test tester/GoldTester: ["pkg", "install"], ] + tester.gold "40-exec" [ + ["exec", "main.toit"], + ] + // Ensure that the directories are back. // We don't guarantee that the directories are the same as before. - contents = file.read-contents "$tester.working-dir/.packages/contents.json" - mapping = json.decode contents - - mapping.do --keys: | key | - if key.ends-with "pkg/foo": foo-url = key - if key.ends-with "pkg/bar": bar-url = key - foo-rel-path = mapping[foo-url][foo-version] - foo-path = "$tester.working-dir/.packages/$foo-rel-path" + foo-path = tester.package-cache-path "pkg/foo" --version=foo-version expect (file.is-directory foo-path) - bar-rel-path = mapping[bar-url][bar-version] - bar-path = "$tester.working-dir/.packages/$bar-rel-path" + bar-path = tester.package-cache-path "pkg/bar" --version=bar-version expect (file.is-directory bar-path) diff --git a/tests/pkg/setup.toit b/tests/pkg/setup.toit index 26b1b32ac..b97445d58 100644 --- a/tests/pkg/setup.toit +++ b/tests/pkg/setup.toit @@ -23,4 +23,4 @@ with-test-registry [block]: block.call tmp-dir finally: - directory.rmdir --recursive tmp-dir + directory.rmdir --force --recursive tmp-dir diff --git a/tests/pkg/utils_.toit b/tests/pkg/utils_.toit index 5e8dd8333..5414cdfff 100644 --- a/tests/pkg/utils_.toit +++ b/tests/pkg/utils_.toit @@ -3,6 +3,7 @@ // be found in the tests/LICENSE file. import host.pipe +import system unzip --source/string --target-dir/string -> none: // Unzip the given 'source' zip file into the 'target-dir'. @@ -11,3 +12,16 @@ unzip --source/string --target-dir/string -> none: exit-signal := pipe.exit-signal exit-value exit-code := pipe.exit-code exit-value throw "Failed to unzip '$source' into '$target-dir': $exit-value/$exit-signal" + +// A copy of `escape-path` from the utils library of the pkg code. +escape-path path/string -> string: + if system.platform != system.PLATFORM-WINDOWS: + return path + escaped-path := path.replace --all "#" "##" + [ '<', '>', ':', '"', '|', '?', '*', '\\' ].do: + escaped-path = escaped-path.replace --all + string.from-rune it + "#$(%02X it)" + if escaped-path.ends-with " " or escaped-path.ends-with ".": + escaped-path = "$escaped-path#20" + return escaped-path diff --git a/tools/pkg/project/project.toit b/tools/pkg/project/project.toit index 6af14e399..745a15103 100644 --- a/tools/pkg/project/project.toit +++ b/tools/pkg/project/project.toit @@ -235,6 +235,7 @@ class Project: hash = version-hash download_ url version --destination=cached-repository-dir --hash=hash file.write-contents hash --path=repo-toit-git-path + make-read-only_ --recursive cached-repository-dir (cached-contents.get url --init=:{:})[version-string] = relative-dir write-cached-repository-contents_ cached-contents return cached-contents diff --git a/tools/pkg/utils.toit b/tools/pkg/utils.toit index a8bf82d04..0d04a6c53 100644 --- a/tools/pkg/utils.toit +++ b/tools/pkg/utils.toit @@ -14,6 +14,8 @@ // directory of this repository. import encoding.url +import host.file +import host.directory import fs import system @@ -101,3 +103,33 @@ escape-path path/string -> string: // a space would normally not be escaped. escaped-path = "$escaped-path#20" return escaped-path + +/** +Makes the given $path read-only. + +If $recursive is true and $path is a directory, makes all files and + directories within $path read-only as well. +*/ +make-read-only_ --recursive/bool path/string -> none: + if not recursive or file.is-file path: + stat := file.stat path + if not stat: + return + mode := stat[file.ST-MODE] + if system.platform == system.PLATFORM-WINDOWS: + read-only-bit := file.WINDOWS-FILE-ATTRIBUTE-READONLY + if (mode & read-only-bit) != 0: return + file.chmod path (mode | read-only-bit) + return + write-bits := 0b010_010_010 + if (mode & write-bits) == 0: return + file.chmod path (mode & ~write-bits) + return + + // If it's not a directory, just ignore it. + if not file.is-directory path: return + + stream := directory.DirectoryStream path + while child := stream.next: + make-read-only_ --recursive (fs.join path child) + make-read-only_ --no-recursive path