Skip to content

Commit 22c6ca4

Browse files
committed
Another fix to how the UNC paths are handled (a workaround similar to the one applied in SBT: sbt/sbt#564)
Build Monitor should load its LESS CSS assets correctly from a mapped network folder defined as a UNC path on Windows as long as: - Build Monitor runs on Jenkins 1.598 or later (due to a bug in Jenkins prior to that version: http://jenkins-ci.org/changelog#v1.598) - Jenkins runs on Java 7 u60 or later (due to a bug in Java prior to that version: http://bugs.java.com/view_bug.do?bug_id=8014394) Fixes jenkinsci#183
1 parent e05bc5d commit 22c6ca4

File tree

4 files changed

+66
-27
lines changed

4 files changed

+66
-27
lines changed

src/main/java/com/smartcodeltd/jenkinsci/plugin/assetbundler/Dispatcher.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import hudson.Plugin;
66
import hudson.util.PluginServletFilter;
77

8-
import java.net.URI;
8+
import java.io.File;
99
import java.net.URISyntaxException;
1010
import java.net.URL;
1111

@@ -31,7 +31,7 @@ private URL baseResourceURL() {
3131
return getWrapper().parent.getPlugin("build-monitor-plugin").baseResourceURL;
3232
}
3333

34-
private URI pathTo(String asset) throws URISyntaxException {
35-
return new PathToAsset(baseResourceURL(), asset).toURI();
34+
private File pathTo(String asset) throws URISyntaxException {
35+
return new PathToAsset(baseResourceURL(), asset).toFile();
3636
}
3737
}

src/main/java/com/smartcodeltd/jenkinsci/plugin/assetbundler/PathToAsset.java

+32-8
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,47 @@
77
import static java.lang.String.format;
88

99
public class PathToAsset {
10-
private final URL root;
11-
private final String asset;
10+
private static final String FILE_PROTOCOL = "file";
11+
private final URI path;
1212

1313
public PathToAsset(URL root, String asset) {
14-
this.root = root;
15-
this.asset = asset;
14+
this.path = validated(uriFrom(root, asset));
1615
}
1716

18-
public URI toURI() {
17+
public File toFile() {
18+
/*
19+
* The below workaround is required as the `uri` representing a UNC path on Windows
20+
* has an `authority` component defined (//foo/bar/some/file.ext),
21+
* however the File class constructor requires URIs with no defined authority
22+
*
23+
* https://github.com/jan-molak/jenkins-build-monitor-plugin/issues/183#issuecomment-157712010
24+
*
25+
* http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
26+
* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5086147
27+
*
28+
* fix as per: https://github.com/sbt/sbt/issues/564
29+
*/
30+
31+
return (null == path.getAuthority())
32+
? new File(path)
33+
: new File(path.getSchemeSpecificPart());
34+
}
35+
36+
// --
37+
38+
private URI uriFrom(URL root, String asset) {
1939
try {
2040
return new URL(root, asset).toURI();
2141
} catch (Exception e) {
22-
throw new RuntimeException(format("Sorry, I couldn't construct a path to asset '%s' using root: '%s", asset, root));
42+
throw new IllegalArgumentException(format("Sorry, I couldn't construct a path to asset '%s' using root: '%s", asset, root));
2343
}
2444
}
2545

26-
public File toFile() {
27-
return new File(toURI());
46+
private URI validated(URI fileUri) {
47+
if (! FILE_PROTOCOL.equals(fileUri.getScheme())) {
48+
throw new IllegalArgumentException(format("Sorry, can't load the asset from '%s' using the '%s' protocol", fileUri, FILE_PROTOCOL));
49+
}
50+
51+
return fileUri;
2852
}
2953
}

src/main/java/com/smartcodeltd/jenkinsci/plugin/assetbundler/filters/LessCSS.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,23 @@
1010
import javax.servlet.http.HttpServletResponse;
1111
import java.io.File;
1212
import java.io.IOException;
13-
import java.net.URI;
1413
import java.net.URISyntaxException;
1514

1615
public class LessCSS implements Filter {
17-
private final File less;
16+
private final File lessFile;
1817
private final String pathToCSS;
1918

2019
private String compiledCSS;
2120

22-
public LessCSS(String pathToCSS, URI pathToLess) throws URISyntaxException {
21+
public LessCSS(String pathToCSS, File pathToLess) throws URISyntaxException {
2322
this.pathToCSS = pathToCSS;
24-
this.less = new File(pathToLess);
23+
this.lessFile = pathToLess;
2524
}
2625

2726
@Override
2827
public void init(FilterConfig filterConfig) throws ServletException {
2928
try {
30-
compiledCSS = cssFrom(less);
29+
compiledCSS = cssFrom(lessFile);
3130
} catch (Less4jException e) {
3231
throw new ServletException("Couldn't compile the CSS from LESS sources", e);
3332
}
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,53 @@
11
package com.smartcodeltd.jenkinsci.plugin.assetbundler;
22

3-
import org.junit.Before;
3+
import org.junit.Rule;
44
import org.junit.Test;
5+
import org.junit.rules.ExpectedException;
56

67
import java.net.MalformedURLException;
78
import java.net.URL;
89

9-
import static com.smartcodeltd.jenkinsci.plugin.assetbundler.OsSpecific.isNotWindows;
1010
import static org.hamcrest.core.Is.is;
1111
import static org.junit.Assert.assertThat;
12-
import static org.junit.Assume.assumeTrue;
1312

1413
public class PathToAssetTest {
15-
@Before
16-
public void checkOS() {
17-
// todo: Build Monitor should use Java 7 once its core dependency on Jenkins can be upgraded to 1.612
18-
assumeTrue(isNotWindows());
19-
}
2014

2115
@Test
2216
public void combines_base_resource_url_given_by_jenkins_and_a_path_to_the_asset() throws Exception {
23-
URL base = baseResourceUrlGivenByJenkins("/opt/jenkins/plugins/build-monitor-plugin/");
17+
URL base = baseResourceUrlGivenByJenkins("file:///opt/jenkins/plugins/build-monitor-plugin/");
2418

2519
PathToAsset path = new PathToAsset(base, "less/index.less");
2620

2721
assertThat(absolute(path), is("/opt/jenkins/plugins/build-monitor-plugin/less/index.less"));
2822
}
2923

24+
@Test
25+
public void works_with_unc_paths_on_windows() throws Exception {
26+
URL base = baseResourceUrlGivenByJenkins("file://server/jenkins/plugins/build-monitor-plugin/");
27+
28+
PathToAsset path = new PathToAsset(base, "less/index.less");
29+
30+
assertThat(absolute(path), is("/server/jenkins/plugins/build-monitor-plugin/less/index.less"));
31+
}
32+
33+
@Rule public ExpectedException thrown = ExpectedException.none();
34+
35+
@Test
36+
public void complains_when_given_a_non_file_base_resource_url() throws Exception {
37+
thrown.expect(IllegalArgumentException.class);
38+
thrown.expectMessage("Sorry, can't load the asset from 'http://google.com/less/index.less' using the 'file' protocol");
39+
40+
new PathToAsset(new URL("http://google.com"), "less/index.less");
41+
}
42+
43+
// --
44+
3045
private String absolute(PathToAsset path) {
3146
return path.toFile().getAbsolutePath();
3247
}
3348

34-
private URL baseResourceUrlGivenByJenkins(String path) throws MalformedURLException {
35-
return new URL("file://" + path);
49+
// a pass-through method, only here for readability purposes
50+
private URL baseResourceUrlGivenByJenkins(String url) throws MalformedURLException {
51+
return new URL(url);
3652
}
3753
}

0 commit comments

Comments
 (0)