diff options
Diffstat (limited to 'anttasks')
-rw-r--r-- | anttasks/src/com/android/ant/AaptExecTask.java | 47 | ||||
-rw-r--r-- | anttasks/src/com/android/ant/BuildConfigTask.java | 68 | ||||
-rw-r--r-- | anttasks/src/com/android/ant/BuildTypedTask.java | 63 | ||||
-rw-r--r-- | anttasks/src/com/android/ant/DependencyGraph.java | 26 | ||||
-rw-r--r-- | anttasks/src/com/android/ant/DexExecTask.java | 3 | ||||
-rw-r--r-- | anttasks/src/com/android/ant/InputPath.java | 20 | ||||
-rw-r--r-- | anttasks/src/com/android/ant/SingleDependencyTask.java | 51 |
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; } |