diff --git a/tests/pkg/assets/install/gold/10-install.gold b/tests/pkg/assets/install/gold/10-install.gold new file mode 100644 index 000000000..c7fa06f11 --- /dev/null +++ b/tests/pkg/assets/install/gold/10-install.gold @@ -0,0 +1,20 @@ +OK +[pkg, registry, add, --local, test-reg, registry] +================== +OK +[pkg, install, foo] +Package 'foo@1.2.3' installed with prefix 'foo'. +================== +OK +[pkg, install, bar] +Package 'bar@2.0.1' installed with prefix 'bar'. +================== +OK +[pkg, install, --local, target] +Package 'target' installed with prefix 'target'. +================== +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/assets/install/gold/20-fail.gold b/tests/pkg/assets/install/gold/20-fail.gold new file mode 100644 index 000000000..c1a24a6ef --- /dev/null +++ b/tests/pkg/assets/install/gold/20-fail.gold @@ -0,0 +1,23 @@ +exec main.toit + +STDERR--- +<[*WORKING-DIR*]>/package.lock:11:10: error: Package 'http://localhost:<[*PORT*]>/pkg/bar-2.0.1' not found + url: http://localhost:<[*PORT*]>/pkg/bar + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +<[*WORKING-DIR*]>/package.lock:15:10: error: Package 'http://localhost:<[*PORT*]>/pkg/foo-1.2.3' not found + url: http://localhost:<[*PORT*]>/pkg/foo + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +main.toit:5:8: error: Package 'http_//localhost_<[*PORT*]>/pkg/foo-1' for prefix 'foo' not found +import foo + ^~~ +main.toit:6:8: error: Package 'http_//localhost_<[*PORT*]>/pkg/bar-2' for prefix 'bar' not found +import bar + ^~~ +main.toit:10:7: error: Unresolved identifier: 'say-hello' + foo.say-hello + ^~~~~~~~~ +main.toit:11:7: error: Unresolved identifier: 'say-hello' + bar.say-hello + ^~~~~~~~~ +Compilation failed +Exit Code: 1 diff --git a/tests/pkg/assets/install/gold/30-install.gold b/tests/pkg/assets/install/gold/30-install.gold new file mode 100644 index 000000000..6b8107666 --- /dev/null +++ b/tests/pkg/assets/install/gold/30-install.gold @@ -0,0 +1,2 @@ +OK +[pkg, install] diff --git a/tests/pkg/assets/install/main.toit b/tests/pkg/assets/install/main.toit new file mode 100644 index 000000000..cd6452454 --- /dev/null +++ b/tests/pkg/assets/install/main.toit @@ -0,0 +1,12 @@ +// Copyright (C) 2025 Toit contributors. +// Use of this source code is governed by a Zero-Clause BSD license that can +// be found in the tests/LICENSE file. + +import foo +import bar +import target + +main: + foo.say-hello + bar.say-hello + target.say-hello diff --git a/tests/pkg/assets/install/target/package.yaml b/tests/pkg/assets/install/target/package.yaml new file mode 100644 index 000000000..07c7c9808 --- /dev/null +++ b/tests/pkg/assets/install/target/package.yaml @@ -0,0 +1,2 @@ +name: target +description: desc diff --git a/tests/pkg/assets/install/target/src/target.toit b/tests/pkg/assets/install/target/src/target.toit new file mode 100644 index 000000000..f8bdbd25e --- /dev/null +++ b/tests/pkg/assets/install/target/src/target.toit @@ -0,0 +1,6 @@ +// Copyright (C) 2025 Toit contributors. +// Use of this source code is governed by a Zero-Clause BSD license that can +// be found in the tests/LICENSE file. + +say-hello: + print "hello from target" diff --git a/tests/pkg/install-gold-test.toit b/tests/pkg/install-gold-test.toit new file mode 100644 index 000000000..20689b71f --- /dev/null +++ b/tests/pkg/install-gold-test.toit @@ -0,0 +1,67 @@ +// Copyright (C) 2025 Toit contributors. +// Use of this source code is governed by a Zero-Clause BSD license that can +// be found in the tests/LICENSE file. + +import encoding.json +import expect show * +import host.directory +import host.file +import .gold-tester + +main args: + with-gold-tester args: test it + +test tester/GoldTester: + tester.gold "10-install" [ + ["pkg", "registry", "add", "--local", "test-reg", "registry"], + ["pkg", "install", "foo"], + ["pkg", "install", "bar"], + ["pkg", "install", "--local", "target"], + ["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" + 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" + expect (file.is-directory bar-path) + directory.rmdir --recursive --force bar-path + + tester.gold "20-fail" [ + ["exec", "main.toit"], + ] + + tester.gold "30-install" [ + ["pkg", "install"], + ] + + // 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" + expect (file.is-directory foo-path) + + bar-rel-path = mapping[bar-url][bar-version] + bar-path = "$tester.working-dir/.packages/$bar-rel-path" + expect (file.is-directory bar-path) diff --git a/tools/pkg/project/project.toit b/tools/pkg/project/project.toit index dd49f0afd..6af14e399 100644 --- a/tools/pkg/project/project.toit +++ b/tools/pkg/project/project.toit @@ -185,6 +185,8 @@ class Project: /** The directory within the cache where the given package is cached. */ relative-cached-repository-dir_ url/string version/SemanticVersion -> string: + url = url.trim --left "http://" + url = url.trim --left "https://" return escape-path "$url/$version" /** The full path of the directory within the cache where the given package is cached. */ @@ -213,7 +215,9 @@ class Project: --hash/string: if not cached-contents: cached-contents = cached-repository-contents_ version-string := version.to-string - if cached-contents.contains url and cached-contents[url].contains version-string: + if cached-contents.contains url and + cached-contents[url].contains version-string and + file.is-directory "$packages-cache-dir/$cached-contents[url][version-string]": return cached-contents cached-repository-dir := cached-repository-dir_ url version relative-dir := relative-cached-repository-dir_ url version