Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(pub): Improve support for custom package repositories #8876

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,13 @@ internal class PubCacheReader(flutterHome: File? = null) {
val path = if (type == "hosted" && url.isNotEmpty()) {
// Packages with source set to "hosted" and "url" key in description set to "https://pub.dartlang.org".
// The path should be resolved to "hosted/pub.dartlang.org/packageName-packageVersion".
"hosted/${url.replace("https://", "")}/$packageName-$packageVersion"
"hosted/${url.replace("https://", "").replace("/", "%47")}/$packageName-$packageVersion"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is "/" really the only character that needs to be escaped here? If there's a chance that other characters might need to be escaped as well, should we use our String.fileSystemEncode() function instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's see... https://github.com/dart-lang/pub/blob/ea4a1c854690d3abceb92c8cc2c6454470f9d5a7/doc/cache_layout.md?plain=1#L72 says

The url of the repository is encoded to a directory name with a weird URI-like
encoding. This is a mistake that seems costly to fix, but is worth being aware
of.

And the code in https://github.com/dart-lang/pub/blob/ea4a1c854690d3abceb92c8cc2c6454470f9d5a7/lib/src/source/hosted.dart#L1911

  return replace(
    url,
    RegExp(r'[<>:"\\/|?*%]'),
    (match) => '%${match[0]!.codeUnitAt(0)}',
  );

String.fileSystemEncode() does not work because Pub uses decimal value instead of hex value.

But now that I found the original code, I will add replace function for the missing 9 chars.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pub uses decimal value instead of hex value.

Wow, that's indeed weird!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But now that I found the original code, I will add replace function for the missing 9 chars.

Any update here, @Syyllinen?

} else if (type == "git" && resolvedRef.isNotEmpty()) {
// Packages with source set to "git" and a "resolved-ref" key in description set to a gitHash.
// These packages do not define a packageName in the packageInfo, but by definition the path resolves to
// the project name as given from the VcsHost and to the resolvedRef.
val projectName = VcsHost.getProject(url) ?: return null
if (resolvedPath.isNotEmpty()) {
if (resolvedPath.isNotEmpty() && resolvedPath != ".") {
"git/$projectName-$resolvedRef/$resolvedPath"
} else {
"git/$projectName-$resolvedRef"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class PubCacheReaderTest : WordSpec({
val gitPackageCacheDir = tmpPubCacheDir.resolve("git/$PACKAGE_NAME-$RESOLVED_REF")
val gitPackageWithPathCacheDir = tmpPubCacheDir.resolve("git/$PACKAGE_NAME-$RESOLVED_REF/$PACKAGE_NAME")
val hostedPackageCacheDir = tmpPubCacheDir.resolve("hosted/oss-review-toolkit.org/$PACKAGE_NAME-$PACKAGE_VERSION")
val customPackageCacheDir = tmpPubCacheDir.resolve(
"hosted/oss-review-toolkit.org%47api%47pub%47repository%47/$PACKAGE_NAME-$PACKAGE_VERSION"
)
val localPackagePathAbsolute = ABSOLUTE_PATH
val localPackagePathRelative = ABSOLUTE_PATH.resolve(RELATIVE_PATH)

Expand All @@ -49,6 +52,7 @@ class PubCacheReaderTest : WordSpec({
gitPackageCacheDir.safeMkdirs()
gitPackageWithPathCacheDir.safeMkdirs()
hostedPackageCacheDir.safeMkdirs()
customPackageCacheDir.safeMkdirs()
}

"findProjectRoot" should {
Expand All @@ -72,6 +76,27 @@ class PubCacheReaderTest : WordSpec({
) shouldBe gitPackageCacheDir
}

"resolve the path of a Git dependency with special path" {
reader.findProjectRoot(
jsonMapper.readTree(
"""
{
"dependency": "direct main",
"description": {
"path": ".",
"ref": "master",
"resolved-ref": "$RESOLVED_REF",
"url": "https://github.com/oss-review-toolkit/$PACKAGE_NAME.git"
},
"source": "git",
"version": "9.9.9"
}
""".trimIndent()
),
ABSOLUTE_PATH // not used
) shouldBe gitPackageCacheDir
}

"resolve the path of a Git dependency with path" {
reader.findProjectRoot(
jsonMapper.readTree(
Expand Down Expand Up @@ -112,6 +137,25 @@ class PubCacheReaderTest : WordSpec({
) shouldBe hostedPackageCacheDir
}

"resolve the path of a custom package repository dependency" {
Syyllinen marked this conversation as resolved.
Show resolved Hide resolved
PubCacheReader().findProjectRoot(
jsonMapper.readTree(
"""
{
"dependency": "transitive",
"description": {
"name": "$PACKAGE_NAME",
"url": "https://oss-review-toolkit.org/api/pub/repository/"
},
"source": "hosted",
"version": "$PACKAGE_VERSION"
}
""".trimIndent()
),
ABSOLUTE_PATH // not used
) shouldBe customPackageCacheDir
}

"resolve the relative path of a local dependency" {
PubCacheReader().findProjectRoot(
jsonMapper.readTree(
Expand Down
Loading