mirror of
https://github.com/apple/pkl.git
synced 2026-08-06 20:28:41 +02:00
Add pkl project package --install to local cache (#1795)
This commit is contained in:
@@ -670,6 +670,12 @@ Example: `--test-reporter minimal` +
|
|||||||
Which test reporter to use for CLI output. Possible values are `spec` and `minimal`.
|
Which test reporter to use for CLI output. Possible values are `spec` and `minimal`.
|
||||||
====
|
====
|
||||||
|
|
||||||
|
.--install
|
||||||
|
[%collapsible]
|
||||||
|
====
|
||||||
|
Install the built package into the module cache dir.
|
||||||
|
====
|
||||||
|
|
||||||
This command also takes <<common-options,common options>>.
|
This command also takes <<common-options,common options>>.
|
||||||
|
|
||||||
[[command-project-resolve]]
|
[[command-project-resolve]]
|
||||||
|
|||||||
@@ -694,6 +694,13 @@ Example: `reporter = "minimal"` +
|
|||||||
Which test reporter to use for CLI output. Possible values are `"spec"` and `"minimal"`.
|
Which test reporter to use for CLI output. Possible values are `"spec"` and `"minimal"`.
|
||||||
====
|
====
|
||||||
|
|
||||||
|
.install: Property<Boolean>
|
||||||
|
[%collapsible]
|
||||||
|
====
|
||||||
|
Default: `false` +
|
||||||
|
Install the built package into the module cache dir.
|
||||||
|
====
|
||||||
|
|
||||||
Common properties:
|
Common properties:
|
||||||
|
|
||||||
include::../partials/gradle-common-properties.adoc[]
|
include::../partials/gradle-common-properties.adoc[]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -31,6 +31,7 @@ class CliProjectPackager(
|
|||||||
private val testOptions: CliTestOptions,
|
private val testOptions: CliTestOptions,
|
||||||
private val outputPath: String,
|
private val outputPath: String,
|
||||||
private val skipPublishCheck: Boolean,
|
private val skipPublishCheck: Boolean,
|
||||||
|
private val install: Boolean,
|
||||||
private val consoleWriter: Writer = System.out.writer(),
|
private val consoleWriter: Writer = System.out.writer(),
|
||||||
private val errWriter: Writer = System.err.writer(),
|
private val errWriter: Writer = System.err.writer(),
|
||||||
) : CliProjectCommand(baseOptions, projectDirs) {
|
) : CliProjectCommand(baseOptions, projectDirs) {
|
||||||
@@ -85,6 +86,8 @@ class CliProjectPackager(
|
|||||||
securityManager,
|
securityManager,
|
||||||
httpClient,
|
httpClient,
|
||||||
skipPublishCheck,
|
skipPublishCheck,
|
||||||
|
install,
|
||||||
|
moduleCacheDir,
|
||||||
consoleWriter,
|
consoleWriter,
|
||||||
)
|
)
|
||||||
.createPackages()
|
.createPackages()
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import com.github.ajalt.clikt.core.subcommands
|
|||||||
import com.github.ajalt.clikt.parameters.arguments.argument
|
import com.github.ajalt.clikt.parameters.arguments.argument
|
||||||
import com.github.ajalt.clikt.parameters.arguments.multiple
|
import com.github.ajalt.clikt.parameters.arguments.multiple
|
||||||
import com.github.ajalt.clikt.parameters.groups.provideDelegate
|
import com.github.ajalt.clikt.parameters.groups.provideDelegate
|
||||||
|
import com.github.ajalt.clikt.parameters.options.check
|
||||||
import com.github.ajalt.clikt.parameters.options.default
|
import com.github.ajalt.clikt.parameters.options.default
|
||||||
import com.github.ajalt.clikt.parameters.options.flag
|
import com.github.ajalt.clikt.parameters.options.flag
|
||||||
import com.github.ajalt.clikt.parameters.options.option
|
import com.github.ajalt.clikt.parameters.options.option
|
||||||
@@ -128,6 +129,15 @@ class PackageCommand : BaseCommand(name = "package", helpLink = helpLink) {
|
|||||||
.single()
|
.single()
|
||||||
.flag()
|
.flag()
|
||||||
|
|
||||||
|
private val install: Boolean by
|
||||||
|
option(
|
||||||
|
names = arrayOf("--install"),
|
||||||
|
help = "Install the built package into the module cache dir",
|
||||||
|
)
|
||||||
|
.single()
|
||||||
|
.flag()
|
||||||
|
.check("not compatible with --no-cache") { !(it && baseOptions.noCache) }
|
||||||
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
CliProjectPackager(
|
CliProjectPackager(
|
||||||
baseOptions.baseOptions(emptyList()),
|
baseOptions.baseOptions(emptyList()),
|
||||||
@@ -135,6 +145,7 @@ class PackageCommand : BaseCommand(name = "package", helpLink = helpLink) {
|
|||||||
testOptions.cliTestOptions,
|
testOptions.cliTestOptions,
|
||||||
outputPath,
|
outputPath,
|
||||||
skipPublishCheck,
|
skipPublishCheck,
|
||||||
|
install,
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
)
|
)
|
||||||
val err = assertThrows<CliException> { packager.run() }
|
val err = assertThrows<CliException> { packager.run() }
|
||||||
assertThat(err).hasMessageStartingWith("No project visible to the working directory.")
|
assertThat(err).hasMessageStartingWith("No project visible to the working directory.")
|
||||||
@@ -74,6 +75,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
)
|
)
|
||||||
val err = assertThrows<CliException> { packager.run() }
|
val err = assertThrows<CliException> { packager.run() }
|
||||||
assertThat(err).hasMessageStartingWith("Directory $tempDir does not contain a PklProject file.")
|
assertThat(err).hasMessageStartingWith("Directory $tempDir does not contain a PklProject file.")
|
||||||
@@ -96,6 +98,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
)
|
)
|
||||||
val err = assertThrows<CliException> { packager.run() }
|
val err = assertThrows<CliException> { packager.run() }
|
||||||
assertThat(err)
|
assertThat(err)
|
||||||
@@ -140,6 +143,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
consoleWriter = buffer,
|
consoleWriter = buffer,
|
||||||
)
|
)
|
||||||
val err = assertThrows<CliException> { packager.run() }
|
val err = assertThrows<CliException> { packager.run() }
|
||||||
@@ -187,6 +191,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
consoleWriter = buffer,
|
consoleWriter = buffer,
|
||||||
)
|
)
|
||||||
packager.run()
|
packager.run()
|
||||||
@@ -286,6 +291,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out",
|
".out",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
consoleWriter = buffer,
|
consoleWriter = buffer,
|
||||||
)
|
)
|
||||||
packager.run()
|
packager.run()
|
||||||
@@ -337,6 +343,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
consoleWriter = StringWriter(),
|
consoleWriter = StringWriter(),
|
||||||
)
|
)
|
||||||
packager.run()
|
packager.run()
|
||||||
@@ -419,6 +426,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
consoleWriter = StringWriter(),
|
consoleWriter = StringWriter(),
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
@@ -517,6 +525,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
consoleWriter = StringWriter(),
|
consoleWriter = StringWriter(),
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
@@ -655,6 +664,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
consoleWriter = StringWriter(),
|
consoleWriter = StringWriter(),
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
@@ -695,6 +705,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
consoleWriter = StringWriter(),
|
consoleWriter = StringWriter(),
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
@@ -749,6 +760,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
consoleWriter = StringWriter(),
|
consoleWriter = StringWriter(),
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
@@ -795,6 +807,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
consoleWriter = StringWriter(),
|
consoleWriter = StringWriter(),
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
@@ -832,6 +845,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
consoleWriter = StringWriter(),
|
consoleWriter = StringWriter(),
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
@@ -875,6 +889,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
consoleWriter = StringWriter(),
|
consoleWriter = StringWriter(),
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
@@ -919,6 +934,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
consoleWriter = out,
|
consoleWriter = out,
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
@@ -974,6 +990,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = false,
|
skipPublishCheck = false,
|
||||||
|
install = false,
|
||||||
consoleWriter = StringWriter(),
|
consoleWriter = StringWriter(),
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
@@ -1018,6 +1035,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = false,
|
skipPublishCheck = false,
|
||||||
|
install = false,
|
||||||
consoleWriter = out,
|
consoleWriter = out,
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
@@ -1062,6 +1080,7 @@ class CliProjectPackagerTest {
|
|||||||
CliTestOptions(),
|
CliTestOptions(),
|
||||||
".out/%{name}@%{version}",
|
".out/%{name}@%{version}",
|
||||||
skipPublishCheck = true,
|
skipPublishCheck = true,
|
||||||
|
install = false,
|
||||||
consoleWriter = StringWriter(),
|
consoleWriter = StringWriter(),
|
||||||
)
|
)
|
||||||
packager.run()
|
packager.run()
|
||||||
@@ -1121,6 +1140,73 @@ class CliProjectPackagerTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `install package to local cache`(@TempDir tempDir: Path, @TempDir cacheDir: Path) {
|
||||||
|
tempDir
|
||||||
|
.resolve("PklProject")
|
||||||
|
.writeString(
|
||||||
|
"""
|
||||||
|
amends "pkl:Project"
|
||||||
|
|
||||||
|
package {
|
||||||
|
name = "mypackage"
|
||||||
|
version = "1.0.0"
|
||||||
|
baseUri = "package://example.com/mypackage"
|
||||||
|
packageZipUrl = "https://foo.com"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
.trimIndent()
|
||||||
|
)
|
||||||
|
val packager =
|
||||||
|
CliProjectPackager(
|
||||||
|
CliBaseOptions(workingDir = tempDir, moduleCacheDir = cacheDir),
|
||||||
|
listOf(tempDir),
|
||||||
|
CliTestOptions(),
|
||||||
|
".out/%{name}@%{version}",
|
||||||
|
skipPublishCheck = true,
|
||||||
|
install = true,
|
||||||
|
consoleWriter = StringWriter(),
|
||||||
|
)
|
||||||
|
packager.run()
|
||||||
|
|
||||||
|
assertThat(cacheDir.resolve("package-2/example.com/mypackage@1.0.0/mypackage@1.0.0.json"))
|
||||||
|
.exists()
|
||||||
|
assertThat(cacheDir.resolve("package-2/example.com/mypackage@1.0.0/mypackage@1.0.0.zip"))
|
||||||
|
.exists()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `cannot install with no cache`(@TempDir tempDir: Path) {
|
||||||
|
tempDir
|
||||||
|
.resolve("PklProject")
|
||||||
|
.writeString(
|
||||||
|
"""
|
||||||
|
amends "pkl:Project"
|
||||||
|
|
||||||
|
package {
|
||||||
|
name = "mypackage"
|
||||||
|
version = "1.0.0"
|
||||||
|
baseUri = "package://example.com/mypackage"
|
||||||
|
packageZipUrl = "https://foo.com"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
.trimIndent()
|
||||||
|
)
|
||||||
|
val packager =
|
||||||
|
CliProjectPackager(
|
||||||
|
CliBaseOptions(workingDir = tempDir, noCache = true),
|
||||||
|
listOf(tempDir),
|
||||||
|
CliTestOptions(),
|
||||||
|
".out/%{name}@%{version}",
|
||||||
|
skipPublishCheck = true,
|
||||||
|
install = true,
|
||||||
|
consoleWriter = StringWriter(),
|
||||||
|
)
|
||||||
|
val exc = assertThrows<CliException> { packager.run() }
|
||||||
|
assertThat(exc.message)
|
||||||
|
.isEqualTo("Cannot install package to module cache dir when module cache is disabled.")
|
||||||
|
}
|
||||||
|
|
||||||
private fun Path.zipFilePaths(): List<String> {
|
private fun Path.zipFilePaths(): List<String> {
|
||||||
return FileSystems.newFileSystem(URI("jar:${toUri()}"), emptyMap<String, String>()).use { fs ->
|
return FileSystems.newFileSystem(URI("jar:${toUri()}"), emptyMap<String, String>()).use { fs ->
|
||||||
Files.walk(fs.getPath("/")).map(IoUtils::toNormalizedPathString).collect(Collectors.toList())
|
Files.walk(fs.getPath("/")).map(IoUtils::toNormalizedPathString).collect(Collectors.toList())
|
||||||
|
|||||||
@@ -56,4 +56,7 @@ public interface PackageResolver extends Closeable {
|
|||||||
|
|
||||||
boolean hasElement(PackageAssetUri uri, @Nullable Checksums checksums)
|
boolean hasElement(PackageAssetUri uri, @Nullable Checksums checksums)
|
||||||
throws IOException, SecurityManagerException;
|
throws IOException, SecurityManagerException;
|
||||||
|
|
||||||
|
Pair<Path, Path> writePackage(PackageUri packageUri, Path metadataFile, Path zipFile)
|
||||||
|
throws IOException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -317,6 +317,11 @@ final class PackageResolvers {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pair<Path, Path> writePackage(PackageUri packageUri, Path metadataFile, Path zipFile) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] getBytes(
|
public byte[] getBytes(
|
||||||
PackageAssetUri uri, boolean allowDirectories, @Nullable Checksums checksums)
|
PackageAssetUri uri, boolean allowDirectories, @Nullable Checksums checksums)
|
||||||
@@ -428,6 +433,7 @@ final class PackageResolvers {
|
|||||||
|
|
||||||
private final Path tmpDir;
|
private final Path tmpDir;
|
||||||
|
|
||||||
|
// if updated, also update CliProjectPackagerTest.`install package to local cache`
|
||||||
private static final String CACHE_DIR_PREFIX = "package-2";
|
private static final String CACHE_DIR_PREFIX = "package-2";
|
||||||
|
|
||||||
@GuardedBy("lock")
|
@GuardedBy("lock")
|
||||||
@@ -503,12 +509,16 @@ final class PackageResolvers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Path doGetMetadataPath(PackageUri packageUri) {
|
||||||
|
var metadataFileName = getLastSegmentName(packageUri) + ".json";
|
||||||
|
var metadataRelativePath = getRelativePath(packageUri).resolve(metadataFileName);
|
||||||
|
return cacheDir.resolve(metadataRelativePath);
|
||||||
|
}
|
||||||
|
|
||||||
private Path getMetadataPath(
|
private Path getMetadataPath(
|
||||||
PackageUri packageUri, URI requestUri, @Nullable Checksums checksums)
|
PackageUri packageUri, URI requestUri, @Nullable Checksums checksums)
|
||||||
throws IOException, SecurityManagerException {
|
throws IOException, SecurityManagerException {
|
||||||
var metadataFileName = getLastSegmentName(packageUri) + ".json";
|
var cachePath = doGetMetadataPath(packageUri);
|
||||||
var metadataRelativePath = getRelativePath(packageUri).resolve(metadataFileName);
|
|
||||||
var cachePath = cacheDir.resolve(metadataRelativePath);
|
|
||||||
if (Files.exists(cachePath)) {
|
if (Files.exists(cachePath)) {
|
||||||
return cachePath;
|
return cachePath;
|
||||||
}
|
}
|
||||||
@@ -556,11 +566,15 @@ final class PackageResolvers {
|
|||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Path getZipFilePath(PackageUri packageUri, DependencyMetadata dependencyMetadata)
|
private Path doGetZipFilePath(PackageUri packageUri) {
|
||||||
throws IOException, SecurityManagerException {
|
|
||||||
var packageZipName = getLastSegmentName(packageUri) + ".zip";
|
var packageZipName = getLastSegmentName(packageUri) + ".zip";
|
||||||
var relativePath = getRelativePath(packageUri).resolve(packageZipName);
|
var relativePath = getRelativePath(packageUri).resolve(packageZipName);
|
||||||
var cachePath = cacheDir.resolve(relativePath);
|
return cacheDir.resolve(relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path getZipFilePath(PackageUri packageUri, DependencyMetadata dependencyMetadata)
|
||||||
|
throws IOException, SecurityManagerException {
|
||||||
|
var cachePath = doGetZipFilePath(packageUri);
|
||||||
if (Files.exists(cachePath)) {
|
if (Files.exists(cachePath)) {
|
||||||
return cachePath;
|
return cachePath;
|
||||||
}
|
}
|
||||||
@@ -684,5 +698,28 @@ final class PackageResolvers {
|
|||||||
fileSystems.clear();
|
fileSystems.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pair<Path, Path> writePackage(PackageUri packageUri, Path metadataFile, Path zipFile)
|
||||||
|
throws IOException {
|
||||||
|
Files.createDirectories(tmpDir);
|
||||||
|
var tmpSubpath = IoUtils.encodePath(packageUri.toString().replace("/", "-"));
|
||||||
|
return Pair.of(
|
||||||
|
writePackagePart(metadataFile, doGetMetadataPath(packageUri), tmpSubpath, ".json"),
|
||||||
|
writePackagePart(zipFile, doGetZipFilePath(packageUri), tmpSubpath, ".zip"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path writePackagePart(Path srcFile, Path cacheFile, String tmpSubpath, String suffix)
|
||||||
|
throws IOException {
|
||||||
|
var tmpFile = Files.createTempFile(tmpDir, tmpSubpath, suffix);
|
||||||
|
Files.createDirectories(cacheFile.getParent());
|
||||||
|
Files.copy(srcFile, tmpFile, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
Files.move(
|
||||||
|
tmpFile, cacheFile, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
|
||||||
|
if (!IoUtils.isWindows()) {
|
||||||
|
Files.setPosixFilePermissions(cacheFile, FILE_PERMISSIONS);
|
||||||
|
}
|
||||||
|
return cacheFile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import java.util.stream.Collectors;
|
|||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
import org.graalvm.collections.EconomicMap;
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
import org.pkl.core.PklBugException;
|
import org.pkl.core.PklBugException;
|
||||||
import org.pkl.core.PklException;
|
import org.pkl.core.PklException;
|
||||||
import org.pkl.core.SecurityManager;
|
import org.pkl.core.SecurityManager;
|
||||||
@@ -100,6 +101,7 @@ public final class ProjectPackager {
|
|||||||
private final boolean color;
|
private final boolean color;
|
||||||
private final SecurityManager securityManager;
|
private final SecurityManager securityManager;
|
||||||
private final PackageResolver packageResolver;
|
private final PackageResolver packageResolver;
|
||||||
|
private final @Nullable PackageResolver packageWriteResolver;
|
||||||
private final boolean skipPublishCheck;
|
private final boolean skipPublishCheck;
|
||||||
private final Writer outputWriter;
|
private final Writer outputWriter;
|
||||||
|
|
||||||
@@ -112,6 +114,8 @@ public final class ProjectPackager {
|
|||||||
SecurityManager securityManager,
|
SecurityManager securityManager,
|
||||||
HttpClient httpClient,
|
HttpClient httpClient,
|
||||||
boolean skipPublishCheck,
|
boolean skipPublishCheck,
|
||||||
|
boolean install,
|
||||||
|
@Nullable Path cacheDir,
|
||||||
Writer outputWriter) {
|
Writer outputWriter) {
|
||||||
this.projects = projects;
|
this.projects = projects;
|
||||||
this.workingDir = workingDir;
|
this.workingDir = workingDir;
|
||||||
@@ -123,6 +127,14 @@ public final class ProjectPackager {
|
|||||||
this.packageResolver = PackageResolver.getInstance(securityManager, httpClient, null);
|
this.packageResolver = PackageResolver.getInstance(securityManager, httpClient, null);
|
||||||
this.skipPublishCheck = skipPublishCheck;
|
this.skipPublishCheck = skipPublishCheck;
|
||||||
this.outputWriter = outputWriter;
|
this.outputWriter = outputWriter;
|
||||||
|
if (install) {
|
||||||
|
if (cacheDir == null) {
|
||||||
|
throw new PklException(ErrorMessages.create("cannotInstallPackageWithNoCache"));
|
||||||
|
}
|
||||||
|
packageWriteResolver = PackageResolver.getInstance(securityManager, httpClient, cacheDir);
|
||||||
|
} else {
|
||||||
|
packageWriteResolver = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeLine(String line) throws IOException {
|
private void writeLine(String line) throws IOException {
|
||||||
@@ -137,6 +149,12 @@ public final class ProjectPackager {
|
|||||||
writeLine(IoUtils.relativize(packageResult.metadataChecksumFile(), workingDir).toString());
|
writeLine(IoUtils.relativize(packageResult.metadataChecksumFile(), workingDir).toString());
|
||||||
writeLine(IoUtils.relativize(packageResult.zipFile(), workingDir).toString());
|
writeLine(IoUtils.relativize(packageResult.zipFile(), workingDir).toString());
|
||||||
writeLine(IoUtils.relativize(packageResult.zipChecksumFile(), workingDir).toString());
|
writeLine(IoUtils.relativize(packageResult.zipChecksumFile(), workingDir).toString());
|
||||||
|
if (packageResult.cacheMetadataFile() != null) {
|
||||||
|
writeLine(packageResult.cacheMetadataFile().normalize().toString());
|
||||||
|
}
|
||||||
|
if (packageResult.cacheZipFile() != null) {
|
||||||
|
writeLine(packageResult.cacheZipFile().normalize().toString());
|
||||||
|
}
|
||||||
outputWriter.flush();
|
outputWriter.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,9 +192,29 @@ public final class ProjectPackager {
|
|||||||
if (!skipPublishCheck) {
|
if (!skipPublishCheck) {
|
||||||
checkAlreadyPublishedPackage(pkg, metadataFileChecksum);
|
checkAlreadyPublishedPackage(pkg, metadataFileChecksum);
|
||||||
}
|
}
|
||||||
var result =
|
PackageResult result;
|
||||||
new PackageResult(
|
if (packageWriteResolver != null) {
|
||||||
metadataFile, metadataChecksumFile, zipFile, zipChecksumFile, metadataFileChecksum);
|
var cachePaths = packageWriteResolver.writePackage(pkg.uri(), metadataFile, zipFile);
|
||||||
|
result =
|
||||||
|
new PackageResult(
|
||||||
|
metadataFile,
|
||||||
|
metadataChecksumFile,
|
||||||
|
zipFile,
|
||||||
|
zipChecksumFile,
|
||||||
|
metadataFileChecksum,
|
||||||
|
cachePaths.getFirst(),
|
||||||
|
cachePaths.getSecond());
|
||||||
|
} else {
|
||||||
|
result =
|
||||||
|
new PackageResult(
|
||||||
|
metadataFile,
|
||||||
|
metadataChecksumFile,
|
||||||
|
zipFile,
|
||||||
|
zipChecksumFile,
|
||||||
|
metadataFileChecksum,
|
||||||
|
null,
|
||||||
|
null);
|
||||||
|
}
|
||||||
packageResults.put(pkg.uri(), result);
|
packageResults.put(pkg.uri(), result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -457,7 +495,9 @@ public final class ProjectPackager {
|
|||||||
Path zipChecksumFile,
|
Path zipChecksumFile,
|
||||||
Path metadataFile,
|
Path metadataFile,
|
||||||
Path metadataChecksumFile,
|
Path metadataChecksumFile,
|
||||||
String metadataChecksum) {
|
String metadataChecksum,
|
||||||
|
@Nullable Path cacheMetadataFile,
|
||||||
|
@Nullable Path cacheZipFile) {
|
||||||
/**
|
/**
|
||||||
* @deprecated As of 0.28.0, replaced by {@link #zipFile()}.
|
* @deprecated As of 0.28.0, replaced by {@link #zipFile()}.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1205,3 +1205,6 @@ Redirected to: `{1}`
|
|||||||
|
|
||||||
invalidReferenceTypeAnnotationWithConstraint=\
|
invalidReferenceTypeAnnotationWithConstraint=\
|
||||||
`Reference` referent type argument may not include type constraints.
|
`Reference` referent type argument may not include type constraints.
|
||||||
|
|
||||||
|
cannotInstallPackageWithNoCache=\
|
||||||
|
Cannot install package to module cache dir when module cache is disabled.
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ public class PklPlugin implements Plugin<Project> {
|
|||||||
task.getProjectDirectories().from(spec.getProjectDirectories());
|
task.getProjectDirectories().from(spec.getProjectDirectories());
|
||||||
task.getOutputPath().set(spec.getOutputPath());
|
task.getOutputPath().set(spec.getOutputPath());
|
||||||
task.getSkipPublishCheck().set(spec.getSkipPublishCheck());
|
task.getSkipPublishCheck().set(spec.getSkipPublishCheck());
|
||||||
|
task.getInstall().set(spec.getInstall());
|
||||||
task.getJunitReportsDir().set(spec.getJunitReportsDir());
|
task.getJunitReportsDir().set(spec.getJunitReportsDir());
|
||||||
task.getOverwrite().set(spec.getOverwrite());
|
task.getOverwrite().set(spec.getOverwrite());
|
||||||
task.getTestReporter().set(spec.getTestReporter());
|
task.getTestReporter().set(spec.getTestReporter());
|
||||||
|
|||||||
@@ -30,5 +30,7 @@ public interface ProjectPackageSpec extends BasePklSpec {
|
|||||||
|
|
||||||
Property<Boolean> getSkipPublishCheck();
|
Property<Boolean> getSkipPublishCheck();
|
||||||
|
|
||||||
|
Property<Boolean> getInstall();
|
||||||
|
|
||||||
Property<String> getTestReporter();
|
Property<String> getTestReporter();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,10 @@ public abstract class ProjectPackageTask extends BasePklTask {
|
|||||||
@Optional
|
@Optional
|
||||||
public abstract Property<Boolean> getSkipPublishCheck();
|
public abstract Property<Boolean> getSkipPublishCheck();
|
||||||
|
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
public abstract Property<Boolean> getInstall();
|
||||||
|
|
||||||
@Input
|
@Input
|
||||||
@Optional
|
@Optional
|
||||||
public abstract Property<String> getTestReporter();
|
public abstract Property<String> getTestReporter();
|
||||||
@@ -92,6 +96,7 @@ public abstract class ProjectPackageTask extends BasePklTask {
|
|||||||
toTestReporter(getTestReporter())),
|
toTestReporter(getTestReporter())),
|
||||||
getOutputPath().get().getAsFile().getAbsolutePath(),
|
getOutputPath().get().getAsFile().getAbsolutePath(),
|
||||||
getSkipPublishCheck().getOrElse(false),
|
getSkipPublishCheck().getOrElse(false),
|
||||||
|
getInstall().getOrElse(false),
|
||||||
new PrintWriter(System.out),
|
new PrintWriter(System.out),
|
||||||
new PrintWriter(System.err))
|
new PrintWriter(System.err))
|
||||||
.run();
|
.run();
|
||||||
|
|||||||
Reference in New Issue
Block a user