| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 org.netbeans.nbbuild; |
| |
| import java.io.File; |
| import java.util.*; |
| |
| import org.apache.tools.ant.BuildException; |
| import org.apache.tools.ant.Project; |
| import org.apache.tools.ant.Target; |
| import org.apache.tools.ant.Task; |
| |
| /** Pseudo-task to unpack a set of modules. |
| * Causes the containing target to both depend on the building of the modules in |
| * the first place; and then to unpack them all to a certain location. |
| * |
| * @author various people |
| * |
| * 2002-07-31: Rudolf Balada Added build success granularity (Issue 9701), |
| * fixed modules can't fail, "modules" can fail |
| */ |
| public class NbMerge extends Task { |
| |
| private File dest; |
| private Vector<String> modules = new Vector<> (); // list of modules defined by build.xml |
| private Vector<String> buildmodules = new Vector<> (); // list of modules which will be built |
| private Vector<String> fixedmodules = new Vector<> (); // list of fixed modules defined in build.xml |
| private Vector<String> buildfixedmodules = new Vector<> (); // List of fixed modules which will be built |
| private Vector<String> failedmodules = new Vector<> (); // List of failed modules |
| private Vector<String> builtmodules = new Vector<> (); // list of successfully built modules |
| private Vector<String> mergemodules = new Vector<> (); // list of successfully built modules |
| private Vector<String> builttargets = new Vector<> (); // list of successfully built targets |
| private String targetprefix = "all-"; |
| private List<File> topdirs = new ArrayList<> (); |
| private List<Suppress> suppress = new LinkedList<> (); |
| private boolean failonerror = true; // false = enable build success granularity |
| private boolean mergedependentmodules = false; // merge also dependent modules |
| private String dummyName; |
| private Target dummy; |
| private Hashtable<String,Target> targets; |
| private String builtmodulesproperty = ""; // if set, update property of the name |
| // to list of successfuly built modules |
| |
| /** Target directory to unpack to (top of IDE installation). */ |
| public void setDest (File f) { |
| dest = f; |
| } |
| |
| /** Enable/disable build failing */ |
| public void setFailOnError (boolean b) { |
| failonerror = b; |
| } |
| |
| /** At the end of task, set system property to the list of successfuly |
| * built modules |
| */ |
| public void setBuiltModulesProperty (String s) { |
| builtmodulesproperty = s; |
| } |
| |
| /** Enable/Disable merging also dependencies */ |
| public void setMergeDependentModules (boolean b) { |
| mergedependentmodules = b; |
| } |
| |
| /** Comma-separated list of fixed modules to include. */ |
| public void setFixedModules (String s) { |
| StringTokenizer tok = new StringTokenizer (s, ", "); |
| fixedmodules = new Vector<> (); |
| while (tok.hasMoreTokens ()) |
| fixedmodules.addElement (tok.nextToken ()); |
| } |
| |
| /** Comma-separated list of modules to include. */ |
| public void setModules (String s) { |
| StringTokenizer tok = new StringTokenizer (s, ", "); |
| modules = new Vector<> (); |
| while (tok.hasMoreTokens ()) |
| modules.addElement (tok.nextToken ()); |
| } |
| |
| /** String which will have a module name appended to it. |
| * This will form a target in the same project which should |
| * create the <samp>netbeans/</samp> subdirectory. |
| */ |
| public void setTargetprefix (String s) { |
| targetprefix = s; |
| } |
| |
| /** Set the top directory. |
| * There should be subdirectories under this for each named module. |
| */ |
| public void setTopdir (File t) { |
| topdirs.add (t); |
| } |
| |
| /** Nested topdir addition. */ |
| public class Topdir { |
| /** Path to an extra topdir. */ |
| public void setPath (File t) { |
| topdirs.add (t); |
| } |
| } |
| /** Add a nested topdir. |
| * If there is more than one topdir total, build products |
| * may be taken from any of them, including from multiple places |
| * for the same module. (Later topdirs may override build |
| * products in earlier topdirs.) |
| */ |
| public Topdir createTopdir () { |
| return new Topdir (); |
| } |
| |
| /** Locale to suppress. */ |
| public class Suppress { |
| // [PENDING] also support branding here |
| String locale; |
| String iftest; |
| String unlesstest; |
| /** Name of the locale, e.g. <samp>ja</samp>. */ |
| public void setLocale (String l) { |
| locale = l; |
| } |
| /** Property which if set will enable the suppression. */ |
| public void setIf (String p) { |
| iftest = p; |
| } |
| /** Property which if set will disable the suppression. */ |
| public void setUnless (String p) { |
| unlesstest = p; |
| } |
| } |
| /** Add a locale to suppress. |
| * Files matching this locale suffix will not be merged in. |
| * E.g. for the locale <samp>ja</samp>, this will exclude |
| * all files and directories ending in <samp>_ja</samp> as well |
| * as files ending in <samp>_ja.</samp> plus some extension. |
| */ |
| public Suppress createSuppress () { |
| Suppress s = new Suppress (); |
| suppress.add (s); |
| return s; |
| } |
| |
| |
| /** Execute targets which cannot fail and though throw BuildException */ |
| private void fixedModulesBuild() throws BuildException { |
| // Somewhat convoluted code because Project.executeTargets does not |
| // eliminate duplicates when analyzing dependencies! Ecch. |
| // build fixed modules first |
| dummy = new Target (); |
| dummyName = "nbmerge-" + getOwningTarget().getName(); |
| targets = getProject().getTargets(); |
| while (targets.contains (dummyName)) |
| dummyName += "-x"; |
| dummy.setName (dummyName); |
| for (String fixedmodule : buildfixedmodules) { |
| dummy.addDependency (targetprefix + fixedmodule); |
| } |
| getProject().addTarget(dummy); |
| |
| getProject().setProperty("fixedmodules-built", "1" ); |
| @SuppressWarnings("unchecked") |
| Vector<Target> fullList = getProject().topoSort(dummyName, targets); |
| // Now remove earlier ones: already done. |
| Vector<Target> doneList = getProject().topoSort(getOwningTarget().getName(), targets); |
| List<Target> todo = new ArrayList<>(fullList.subList(0, fullList.indexOf(dummy))); |
| todo.removeAll(doneList.subList(0, doneList.indexOf(getOwningTarget()))); |
| log("Going to execute targets " + todo); |
| for (Target nexttargit: todo) { |
| String targetname = nexttargit.getName(); |
| if ( builttargets.indexOf(targetname) < 0 ) { |
| // XXX poor replacement for Project.fireTargetStarted etc. |
| System.out.println(""); System.out.println(targetname + ":"); |
| try { |
| nexttargit.execute(); |
| } catch (BuildException ex) { |
| log("Failed to build target: " + targetname, Project.MSG_ERR); |
| throw ex; |
| } |
| builttargets.addElement(targetname); |
| } |
| } |
| |
| builtmodules.addAll(buildfixedmodules); // add already built fixed modules to the list |
| log("fixedmodules=" + buildfixedmodules, Project.MSG_DEBUG); |
| log("builtmodules=" + builtmodules, Project.MSG_VERBOSE); |
| } |
| |
| /** Execute targets which can fail _without_ throwing BuildException */ |
| private void modulesBuild() throws BuildException { |
| if ( ! failonerror ) { |
| // build the rest of modules |
| for (String module : buildmodules) { |
| dummy = new Target (); |
| dummyName = "nbmerge-" + getOwningTarget().getName() + "-" + module; |
| while (targets.contains (dummyName)) |
| dummyName += "-x"; |
| dummy.setName (dummyName); |
| dummy.addDependency (targetprefix + module); |
| getProject().addTarget(dummy); |
| @SuppressWarnings("unchecked") |
| Vector<Target> fullList = getProject().topoSort(dummyName, targets); |
| // Now remove earlier ones: already done. |
| @SuppressWarnings("unchecked") |
| Vector<Target> doneList = getProject().topoSort(getOwningTarget().getName(), targets); |
| List<Target> todo = new ArrayList<>(fullList.subList(0, fullList.indexOf(dummy))); |
| todo.removeAll(doneList.subList(0, doneList.indexOf(getOwningTarget()))); |
| |
| Iterator<Target> targit = todo.iterator(); |
| try { |
| while (targit.hasNext()) { |
| Target nexttargit = targit.next(); |
| String targetname = nexttargit.getName(); |
| if ( builttargets.indexOf(targetname) < 0 ) { |
| System.out.println(); System.out.println(targetname + ":"); |
| nexttargit.execute(); |
| builttargets.addElement(targetname); |
| } |
| |
| } |
| builtmodules.addElement(module); |
| } catch (BuildException BE) { |
| log(BE.toString(), Project.MSG_WARN); |
| BE.printStackTrace(); |
| failedmodules.addElement(module); |
| } |
| } |
| log("builtmodules=" + builtmodules, Project.MSG_VERBOSE); |
| log("failedmodules=" + failedmodules, Project.MSG_VERBOSE); |
| } |
| } |
| |
| public void execute () throws BuildException { |
| if (topdirs.isEmpty ()) { |
| throw new BuildException("You must set at least one topdir attribute", getLocation()); |
| } |
| |
| buildfixedmodules.addAll(fixedmodules); |
| buildmodules.addAll(modules); |
| |
| if (( modules.size() > 0 ) && ( fixedmodules.size() == 0 ) && (! failonerror)) { |
| log("Unable to build without fixedmodules set", Project.MSG_WARN); |
| log("Swapping modules list with fixedmodules list", Project.MSG_WARN); |
| buildfixedmodules.addAll(modules); |
| buildmodules.removeAllElements(); |
| } |
| |
| if (( failonerror ) && ( modules.size() > 0 )) { |
| // failonerror is enabled => build success granularity is disabled |
| // though move all modules to fixedmodules |
| buildfixedmodules.addAll(modules); |
| buildmodules.removeAllElements(); |
| } |
| |
| // build of fixed modules |
| fixedModulesBuild(); |
| |
| // build of the rest of modules |
| modulesBuild(); |
| |
| // final data merging |
| dataMerge(); |
| |
| // display build success status |
| if (builtmodules.size() > 0 ) { |
| log("builtmodules=" + builtmodules); |
| log("builttargets=" + builttargets); |
| if (failedmodules.size() > 0 ) { |
| log("SOME MODULES FAILED TO BUILD, BUT THEIR BuildException WAS CAUGHT.", Project.MSG_WARN); |
| log("failedmodules=" + failedmodules, Project.MSG_WARN); |
| } |
| |
| if ( mergemodules.size() > 0 ) { |
| if ( builtmodulesproperty.length() > 0 ) { |
| Vector<String> setmodules = new Vector<>(); |
| // add all successfuly built modules |
| setmodules.addAll(mergemodules); |
| // remove all fixed modules (don't put fixed modules to modules list) |
| setmodules.removeAll(fixedmodules); |
| // check if the modules list is equal to mergemodules without fixedmodules |
| if (( ! modules.containsAll(setmodules)) || ( ! setmodules.containsAll(modules))) { |
| String bm = setmodules.toString(); |
| bm = bm.substring( 1, bm.length() - 1); |
| if (bm.length() > 0 ) { |
| log("Setting property \"" + builtmodulesproperty + "\" to new value " + bm); //, Project.MSG_VERBOSE); |
| getProject().setUserProperty(builtmodulesproperty, bm); |
| } |
| } |
| } |
| } |
| |
| } else { |
| throw new BuildException("No modules were built", getLocation()); |
| } |
| |
| } |
| |
| /** Do final data merge */ |
| private void dataMerge() throws BuildException { |
| List<String> suppressedlocales = new LinkedList<> (); |
| for (Suppress s: suppress) { |
| if (s.iftest != null && getProject().getProperty(s.iftest) == null) { |
| continue; |
| } else if (s.unlesstest != null && getProject().getProperty(s.unlesstest) != null) { |
| continue; |
| } |
| log ("Suppressing locale: " + s.locale); |
| suppressedlocales.add (s.locale); |
| } |
| |
| UpdateTracking tr = new UpdateTracking( dest.getAbsolutePath() ); |
| log ( dest.getAbsolutePath() ); |
| for(String locale: suppressedlocales) { |
| tr.removeLocalized(locale); |
| } |
| } |
| } |