diff --git a/updateMonotone/build.xml b/updateMonotone/build.xml new file mode 100644 index 0000000..13cba37 --- /dev/null +++ b/updateMonotone/build.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Builds, tests, and runs the project updateMonotone. + + + diff --git a/updateMonotone/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar b/updateMonotone/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar new file mode 100644 index 0000000..0297ed6 Binary files /dev/null and b/updateMonotone/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar differ diff --git a/updateMonotone/lib/nblibraries-private.properties b/updateMonotone/lib/nblibraries-private.properties new file mode 100644 index 0000000..e69de29 diff --git a/updateMonotone/lib/nblibraries.properties b/updateMonotone/lib/nblibraries.properties new file mode 100644 index 0000000..b191095 --- /dev/null +++ b/updateMonotone/lib/nblibraries.properties @@ -0,0 +1,12 @@ +libs.junit.classpath=\ + ${base}/junit/junit-3.8.2.jar +libs.junit.javadoc=\ + ${base}/junit/junit-3.8.2-api.zip +libs.junit_4.classpath=\ + ${base}/junit_4/junit-4.5.jar +libs.junit_4.javadoc=\ + ${base}/junit_4/junit-4.5-api.zip +libs.junit_4.src=\ + ${base}/junit_4/junit-4.5-src.jar +libs.CopyLibs.classpath=\ + ${base}/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar diff --git a/updateMonotone/manifest.mf b/updateMonotone/manifest.mf new file mode 100644 index 0000000..328e8e5 --- /dev/null +++ b/updateMonotone/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/updateMonotone/nbproject/build-impl.xml b/updateMonotone/nbproject/build-impl.xml new file mode 100644 index 0000000..9bab133 --- /dev/null +++ b/updateMonotone/nbproject/build-impl.xml @@ -0,0 +1,661 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + diff --git a/updateMonotone/nbproject/genfiles.properties b/updateMonotone/nbproject/genfiles.properties new file mode 100644 index 0000000..5f89fbc --- /dev/null +++ b/updateMonotone/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=5b771ce9 +build.xml.script.CRC32=2e04d301 +build.xml.stylesheet.CRC32=958a1d3e +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=5b771ce9 +nbproject/build-impl.xml.script.CRC32=42081327 +nbproject/build-impl.xml.stylesheet.CRC32=65b8de21 diff --git a/updateMonotone/nbproject/private/private.properties b/updateMonotone/nbproject/private/private.properties new file mode 100644 index 0000000..7fd79d7 --- /dev/null +++ b/updateMonotone/nbproject/private/private.properties @@ -0,0 +1,3 @@ +compile.on.save=true +jaxws.endorsed.dir=/usr/local/netbeans-6.5.1/java2/modules/ext/jaxws21/api:/usr/local/netbeans-6.5.1/ide10/modules/ext/jaxb/api +user.properties.file=/home/dream/.netbeans/6.5/build.properties diff --git a/updateMonotone/nbproject/private/private.xml b/updateMonotone/nbproject/private/private.xml new file mode 100644 index 0000000..c2b6ac5 --- /dev/null +++ b/updateMonotone/nbproject/private/private.xml @@ -0,0 +1,8 @@ + + + + + file:/home/dream/code/updateMonotone/src/updatemonotone/Main.java + file:/home/dream/code/updateMonotone/src/updatemonotone/Updater.java + + diff --git a/updateMonotone/nbproject/project.properties b/updateMonotone/nbproject/project.properties new file mode 100644 index 0000000..a672242 --- /dev/null +++ b/updateMonotone/nbproject/project.properties @@ -0,0 +1,61 @@ +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/updateMonotone.jar +dist.javadoc.dir=${dist.dir}/javadoc +excludes= +includes=** +jar.compress=false +javac.classpath= +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit.classpath}:\ + ${libs.junit_4.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=updatemonotone.Main +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/updateMonotone/nbproject/project.xml b/updateMonotone/nbproject/project.xml new file mode 100644 index 0000000..a99a874 --- /dev/null +++ b/updateMonotone/nbproject/project.xml @@ -0,0 +1,19 @@ + + + org.netbeans.modules.java.j2seproject + + + updateMonotone + 1.6.5 + + + + + + + + + ./lib/nblibraries.properties + + + diff --git a/updateMonotone/src/updatemonotone/Main.java b/updateMonotone/src/updatemonotone/Main.java new file mode 100644 index 0000000..e2b6091 --- /dev/null +++ b/updateMonotone/src/updatemonotone/Main.java @@ -0,0 +1,30 @@ +package updatemonotone; + +import java.io.File; + +public class Main { + + public static void main(String[] args) { + String[] modules = { + "i2p","www", + "scripts","Seedless", + "i2p-bote", + "plugins.jIRCii", + "translator" + }; + final File top = new File(new File(System.getenv("HOME"),"packages"),"mtn"); + top.mkdirs(); + Updater monotone = new Updater(top,prefix("i2p",modules),new Range(8996,8999)); + if(System.getenv("NOSYNC")==null) monotone.sync(); + monotone.checkout(); + System.exit(0); + } + + private static String[] prefix(String string, String[] modules) { + for(int i=0;i { + final int bottom; + final int top; + final int span; + final int randthing; + int offset; + + public RangeIterator(int bottom, int top) { + this.bottom = bottom; + this.top = top; + this.span = top - bottom; + // XXX: This is a horrid hack. Ranges do not work this way what are u doin + this.randthing = (int) (Math.random() * span); + offset = 0; + } + + public boolean hasNext() { + return offset { + private final int top; + private final int bottom; + public Range(int bottom, int top) { + this.bottom = bottom; + this.top = top; + } + + public Iterator iterator() { + return new RangeIterator(bottom,top); + } + +} \ No newline at end of file diff --git a/updateMonotone/src/updatemonotone/Updater.java b/updateMonotone/src/updatemonotone/Updater.java new file mode 100644 index 0000000..0030d5d --- /dev/null +++ b/updateMonotone/src/updatemonotone/Updater.java @@ -0,0 +1,202 @@ +package updatemonotone; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.Queue; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.logging.Level; +import java.util.logging.Logger; + +class Updater { + + final String[] modules; + final Range range; + final File top; + final File database; + final File keydir; + File monotone = null; + private static final ExecutorService executor = Executors.newFixedThreadPool(4); + + OutputStream log; + + public Updater(File top, String[] modules, Range range) { + this.keydir = new File(new File(System.getenv("HOME"),".monotone"),"keys"); + for (String path : System.getenv("PATH").split(":")) { + final File test = new File(path, "mtn"); + if (test.exists()) { + this.monotone = test; + break; + } + } + if (monotone == null) { + throw new RuntimeException("Could not find monotone mtn in " + System.getenv("PATH")); + } + System.out.println("Monotone: " + monotone); + this.modules = modules; + this.range = range; + this.top = top; + this.top.mkdirs(); + File dbdir = new File(top, "db"); + dbdir.mkdir(); + try { + log = new FileOutputStream(new File(top, "monotone.log")); + } catch (FileNotFoundException ex) { + Logger.getLogger(Updater.class.getName()).log(Level.SEVERE, null, ex); + log = System.err; + } + this.database = new File(dbdir, "monotone.sqlite"); + if (!this.database.exists()) { + waitFor(doit("Initializing a new database", + top, + "db", "init")); + } + System.out.println("Database: " + database); + System.out.println("Keydir: " + keydir); + } + + private String join(char separator, String[] ss) { + String sep = Character.toString(separator); + String result = null; + for (String s : ss) { + if (result == null) { + result = s; + } else { + result = result + sep + s; + } + } + return result; + } + + public void sync() { + // can't sync in parallel it screws up the... yeah + for (Integer port : range) { + final URL url; + try { + url = new URL("http", "127.0.0.1", port, "?" + join(';', modules)); + } catch (MalformedURLException ex) { + Logger.getLogger(Updater.class.getName()).log(Level.SEVERE, null, ex); + continue; + } + waitFor(doit("Synchronizing with port "+port, + top, + "-k", "dream-transport@mail.i2p", "sync", url.toExternalForm())); + break; + } + } + + public void checkout() { + // can't update in parallel it screws up the database + for (String module : modules) { + File dir = new File(top, module); + if (dir.exists()) { + waitFor(doit("Updating "+module, + dir, + "update")); + } else { + waitFor(doit("Checking out "+module, + top, + "co", "--branch=" + module)); + } + } + System.out.println("Done checking out."); + } + + private Future doit(String what, File cwd, String... args) { + return doit(args, cwd, what); + } + + private Future doit(String[] args, final File cwd, final String what) { + System.out.print(what+"..."); + System.out.flush(); + + final String[] fullargs = new String[args.length + 3]; + fullargs[0] = monotone.getAbsolutePath(); + fullargs[1] = "--db=" + database; + fullargs[2] = "--keydir=" + keydir; + //System.out.println("Doing " + join(' ', args)); + System.arraycopy(args, 0, fullargs, 3, args.length); + try { + Thread.sleep(1000); + } catch (InterruptedException ex) { + Logger.getLogger(Updater.class.getName()).log(Level.SEVERE, null, ex); + } + return executor.submit(new Runnable() { + + public void run() { + final ProcessBuilder builder = new ProcessBuilder(fullargs); + builder.directory(cwd); + builder.redirectErrorStream(true); + final Process process; + try { + process = builder.start(); + } catch (IOException ex) { + Logger.getLogger(Updater.class.getName()).log(Level.SEVERE, null, ex); + throw new RuntimeException("There was an IO failure dealing with Monotone"); + } + try { + process.getOutputStream().close(); + } catch (IOException ex) { + Logger.getLogger(Updater.class.getName()).log(Level.SEVERE, null, ex); + } + + InputStream stdout = process.getInputStream(); + byte[] buf = new byte[0x1000]; + for (;;) { + try { + int amount = stdout.read(buf); + if(amount<=0) break; + log.write(buf, 0, amount); + log.flush(); + } catch (IOException ex) { + Logger.getLogger(Updater.class.getName()).log(Level.SEVERE, null, ex); + break; + } + } + + for (;;) { + try { + process.waitFor(); + break; + } catch (InterruptedException ex) { + Logger.getLogger(Updater.class.getName()).log(Level.SEVERE, null, ex); + } + } + if (process.exitValue() != 0) { + System.err.print("Monotone failed for some reason"); + System.exit(0); + } + } + }); + } + + private void waitFor(Future f) { + waitFor(Arrays.asList(new Future[]{f})); + System.out.println("done."); + } + + private void waitFor(Iterable fs) { + for (Future f : fs) { + for (;;) { + try { + f.get(); + break; + } catch (InterruptedException ex) { + Logger.getLogger(Updater.class.getName()).log(Level.SEVERE, null, ex); + } catch (ExecutionException ex) { + Logger.getLogger(Updater.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + } +}