aboutsummaryrefslogtreecommitdiffstats
path: root/anttasks
diff options
context:
space:
mode:
Diffstat (limited to 'anttasks')
-rw-r--r--anttasks/src/com/android/ant/AaptExecTask.java47
-rw-r--r--anttasks/src/com/android/ant/BuildConfigTask.java68
-rw-r--r--anttasks/src/com/android/ant/BuildTypedTask.java63
-rw-r--r--anttasks/src/com/android/ant/DependencyGraph.java26
-rw-r--r--anttasks/src/com/android/ant/DexExecTask.java3
-rw-r--r--anttasks/src/com/android/ant/InputPath.java20
-rw-r--r--anttasks/src/com/android/ant/SingleDependencyTask.java51
7 files changed, 248 insertions, 30 deletions
diff --git a/anttasks/src/com/android/ant/AaptExecTask.java b/anttasks/src/com/android/ant/AaptExecTask.java
index 45adc7c..8731732 100644
--- a/anttasks/src/com/android/ant/AaptExecTask.java
+++ b/anttasks/src/com/android/ant/AaptExecTask.java
@@ -25,6 +25,7 @@ import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
/**
* Task to execute aapt.
@@ -95,6 +96,46 @@ public final class AaptExecTask extends SingleDependencyTask {
private boolean mNonConstantId;
/**
+ * Input path that ignores the same file that aapt does.
+ */
+ private static class ResFolderInputPath extends InputPath {
+ public ResFolderInputPath(File file, Set<String> extensionsToCheck) {
+ super(file, extensionsToCheck);
+ }
+
+ @Override
+ public boolean ignores(File file) {
+ String name = file.getName();
+ char firstChar = name.charAt(0);
+
+ if (firstChar == '.' || (firstChar == '_' && file.isDirectory()) ||
+ name.charAt(name.length()-1) == '~') {
+ return true;
+ }
+
+ if ("CVS".equals(name) ||
+ "thumbs.db".equalsIgnoreCase(name) ||
+ "picasa.ini".equalsIgnoreCase(name)) {
+ return true;
+ }
+
+ String ext = getExtension(name);
+ if ("scc".equalsIgnoreCase(ext)) {
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ private final static InputPathFactory sPathFactory = new InputPathFactory() {
+
+ public InputPath createPath(File file, Set<String> extensionsToCheck) {
+ return new ResFolderInputPath(file, extensionsToCheck);
+ }
+ };
+
+ /**
* Sets the value of the "executable" attribute.
* @param executable the value.
*/
@@ -351,7 +392,8 @@ public final class AaptExecTask extends SingleDependencyTask {
if (generateRClass) {
// in this case we only want to run aapt if an XML file was touched, or if any
// file is added/removed
- List<InputPath> inputPaths = getInputPaths(paths, Collections.singleton("xml"));
+ List<InputPath> inputPaths = getInputPaths(paths, Collections.singleton("xml"),
+ sPathFactory);
// let's not forget the manifest as an input path (with no extension restrictions).
if (mManifest != null) {
@@ -369,7 +411,8 @@ public final class AaptExecTask extends SingleDependencyTask {
} else {
// in this case we want to run aapt if any file was updated/removed/added in any of the
// input paths
- List<InputPath> inputPaths = getInputPaths(paths, null /*extensionsToCheck*/);
+ List<InputPath> inputPaths = getInputPaths(paths, null /*extensionsToCheck*/,
+ sPathFactory);
// let's not forget the manifest as an input path.
if (mManifest != null) {
diff --git a/anttasks/src/com/android/ant/BuildConfigTask.java b/anttasks/src/com/android/ant/BuildConfigTask.java
new file mode 100644
index 0000000..08f91e9
--- /dev/null
+++ b/anttasks/src/com/android/ant/BuildConfigTask.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+package com.android.ant;
+
+import com.android.sdklib.internal.build.BuildConfigGenerator;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Path;
+
+import java.io.IOException;
+
+public class BuildConfigTask extends BuildTypedTask {
+
+ private String mGenFolder;
+ private String mAppPackage;
+
+ public void setGenFolder(Path path) {
+ mGenFolder = TaskHelper.checkSinglePath("genFolder", path);
+ }
+
+ public void setPackage(String appPackage) {
+ mAppPackage = appPackage;
+ }
+
+
+ @Override
+ public void execute() throws BuildException {
+ if (mGenFolder == null) {
+ throw new BuildException("Missing attribute genFolder");
+ }
+ if (mAppPackage == null) {
+ throw new BuildException("Missing attribute package");
+ }
+
+ if (hasBuildTypeChanged()) {
+ if (isNewBuild()) {
+ System.out.println("Generating BuildConfig class.");
+ } else {
+ System.out.println("Build type changed: Generating new BuildConfig class.");
+ }
+ BuildConfigGenerator generator = new BuildConfigGenerator(
+ mGenFolder, mAppPackage,
+ Boolean.parseBoolean(getBuildType()));
+
+ try {
+ generator.generate();
+ } catch (IOException e) {
+ throw new BuildException("Failed to create BuildConfig class", e);
+ }
+ } else {
+ System.out.println("No need to generate new BuildConfig.");
+ }
+ }
+}
diff --git a/anttasks/src/com/android/ant/BuildTypedTask.java b/anttasks/src/com/android/ant/BuildTypedTask.java
new file mode 100644
index 0000000..c697bac
--- /dev/null
+++ b/anttasks/src/com/android/ant/BuildTypedTask.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+package com.android.ant;
+
+import org.apache.tools.ant.Task;
+
+/**
+ * Base class for tasks that should exec when the build type change.
+ */
+public abstract class BuildTypedTask extends Task {
+
+ private String mPreviousBuildType;
+ private String mBuildType;
+
+ /** Sets the current build type */
+ public void setBuildType(String buildType) {
+ mBuildType = buildType;
+ }
+
+ /** Sets the previous build type */
+ public void setPreviousBuildType(String previousBuildType) {
+ mPreviousBuildType = previousBuildType;
+ }
+
+ protected String getBuildType() {
+ return mBuildType;
+ }
+
+ /**
+ * Returns if it is a new build. If the built type is not input
+ * from the XML, this always returns true.
+ * A build type is defined by having an empty previousBuildType.
+ */
+ protected boolean isNewBuild() {
+ return mBuildType == null || mPreviousBuildType.length() == 0;
+ }
+
+ /**
+ * Returns true if the build type changed.
+ */
+ protected boolean hasBuildTypeChanged() {
+ // no build type? return false as the feature is simply not used
+ if (mBuildType == null && mPreviousBuildType == null) {
+ return false;
+ }
+
+ return mBuildType.equals(mPreviousBuildType) == false;
+ }
+}
diff --git a/anttasks/src/com/android/ant/DependencyGraph.java b/anttasks/src/com/android/ant/DependencyGraph.java
index 1885c17..8671359 100644
--- a/anttasks/src/com/android/ant/DependencyGraph.java
+++ b/anttasks/src/com/android/ant/DependencyGraph.java
@@ -35,6 +35,8 @@ import java.util.Set;
*/
public class DependencyGraph {
+ private final static boolean DEBUG = false;
+
private static enum DependencyStatus {
NONE, NEW_FILE, UPDATED_FILE, MISSING_FILE, ERROR;
}
@@ -189,6 +191,9 @@ public class DependencyGraph {
mPrereqs = new HashSet<File>(prereqs.length);
for (String path : prereqs) {
if (path.length() > 0) {
+ if (DEBUG) {
+ System.out.println("PREREQ: " + path);
+ }
File f = new File(path);
if (mFirstPrereq == null) {
mFirstPrereq = f;
@@ -290,12 +295,19 @@ public class DependencyGraph {
// files to go through manually
if (mPrereqs.remove(file) == false) {
// turns out this is a new file!
+
+ if (DEBUG) {
+ System.out.println("NEW FILE: " + file.getAbsolutePath());
+ }
return DependencyStatus.NEW_FILE;
} else {
// check the time stamp on this file if it's a file we care about based what the
// input folder decides.
if (inputFolder.checksForModification(file)) {
if (file.lastModified() > oldestTarget) {
+ if (DEBUG) {
+ System.out.println("UPDATED FILE: " + file.getAbsolutePath());
+ }
return DependencyStatus.UPDATED_FILE;
}
}
@@ -319,6 +331,9 @@ public class DependencyGraph {
// Loop through our prereq files and make sure they still exist
for (File prereq : mPrereqs) {
if (prereq.exists() == false) {
+ if (DEBUG) {
+ System.out.println("MISSING FILE: " + prereq.getAbsolutePath());
+ }
return DependencyStatus.MISSING_FILE;
}
@@ -336,6 +351,10 @@ public class DependencyGraph {
// check if we need to check this type of file, and if yes, check it.
if (input.checksForModification(prereq)) {
if (prereq.lastModified() > oldestTarget) {
+ if (DEBUG) {
+ System.out.println(
+ "UPDATED FILE: " + prereq.getAbsolutePath());
+ }
return DependencyStatus.UPDATED_FILE;
}
}
@@ -345,6 +364,10 @@ public class DependencyGraph {
if (prereq.equals(inputFile)) {
if (input.checksForModification(prereq)) {
if (prereq.lastModified() > oldestTarget) {
+ if (DEBUG) {
+ System.out.println(
+ "UPDATED FILE: " + prereq.getAbsolutePath());
+ }
return DependencyStatus.UPDATED_FILE;
}
}
@@ -354,6 +377,9 @@ public class DependencyGraph {
} else {
// no input? we consider all files.
if (prereq.lastModified() > oldestTarget) {
+ if (DEBUG) {
+ System.out.println("UPDATED FILE: " + prereq.getAbsolutePath());
+ }
return DependencyStatus.UPDATED_FILE;
}
}
diff --git a/anttasks/src/com/android/ant/DexExecTask.java b/anttasks/src/com/android/ant/DexExecTask.java
index 6be0a98..2d9479e 100644
--- a/anttasks/src/com/android/ant/DexExecTask.java
+++ b/anttasks/src/com/android/ant/DexExecTask.java
@@ -129,7 +129,8 @@ public class DexExecTask extends SingleDependencyTask {
String depFile = mOutput + ".d";
// get InputPath with no extension restrictions
- List<InputPath> inputPaths = getInputPaths(paths, null /*extensionsToCheck*/);
+ List<InputPath> inputPaths = getInputPaths(paths, null /*extensionsToCheck*/,
+ null /*factory*/);
if (initDependencies(depFile, inputPaths) && dependenciesHaveChanged() == false) {
System.out.println(
diff --git a/anttasks/src/com/android/ant/InputPath.java b/anttasks/src/com/android/ant/InputPath.java
index 3327385..b1a98b5 100644
--- a/anttasks/src/com/android/ant/InputPath.java
+++ b/anttasks/src/com/android/ant/InputPath.java
@@ -72,23 +72,33 @@ public class InputPath {
* @return true if the file or folder are ignored.
*/
public boolean ignores(File file) {
- return false;
+ // always ignore hidden files/folders.
+ return file.getName().startsWith(".") == false;
}
/**
* Gets the extension (if present) on a file by looking at the filename
- * @param file the file to get the extension of
+ * @param file the file to get the extension from
* @return the extension if present, or the empty string if the filename doesn't have
* and extension.
*/
protected static String getExtension(File file) {
- String filename = file.getName();
- int index = filename.lastIndexOf('.');
+ return getExtension(file.getName());
+ }
+
+ /**
+ * Gets the extension (if present) on a file by looking at the filename
+ * @param fileName the filename to get the extension from
+ * @return the extension if present, or the empty string if the filename doesn't have
+ * and extension.
+ */
+ protected static String getExtension(String fileName) {
+ int index = fileName.lastIndexOf('.');
if (index == -1) {
return "";
}
// Don't include the leading '.' in the extension
- return filename.substring(index + 1);
+ return fileName.substring(index + 1);
}
}
diff --git a/anttasks/src/com/android/ant/SingleDependencyTask.java b/anttasks/src/com/android/ant/SingleDependencyTask.java
index dc3e15d..926e59c 100644
--- a/anttasks/src/com/android/ant/SingleDependencyTask.java
+++ b/anttasks/src/com/android/ant/SingleDependencyTask.java
@@ -17,7 +17,6 @@
package com.android.ant;
import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
import java.io.File;
import java.io.FileNotFoundException;
@@ -29,21 +28,21 @@ import java.util.Set;
/**
* A base class for ant tasks that use a single dependency files to control (re)execution.
*/
-public abstract class SingleDependencyTask extends Task {
+public abstract class SingleDependencyTask extends BuildTypedTask {
private DependencyGraph mDependencies;
- private String mPreviousBuildType;
- private String mBuildType;
- public void setPreviousBuildType(String previousBuildType) {
- mPreviousBuildType = previousBuildType;
- }
+ protected abstract String getExecTaskName();
- public void setBuildType(String buildType) {
- mBuildType = buildType;
+ protected interface InputPathFactory {
+ InputPath createPath(File file, Set<String> extensionsToCheck);
}
- protected abstract String getExecTaskName();
+ private final static InputPathFactory sDefaultFactory = new InputPathFactory() {
+ public InputPath createPath(File file, Set<String> extensionsToCheck) {
+ return new InputPath(file, extensionsToCheck);
+ }
+ };
/**
* Creates a list of {@link InputPath} from a list of {@link File} and an optional list of
@@ -55,11 +54,15 @@ public abstract class SingleDependencyTask extends Task {
* @return a list of {@link InputPath}
*/
protected static List<InputPath> getInputPaths(List<File> paths,
- Set<String> extensionsToCheck) {
+ Set<String> extensionsToCheck, InputPathFactory factory) {
List<InputPath> result = new ArrayList<InputPath>(paths.size());
+ if (factory == null ) {
+ factory = sDefaultFactory;
+ }
+
for (File f : paths) {
- result.add(new InputPath(f, extensionsToCheck));
+ result.add(factory.createPath(f, extensionsToCheck));
}
return result;
@@ -73,7 +76,7 @@ public abstract class SingleDependencyTask extends Task {
* @return true if the dependency graph was successfully initialized
*/
protected boolean initDependencies(String dependencyFile, List<InputPath> inputPaths) {
- if (mBuildType != null && mBuildType.equals(mPreviousBuildType) == false) {
+ if (hasBuildTypeChanged()) {
// we don't care about deps, we need to execute the task no matter what.
return true;
}
@@ -93,15 +96,19 @@ public abstract class SingleDependencyTask extends Task {
* have changed since the last run
*/
protected boolean dependenciesHaveChanged() {
- if (mBuildType != null && mBuildType.equals(mPreviousBuildType) == false) {
- String execName = getExecTaskName();
- if (execName == null) {
- System.out.println(
- "Current build type is different than previous build: forced task run.");
- } else {
- System.out.println(
- "Current build type is different than previous build: forced " +
- execName + " run.");
+ if (hasBuildTypeChanged()) {
+ // if this is not a new build, display that build type change is forcing running
+ // the task.
+ if (isNewBuild() == false) {
+ String execName = getExecTaskName();
+ if (execName == null) {
+ System.out.println(
+ "Current build type is different than previous build: forced task run.");
+ } else {
+ System.out.println(
+ "Current build type is different than previous build: forced " +
+ execName + " run.");
+ }
}
return true;
}