Filesystem.java \
Git.java \
Module.java \
- Modules.java \
MappedDirectory.java \
PullHarmonyCode.java \
+ PushAndroidCode.java \
Svn.java
LOCAL_MODULE:= integrate
* directory is nonempty.
*/
public int moveContents(String source, String target) {
+ return copyContents(true, source, target);
+ }
+
+ /**
+ * Copies all of the files in {@code source} to {@code target}, one at a
+ * time. Unlike {@code move}, this approach works even if the target
+ * directory is nonempty.
+ */
+ public int copyContents(String source, String target) {
+ return copyContents(false, source, target);
+ }
+
+ private int copyContents(boolean move, String source, String target) {
List<String> files = new Command("find", source, "-type", "f") .execute();
for (String file : files) {
String targetFile = target + "/" + file.substring(source.length());
mkdir(parent(targetFile));
- new Command("mv", "-i", file, targetFile).execute();
+ if (move) {
+ new Command("mv", "-i", file, targetFile).execute();
+ } else {
+ new Command("cp", file, targetFile).execute();
+ }
}
return files.size();
}
* limitations under the License.
*/
+import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
+import java.util.Map;
import java.util.Set;
/**
*/
class Module {
+ static final Map<String, Module> VALUES;
+ static {
+ Map<String, Module> valuesMutable = new LinkedHashMap<String, Module>();
+
+ String svnRoot = "http://svn.apache.org/repos/asf/harmony/enhanced/classlib/trunk/modules";
+ valuesMutable.put("archive", new Module.Builder(svnRoot, "archive")
+ .mapDirectory("archive/src/main/native/archive/shared",
+ "archive/src/main/native")
+ .mapDirectory("archive/src/main/native/zip/shared",
+ "archive/src/main/native")
+ .build());
+
+ valuesMutable.put("crypto", new Module.Builder(svnRoot, "crypto")
+ .mapDirectory("crypto/src/test/api/java.injected/javax",
+ "crypto/src/test/java/org/apache/harmony/crypto/tests/javax")
+ .mapDirectory("crypto/src/test/api/java",
+ "crypto/src/test/java")
+ .mapDirectory("crypto/src/test/resources/serialization",
+ "crypto/src/test/java/serialization")
+ .mapDirectory("crypto/src/test/support/common/java",
+ "crypto/src/test/java")
+ .build());
+
+ valuesMutable.put("regex", new Module.Builder(svnRoot, "regex").build());
+
+ valuesMutable.put("security", new Module.Builder(svnRoot, "security")
+ .mapDirectory("security/src/main/java/common",
+ "security/src/main/java")
+ .mapDirectory("security/src/main/java/unix/org",
+ "security/src/main/java/org")
+ .mapDirectory("security/src/test/api/java",
+ "security/src/test/java")
+ .build());
+
+ valuesMutable.put("text", new Module.Builder(svnRoot, "text").build());
+
+ valuesMutable.put("x-net", new Module.Builder(svnRoot, "x-net").build());
+
+ VALUES = Collections.unmodifiableMap(valuesMutable);
+ }
+
private final String svnBaseUrl;
private final String path;
private final Set<MappedDirectory> mappedDirectories;
+++ /dev/null
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Constants that define modules shared by Harmony and Dalvik.
- */
-public class Modules {
-
- private static final String SVN_ROOT
- = "http://svn.apache.org/repos/asf/harmony/enhanced/classlib/trunk/modules";
-
- public static final Module ARCHIVE = new Module.Builder(SVN_ROOT, "archive")
- .mapDirectory("archive/src/main/native/archive/shared",
- "archive/src/main/native")
- .mapDirectory("archive/src/main/native/zip/shared",
- "archive/src/main/native")
- .build();
-
- public static final Module CRYPTO = new Module.Builder(SVN_ROOT, "crypto")
- .mapDirectory("crypto/src/test/api/java.injected/javax",
- "crypto/src/test/java/org/apache/harmony/crypto/tests/javax")
- .mapDirectory("crypto/src/test/api/java",
- "crypto/src/test/java")
- .mapDirectory("crypto/src/test/resources/serialization",
- "crypto/src/test/java/serialization")
- .mapDirectory("crypto/src/test/support/common/java",
- "crypto/src/test/java")
- .build();
-
- public static final Module REGEX
- = new Module.Builder(SVN_ROOT, "regex").build();
-
- public static final Module SECURITY = new Module.Builder(SVN_ROOT, "security")
- .mapDirectory("security/src/main/java/common",
- "security/src/main/java")
- .mapDirectory("security/src/main/java/unix/org",
- "security/src/main/java/org")
- .mapDirectory("security/src/test/api/java",
- "security/src/test/java")
- .build();
-
- public static final Module TEXT
- = new Module.Builder(SVN_ROOT, "text").build();
-
- public static final Module X_NET
- = new Module.Builder(SVN_ROOT, "x-net").build();
-
- // TODO: add the other modules
-}
}
}
+
public static void main(String[] args) {
-// new PullHarmonyCode(527399, 802921).pull(Modules.CRYPTO);
- new PullHarmonyCode(772995, 802921).pull(Modules.ARCHIVE);
+ if (args.length < 3) {
+ printUsage();
+ return;
+ }
+
+ int currentSvnRev = Integer.parseInt(args[0]);
+ int targetSvnRev = Integer.parseInt(args[1]);
+
+ if (currentSvnRev < 527399 || targetSvnRev <= currentSvnRev) {
+ System.out.println("Invalid SVN revision range: "
+ + currentSvnRev + ".." + targetSvnRev);
+ return;
+ }
+
+ Module module = Module.VALUES.get(args[2]);
+ if (module == null) {
+ System.out.println("No such module: " + args[2]);
+ return;
+ }
+
+ PullHarmonyCode puller = new PullHarmonyCode(currentSvnRev, targetSvnRev);
+ puller.pull(module);
+ }
+
+ private static void printUsage() {
+ System.out.println("This tool will prepare a three-way merge between the latest Harmony");
+ System.out.println("the latest Dalvik, and their common ancestor. It downloads both old");
+ System.out.println("and new versions of Harmony code from SVN for better merge results.");
+ System.out.println();
+ System.out.println("Usage: PullHarmonyCode <current_rev> <target_rev> <module>...");
+ System.out.println();
+ System.out.println(" <current_rev> is the SVN revision of the Harmony code that was");
+ System.out.println(" most recently integrated into Dalvik. This should");
+ System.out.println(" be a number greater than 527399. The current");
+ System.out.println(" revision for each module is tracked at");
+ System.out.println(" http://go/dalvik/harmony");
+ System.out.println();
+ System.out.println(" <target_rev> is the SVN revision of the Harmony code to be");
+ System.out.println(" merged into Dalvik. This should be a number greater");
+ System.out.println(" than <current_rev>. The latest Harmony revision is");
+ System.out.println(" tracked at");
+ System.out.println(" http://svn.apache.org/viewvc/harmony/?root=Apache-SVN");
+ System.out.println();
+ System.out.println(" <module> is one of " + Module.VALUES.keySet());
+ System.out.println();
+ System.out.println("This program must be executed from within the dalvik/libcore directory");
+ System.out.println("of an Android git client. Such a client must be synced and contain no");
+ System.out.println("uncommitted changes. Upon termination, a new Git branch with the");
+ System.out.println("integrated changes will be active. This branch may require some manual");
+ System.out.println("merging.");
+ System.out.println();
+ System.out.println("Example usage:");
+ System.out.println(" java -cp ../../out/host/linux-x86/framework/integrate.jar PullAndroidCode \\");
+ System.out.println(" 527399 802921 security");
}
}
--- /dev/null
+// Copyright 2009 Google Inc. All Rights Reserved.
+
+import java.util.UUID;
+
+/**
+ * Copy the current Android sourcecode into Apache Harmony, where it can be
+ * reviewed and submitted to their SVN. Only run this script after first merging
+ * the latest harmony code into Android.
+ */
+public class PushAndroidCode {
+
+ private final String androidPath;
+ private final String harmonyPath;
+
+ public PushAndroidCode(String androidPath, String harmonyPath) {
+ this.androidPath = androidPath;
+ this.harmonyPath = harmonyPath;
+ }
+
+ public void push(Module module) {
+ Filesystem filesystem = new Filesystem();
+
+ // copy android code to a temp directory that is laid out like Harmony
+ String temp = "/tmp/" + UUID.randomUUID();
+ filesystem.mkdir(temp);
+ filesystem.copyContents(androidPath + "/" + module.path(),
+ temp + "/" + module.path());
+ for (MappedDirectory mappedDirectory : module.getMappedDirectories()) {
+ filesystem.moveContents(
+ temp + "/" + mappedDirectory.gitPath(),
+ temp + "/" + mappedDirectory.svnPath());
+ }
+
+ // clobber files from harmony with their Android equivalents
+ filesystem.copyContents(temp + "/" + module.path(),
+ harmonyPath + "/" + module.path());
+ }
+
+ public static void main(String[] args) {
+ if (args.length < 3) {
+ printUsage();
+ return;
+ }
+
+ String androidPath = args[0] + "/dalvik/libcore";
+ String harmonyPath = args[1] + "/working_classlib/modules";
+
+ // TODO: validate directories?
+
+ Module[] modules = new Module[args.length - 2];
+ for (int i = 0; i < modules.length; i++) {
+ modules[i] = Module.VALUES.get(args[i+2]);
+ if (modules[i] == null) {
+ System.out.println("No such module: " + args[i+2]);
+ return;
+ }
+ }
+
+ PushAndroidCode pusher = new PushAndroidCode(androidPath, harmonyPath);
+ for (Module module : modules) {
+ pusher.push(module);
+ }
+ }
+
+ private static void printUsage() {
+ System.out.println("This tool will clobber Harmony's core libraries with Android's copy");
+ System.out.println("so that a patch can be submitted upstream.");
+ System.out.println();
+ System.out.println("Usage: PushAndroidCode <android_root> <harmony_root> <module>...");
+ System.out.println();
+ System.out.println(" <android_root> is the android git client directory that contains dalvik");
+ System.out.println(" This should hold an up-to-date checkout of Android. The");
+ System.out.println(" target modules should also be up-to-date with respect to");
+ System.out.println(" Harmony; use the PullHarmonyCode tool first if necessary.");
+ System.out.println();
+ System.out.println(" <harmony_root> is the android client directory that contains working_classlib.");
+ System.out.println(" This should hold an up-to-date checkout of Harmony.");
+ System.out.println();
+ System.out.println(" <module> is one of " + Module.VALUES.keySet());
+ System.out.println();
+ System.out.println("Example usage:");
+ System.out.println(" java -cp out/host/linux-x86/framework/integrate.jar PushAndroidCode \\");
+ System.out.println(" /usr/local/google/jesse/clients/jessewilson_g1 \\");
+ System.out.println(" /usr/local/google/jesse/clients/jessewilson_h0/trunk \\");
+ System.out.println(" crypto");
+ }
+}