Skip to content

Commit

Permalink
[JENKINS-1143] Dropping support for Forest extension.
Browse files Browse the repository at this point in the history
The extension itself has long been deprecated;
an unofficial fork for compatibility with newer Mercurials has not been updated in a year.
The plugin integration was incomplete, rarely tested,
and complicated implementation of other features.
Anyway the new Multiple SCMs Plugin seems to do just as well for the same use cases.
  • Loading branch information
Jesse Glick committed Oct 17, 2011
1 parent 3acb0e5 commit e314ee8
Show file tree
Hide file tree
Showing 16 changed files with 45 additions and 1,683 deletions.
Expand Up @@ -53,18 +53,16 @@ public class MercurialInstallation extends ToolInstallation implements
EnvironmentSpecific<MercurialInstallation> {

private String executable;
private String downloadForest;
private boolean debug;
private boolean useCaches;
private boolean useSharing;

@DataBoundConstructor
public MercurialInstallation(String name, String home, String executable,
String downloadForest, boolean debug, boolean useCaches,
boolean debug, boolean useCaches,
boolean useSharing, List<? extends ToolProperty<?>> properties) {
super(name, home, properties);
this.executable = Util.fixEmpty(executable);
this.downloadForest = Util.fixEmpty(downloadForest);
this.debug = debug;
this.useCaches = useCaches || useSharing;
this.useSharing = useSharing;
Expand All @@ -78,10 +76,6 @@ String executableWithSubstitution(String home) {
return getExecutable().replace("INSTALLATION", home);
}

public String getDownloadForest() {
return downloadForest;
}

public boolean getDebug() {
return debug;
}
Expand All @@ -102,13 +96,13 @@ public static MercurialInstallation[] allInstallations() {
public MercurialInstallation forNode(Node node, TaskListener log)
throws IOException, InterruptedException {
return new MercurialInstallation(getName(), translateFor(node, log),
executable, downloadForest, debug, useCaches, useSharing,
executable, debug, useCaches, useSharing,
getProperties().toList());
}

public MercurialInstallation forEnvironment(EnvVars environment) {
return new MercurialInstallation(getName(),
environment.expand(getHome()), executable, downloadForest,
environment.expand(getHome()), executable,
debug, useCaches, useSharing, getProperties().toList());
}

Expand Down
79 changes: 12 additions & 67 deletions src/main/java/hudson/plugins/mercurial/MercurialSCM.java
Expand Up @@ -35,19 +35,16 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import java.util.regex.Matcher;
Expand Down Expand Up @@ -96,18 +93,16 @@ public class MercurialSCM extends SCM implements Serializable {
private final String subdir;

private final boolean clean;
private final boolean forest;

private HgBrowser browser;

@DataBoundConstructor
public MercurialSCM(String installation, String source, String branch, String modules, String subdir, HgBrowser browser, boolean clean, boolean forest) {
public MercurialSCM(String installation, String source, String branch, String modules, String subdir, HgBrowser browser, boolean clean) {
this.installation = installation;
this.source = source;
this.modules = Util.fixNull(modules);
this.subdir = Util.fixEmptyAndTrim(subdir);
this.clean = clean;
this.forest = forest;
parseModules();
branch = Util.fixEmpty(branch);
if (branch != null && branch.equals("default")) {
Expand Down Expand Up @@ -197,13 +192,6 @@ public boolean isClean() {
return clean;
}

/**
* True if we want consider repository a forest
*/
public boolean isForest() {
return forest;
}

private ArgumentListBuilder findHgExe(AbstractBuild<?,?> build, TaskListener listener, boolean allowDebug) throws IOException, InterruptedException {
return findHgExe(build.getBuiltOn(), listener, allowDebug);
}
Expand All @@ -219,23 +207,6 @@ ArgumentListBuilder findHgExe(Node node, TaskListener listener, boolean allowDeb
// XXX what about forEnvironment?
ArgumentListBuilder b = new ArgumentListBuilder(inst.executableWithSubstitution(
inst.forNode(node, listener).getHome()));
if (forest) {
String downloadForest = inst.getDownloadForest();
if (downloadForest != null) {
// Uniquify path so if user chooses a different URL it will be downloaded again.
FilePath forestPy = node.getRootPath().child(String.format("forest-%08X.py", downloadForest.hashCode()));
if (!forestPy.exists()) {
listener.getLogger().println("Downloading: " + downloadForest);
InputStream is = new URL(downloadForest).openStream();
try {
forestPy.copyFrom(is);
} finally {
is.close();
}
}
b.add("--config", "extensions.forest=" + forestPy.getRemote());
}
}
if (allowDebug && inst.getDebug()) {
b.add("--debug");
}
Expand Down Expand Up @@ -289,21 +260,10 @@ protected PollingResult compareRemoteRevisionWith(AbstractProject<?, ?> project,
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ForkOutputStream fos = new ForkOutputStream(baos, output);

if (forest) {
logCmd.add("--prune", ".");
StringTokenizer trees = new StringTokenizer(hg.popen(repository, listener, false, new ArgumentListBuilder("ftrees", "--convert")));
while (trees.hasMoreTokens()) {
String tree = trees.nextToken();
joinWithPossibleTimeout(
launch(launcher).cmds(logCmd).stdout(fos).pwd(tree.equals(".") ? repository : repository.child(tree)),
true, listener);
}
} else {
logCmd.add("--prune", baseline.id);
joinWithPossibleTimeout(
launch(launcher).cmds(logCmd).stdout(fos).pwd(repository),
true, listener);
}
logCmd.add("--prune", baseline.id);
joinWithPossibleTimeout(
launch(launcher).cmds(logCmd).stdout(fos).pwd(repository),
true, listener);

MercurialTagAction cur = parsePollingLogOutput(baos, baseline, changedFileNames);
return new PollingResult(baseline,cur,computeDegreeOfChanges(changedFileNames,output));
Expand All @@ -314,7 +274,7 @@ protected PollingResult compareRemoteRevisionWith(AbstractProject<?, ?> project,

private void pull(Launcher launcher, FilePath repository, TaskListener listener, PrintStream output, Node node, String branch) throws IOException, InterruptedException {
ArgumentListBuilder cmd = findHgExe(node, listener, false);
cmd.add(forest ? "fpull" : "pull");
cmd.add("pull");
cmd.add("--rev", branch);
PossiblyCachedRepo cachedSource = cachedSource(node, launcher, listener, true);
if (cachedSource != null) {
Expand Down Expand Up @@ -510,7 +470,7 @@ private boolean update(AbstractBuild<?, ?> build, Launcher launcher, FilePath re
}

try {
if(hg.run(forest ? "fupdate" : "update", "--clean", "--rev", getBranch(env)).pwd(repository).join()!=0) {
if(hg.run("update", "--clean", "--rev", getBranch(env)).pwd(repository).join()!=0) {
listener.error("Failed to update");
return false;
}
Expand All @@ -521,20 +481,9 @@ private boolean update(AbstractBuild<?, ?> build, Launcher launcher, FilePath re
}

if(clean) {
if (forest) {
StringTokenizer trees = new StringTokenizer(hg.popen(repository, listener, false, new ArgumentListBuilder("ftrees", "--convert")));
while (trees.hasMoreTokens()) {
String tree = trees.nextToken();
if (hg.cleanAll().pwd(tree.equals(".") ? repository : repository.child(tree)).join() != 0) {
listener.error("Failed to clean unversioned files in " + tree);
return false;
}
}
} else {
if (hg.cleanAll().pwd(repository).join() != 0) {
listener.error("Failed to clean unversioned files");
return false;
}
if (hg.cleanAll().pwd(repository).join() != 0) {
listener.error("Failed to clean unversioned files");
return false;
}
}

Expand Down Expand Up @@ -576,7 +525,7 @@ private boolean clone(AbstractBuild<?,?> build, Launcher launcher, FilePath repo
args.add(cachedSource.getRepoLocation());
}
} else {
args.add(forest ? "fclone" : "clone");
args.add("clone");
args.add("--rev", getBranch(env));
args.add("--noupdate");
args.add(source);
Expand Down Expand Up @@ -608,7 +557,7 @@ private boolean clone(AbstractBuild<?,?> build, Launcher launcher, FilePath repo
}

ArgumentListBuilder upArgs = new ArgumentListBuilder();
upArgs.add(forest ? "fupdate" : "update");
upArgs.add("update");
upArgs.add("--rev", getBranch(env));
hg.run(upArgs).pwd(repository).join();

Expand Down Expand Up @@ -647,10 +596,6 @@ public String getModules() {
if (!CACHE_LOCAL_REPOS && source.matches("(file:|[/\\\\]).+")) {
return null;
}
if (forest) {
// Caching forests not supported yet - too complicated.
return null;
}
boolean useCaches = false;
MercurialInstallation _installation = null;
for (MercurialInstallation inst : MercurialInstallation.allInstallations()) {
Expand Down
Expand Up @@ -17,7 +17,4 @@
<f:entry field="debug" title="${%Debug Flag}">
<f:checkbox/>
</f:entry>
<f:entry title="${%Download Forest extension}" field="downloadForest">
<f:textbox/>
</f:entry>
</j:jelly>

This file was deleted.

@@ -1,6 +1,6 @@
<div>
When checked, Hudson will maintain a cache of the Mercurial repository in use
by a project. (Does not apply to projects using the Forest extension.) The
by a project. The
cache will be kept on the master node, updated on demand, and additional
caches may be kept on slave nodes running this job. All jobs pointing to the
same repository location will share a single cache (even if they use different
Expand Down
@@ -1,8 +1,7 @@
<div>
<p>When checked, different clones of the same repository will
<a href="http://mercurial.selenic.com/wiki/ShareExtension">share</a> the
history portion of the Mercurial. This does not apply to jobs using the
Forest extension.</p>
history portion of the Mercurial.</p>

<p>Enabling this option also automatically enables the caching option.</p>

Expand Down
Expand Up @@ -28,9 +28,6 @@
<f:entry field="subdir" title="${%Subdirectory}">
<f:textbox/>
</f:entry>
<f:entry field="forest" title="${%Forest Extension - EXPERIMENTAL}">
<f:checkbox/>
</f:entry>
</f:advanced>

<t:listScmBrowsers name="mercurial.browser" />
Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion src/main/resources/index.jelly
Expand Up @@ -2,6 +2,6 @@
This plugin integrates <a href="http://www.selenic.com/mercurial/">Mercurial SCM</a> with Hudson.
It includes repository browsing support for <code>hg serve</code>/<code>hgweb</code>,
Google Code, Bitbucket, FishEye, KilnHG and RhodeCode. Features include guaranteed clean builds, named branch
support, Forest extension support, module lists, Mercurial tool installation, and
support, module lists, Mercurial tool installation, and
automatic caching.
</div>
2 changes: 1 addition & 1 deletion src/test/java/hudson/plugins/mercurial/CachingSCMTest.java
Expand Up @@ -17,7 +17,7 @@ void setUp() throws Exception {
.getDescriptorByType(MercurialInstallation.DescriptorImpl.class)
.setInstallations(
new MercurialInstallation(CACHING_INSTALLATION, "",
"hg", null, false, true, false, Collections
"hg", false, true, false, Collections
.<ToolProperty<?>> emptyList()));
MercurialSCM.CACHE_LOCAL_REPOS = true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/hudson/plugins/mercurial/DebugFlagTest.java
Expand Up @@ -17,7 +17,7 @@ void setUp() throws Exception {
.getDescriptorByType(MercurialInstallation.DescriptorImpl.class)
.setInstallations(
new MercurialInstallation(DEBUG_INSTALLATION, "", "hg",
null, true, false, false, Collections
true, false, false, Collections
.<ToolProperty<?>> emptyList()));
}

Expand Down
51 changes: 0 additions & 51 deletions src/test/java/hudson/plugins/mercurial/ForestTest.java

This file was deleted.

0 comments on commit e314ee8

Please sign in to comment.