-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
[JEP-202] Extending VirtualFile #3302
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
Conversation
…ternal artifact storage.
…ly defined semantics.
…ring, boolean) which is also more convenient for some implementations.
…ows, contrary to Javadoc.
…or, which is normally handled deep within DirectoryScanner.
| */ | ||
| @CheckForNull | ||
| public static String resolveSymlink(@Nonnull File link) throws InterruptedException, IOException { | ||
| public static String resolveSymlink(@Nonnull File link) throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Binary compatible simplification—the body never actually threw that exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not source compatible IIRC (javac fails when there is a catch block for impossible exception), may impact PCT. There are usages of it externally, e.g. in the Support Core plugin: https://github.com/search?p=1&q=org%3Ajenkinsci+resolveSymlink&type=Code
I would propose to detach it to a separate PR if you feel it's important enough
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@oleg-nenashev Jesse already disputed this in #3340 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, PCT should be unaffected, though it could impede
buildPlugin(jenkinsVersions: [null, '2.222']) // or whateverWhy the Java language treats an exception which cannot be thrown as a fatal error rather than a warning (ditto unreachable statements etc.), I do not know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The simple workaround for the buildPlugin case would be to just catch (Exception I guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be better to fix it tho
| try (ZipOutputStream zos = new ZipOutputStream(outputStream)) { | ||
| zos.setEncoding(System.getProperty("file.encoding")); // TODO JENKINS-20663 make this overridable via query parameter | ||
| for (String n : dir.list(glob.length() == 0 ? "**" : glob)) { | ||
| for (String n : dir.list(glob.isEmpty() ? "**" : glob, null, /* TODO what is the user expectation? */true)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Retaining default excludes functionality here to maintain semantics but I am unsure whether users would want this or not.
| } | ||
| return r.stream().filter(p -> { | ||
| TokenizedPath path = new TokenizedPath(p.replace('/', File.separatorChar)); | ||
| return includePatterns.stream().anyMatch(patt -> patt.matchPath(path, true)) && !excludePatterns.stream().anyMatch(patt -> patt.matchPath(path, true)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VirtualFileTest.Ram checks all this implementation.
| * <p>Generally this will be harder to implement than {@link #asRemotable}, | ||
| * which would have the opportunity to perform arbitrary preparation for {@link #open} | ||
| * such as negotiating session authentication. | ||
| * @return an externally usable URL like {@code https://gist.githubusercontent.com/ACCT/GISTID/raw/COMMITHASH/FILE}, or null if there is no such support |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just the most familiar download URL example I could come up with—certainly not a choice for artifact storage!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoever implements this as a weekend project will get 🍻 from me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding some 🍺 to the trophy
| * <p>Since some implementations may in fact use external file storage, | ||
| * callers may request optional APIs to access those services more efficiently. | ||
| * Otherwise, for example, a plugin copying a file | ||
| * previously saved by {@link ArtifactManager} to an external storage servuce |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/servuce/service/
oleg-nenashev
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good so far though I would still prefer InterruptedException. Accmod is still waiting for the release by @kohsuke
| */ | ||
| @CheckForNull | ||
| public static String resolveSymlink(@Nonnull File link) throws InterruptedException, IOException { | ||
| public static String resolveSymlink(@Nonnull File link) throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be better to fix it tho
| */ | ||
| private static List<List<Path>> patternScan(VirtualFile baseDir, String pattern, String baseRef) throws IOException { | ||
| String[] files = baseDir.list(pattern); | ||
| Collection<String> files = baseDir.list(pattern, null, /* TODO what is the user expectation? */true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that there was a JEP-200 regression in the similar code recently
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, in DirScanner.Glob IIRC, which is called by some list implementations.
| /** {@link Run.ArtifactList} without the implicit link to {@link Run} */ | ||
| private static final class SerializableArtifactList extends ArrayList<SerializableArtifact> { | ||
| private static final long serialVersionUID = 1L; | ||
| private LinkedHashMap<SerializableArtifact, String> tree = new LinkedHashMap<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even for a private class not looks a bit dangerous since you do not override modification methods to put data to both containers (array and tree)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code was already a mess and I am trying to touch it as little as possible. The problem here was that Artifact and ArtifactList were, surprisingly, nonstatic—they held a Run reference—which is unsupportable when they must be constructed inside a callable which might run remotely. (If using the FilePath-based VirtualFile, for example. In fact this is not currently used by any ArtifactManager, only workspace browsing, but the API does not preclude the possibility, so…)
| * only on the node on which the object was created. | ||
| * | ||
| * <p>Since some implementations may in fact use external file storage, | ||
| * callers may request optional APIs to access those services more efficiently. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still feel that we grow a technical debt in API, but Ican live with that.
| throw (IOException) new InterruptedIOException().initCause(e); | ||
| target = Util.resolveSymlink(f); | ||
| } catch (IOException x) { // JENKINS-13202 | ||
| target = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed
|
this is stable now for final review |
|
@daniel-beck can you take a look at the new changes to see if your positive review still stands? |
carlossg
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is tested with the https://github.com/jenkinsci/artifact-manager-s3-plugin and works fine
oleg-nenashev
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🐝 The diff from the previous review looks good to me. Since all APIs are annotated with Beta, we can reconsider APIs in the worst case
|
@reviewbybees done |
|
Given the JEP is in place, no objections have been raised and all apis are marked as |
| /** | ||
| * @deprecated use {@link #list(String, String, boolean)} instead | ||
| */ | ||
| @Deprecated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This deprecation points to a Beta API. This seems unhelpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, the only callers will be updated anyway.
|
FTR, agree with @carlossg regarding the eligibility for this to be merged. Beta annotations allow this to evolve if needed without breaking existing API commitments. |
|
FTR jenkinsci/jep#96 |
See JENKINS-49635 and also JENKINS-26810, and JEP-202.
toExternalURLVirtualFile.mode()(needed by [JENKINS-22637] ArtifactManager support on new core copyartifact-plugin#100)VirtualFile.readLink()(needed by [JENKINS-22637] ArtifactManager support on new core copyartifact-plugin#100)VirtualFile.list(String, String, boolean)(needed by [JENKINS-22637] ArtifactManager support on new core copyartifact-plugin#100) (could also be used to simplify Add support for download of zipped artifacts compress-artifacts-plugin#1)toExternalURLin [JENKINS-22637] ArtifactManager support on new core copyartifact-plugin#100Reference implementation is in the
artifact-manager-s3plugin.@reviewbybees @jenkinsci/code-reviewers