You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by Roger Vaughn <rv...@seaconinc.com> on 2000/08/03 23:36:57 UTC

New CAB Task, Take 5: Revenge of the Cab Task

Ok, I did it again.  The last version included a Random method available only in 1.2+.  This version corrects it.  I suppose it's time to set up a 1.1 testing environment....

Roger Vaughn wrote:

> I see someone got to the docs before I did.  In any case, I expanded what
> was there to include the matching params.  I'm not going to attempt to add
> docs for the fileset support until Stefan gets the basics in there.  I can
> revisit the docs when that happens.  The diff is attached.
>
> I also removed the 1.2+ dependency from the Cab code.  That was entirely
> unintentional.  The compile guard should be removed from the build.xml
> file now.  I also corrected a bug in the handling of the cabfile param (I
> don't know how that got in there.)  The new file is attached.
>
> Stefan Bodewig wrote:
>
> > >>>>> "RV" == Roger Vaughn <rv...@seaconinc.com> writes:
> >
> >  RV> This now includes support for nested filesets as well as
> >  RV> supporting the traditional matching params.  Only one style or
> >  RV> the other is allowed in a single task.
> >
> > Roger, could you please (1) update the documentation in
> > docs/index.html for it and (2) remove the JDK 1.2 dependency -
> > File.deleteOnExit and File.createTempFile?
> >
> > Step (1) may wait until I get to document fileset myself of course 8^)
> > - but I really see no reason to make that task depend on JDK > 1.1.
> >
> > Stefan
>
>   ------------------------------------------------------------------------
> *** index.html.orig Thu Aug 03 09:41:35 2000 --- index.html Thu Aug 03 15:46:46 2000 *************** *** 3335,3366 **** basedir ! the directory to start archiving files from. Yes verbose ! set to "yes" if you want to see the output from ! the cabarc tool. defaults to "no". No compress set to "no" to store files without compressing. ! defaults to "yes". No options use to set additional command-line options for ! the cabarc tool. should not normally be necessary. No
>
> Examples
>
> !
>
>      !
>
>      None yet available
>
>      !
>
>   ------------------------------------------------------------------------
>
> NetRexxC
>
> Description:
>
> --- 3335,3415 ---- basedir ! the directory from which to start archiving files. Yes verbose ! set to "yes" to see the output from ! the cabarc tool. Defaults to "no". No compress set to "no" to store files without compressing. ! Defaults to "yes". No options use to set additional command-line options for ! the cabarc tool. Should not normally be necessary. ! No ! ! ! includes ! comma separated list of patterns of files that must be ! included. All files are included when omitted. ! No ! ! ! includesfile ! the name of a file. Each line of this file is ! taken to be an include pattern ! No ! ! ! excludes ! comma separated list of patterns of files that must be ! excluded. No files (except default excludes) are excluded when omitted. ! No ! ! ! excludesfile ! the name of a file. Each line of this file is ! taken to be an exclude pattern ! No ! ! ! defaultexcludes ! indicates whether default excludes should be used or not ! ("yes"/"no"). Default excludes are used when omitted. No
>
> Examples
>
> !
>
>   <cab cabfile="${dist}/manual.cab"
> !        basedir="htdocs/manual"
> !   />
>
> !
>
> cabs all files in the htdocs/manual directory in a file called manual.cab ! in the ${dist} directory.
>
> !
>
>   <cab cabfile="${dist}/manual.cab"
> !        basedir="htdocs/manual"
> !        excludes="mydocs/**, **/todo.html"
> !   />
>
> !
>
> cabs all files in the htdocs/manual directory in a file called manual.cab ! in the ${dist} directory. Files in the directory mydocs, ! or files with the name todo.html are excluded.
>
> !
>
>   <cab cabfile="${dist}/manual.cab"
> !        basedir="htdocs/manual"
> !        includes="api/**/*.html"
> !        excludes="**/todo.html"
> !        verbose="yes"
> !   />
>
> !
>
> cab all files in the htdocs/manual directory in a file called manual.cab ! in the ${dist} directory. Only html files under the directory api ! are archived, and files with the name todo.html are excluded. Output from ! the cabarc tool is displayed in the build output.
>
>   ------------------------------------------------------------------------
>
> NetRexxC
>
> Description:
>
>   ------------------------------------------------------------------------
> /*
>  * The Apache Software License, Version 1.1
>  *
>  * Copyright (c) 1999 The Apache Software Foundation.  All rights
>  * reserved.
>  *
>  * Redistribution and use in source and binary forms, with or without
>  * modification, are permitted provided that the following conditions
>  * are met:
>  *
>  * 1. Redistributions of source code must retain the above copyright
>  *    notice, this list of conditions and the following disclaimer.
>  *
>  * 2. Redistributions in binary form must reproduce the above copyright
>  *    notice, this list of conditions and the following disclaimer in
>  *    the documentation and/or other materials provided with the
>  *    distribution.
>  *
>  * 3. The end-user documentation included with the redistribution, if
>  *    any, must include the following acknowlegement:
>  *       "This product includes software developed by the
>  *        Apache Software Foundation (http://www.apache.org/)."
>  *    Alternately, this acknowlegement may appear in the software itself,
>  *    if and wherever such third-party acknowlegements normally appear.
>  *
>  * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
>  *    Foundation" must not be used to endorse or promote products derived
>  *    from this software without prior written permission. For written
>  *    permission, please contact apache@apache.org.
>  *
>  * 5. Products derived from this software may not be called "Apache"
>  *    nor may "Apache" appear in their names without prior written
>  *    permission of the Apache Group.
>  *
>  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>  * SUCH DAMAGE.
>  * ====================================================================
>  *
>  * This software consists of voluntary contributions made by many
>  * individuals on behalf of the Apache Software Foundation.  For more
>  * information on the Apache Software Foundation, please see
>  * <http://www.apache.org/>.
>  */
>
> package org.apache.tools.ant.taskdefs.optional;
>
> import org.apache.tools.ant.*;
> import org.apache.tools.ant.taskdefs.*;
> import org.apache.tools.ant.types.*;
>
> import java.io.*;
> import java.util.Enumeration;
> import java.util.StringTokenizer;
> import java.util.Vector;
> import java.util.Random;
> import java.text.DecimalFormat;
>
> /**
>  * Create a CAB archive.
>  *
>  * @author Roger Vaughn <a href="mailto:rvaughn@seaconinc.com">rvaughn@seaconinc.com</a>
>  */
>
> public class Cab extends MatchingTask {
>
>     private File cabFile;
>     private File baseDir;
>     private Vector filesets = new Vector();
>     private boolean doCompress = true;
>     private boolean doVerbose = false;
>     private String cmdOptions;
>
>     protected String archiveType = "cab";
>
>     private static String myos;
>     private static boolean isWindows;
>
>     static {
>         myos = System.getProperty("os.name");
>         isWindows = myos.toLowerCase().indexOf("windows") >= 0;
>     }
>
>     /**
>      * This is the name/location of where to
>      * create the .cab file.
>      */
>     public void setCabfile(File cabFile) {
>         this.cabFile = cabFile;
>     }
>
>     /**
>      * This is the base directory to look in for
>      * things to cab.
>      */
>     public void setBasedir(File baseDir) {
>         this.baseDir = baseDir;
>     }
>
>     /**
>      * Sets whether we want to compress the files or only store them.
>      */
>     public void setCompress(boolean compress) {
>         doCompress = compress;
>     }
>
>     /**
>      * Sets whether we want to see or suppress cabarc output.
>      */
>     public void setVerbose(boolean verbose) {
>         doVerbose = verbose;
>     }
>
>     /**
>      * Sets additional cabarc options that aren't supported directly.
>      */
>     public void setOptions(String options) {
>         cmdOptions = options;
>     }
>
>     /**
>      * Adds a set of files (nested fileset attribute).
>      */
>     public void addFileset(FileSet set) {
>         filesets.addElement(set);
>     }
>
>     /**
>      * Adds a reference to a set of files (nested filesetref element).
>      */
>     public void addFilesetref(Reference ref) {
>         filesets.addElement(ref);
>     }
>
>     /*
>      * I'm not fond of this pattern: "sub-method expected to throw
>      * task-cancelling exceptions".  It feels too much like programming
>      * for side-effects to me...
>      */
>     protected void checkConfiguration() throws BuildException {
>         if (baseDir == null) {
>             throw new BuildException("basedir attribute must be set!");
>         }
>         if (!baseDir.exists()) {
>             throw new BuildException("basedir does not exist!");
>         }
>         if (cabFile == null) {
>             throw new BuildException("cabfile attribute must be set!");
>         }
>     }
>
>     /**
>      * Create a new exec delegate.  The delegate task is populated so that
>      * it appears in the logs to be the same task as this one.
>      */
>     protected ExecTask createExec() throws BuildException
>     {
>         ExecTask exec = (ExecTask)project.createTask("exec");
>         exec.setOwningTarget(this.getOwningTarget());
>         exec.setTaskName(this.getTaskName());
>         exec.setDescription(this.getDescription());
>
>         return exec;
>     }
>
>     /**
>      * Check to see if the target is up to date with respect to input files.
>      * @return true if the cab file is newer than its dependents.
>      */
>     protected boolean isUpToDate(Vector files)
>     {
>         boolean upToDate = true;
>         for (int i=0; i<files.size() && upToDate; i++)
>         {
>             String file = files.elementAt(i).toString();
>             if (new File(baseDir,file).lastModified() >
>                 cabFile.lastModified())
>                 upToDate = false;
>         }
>         return upToDate;
>     }
>
>     /**
>      * Create the cabarc command line to use.
>      */
>     protected Commandline createCommand(File listFile)
>     {
>         Commandline command = new Commandline();
>         command.setExecutable("cabarc");
>         command.createArgument().setValue("-r");
>         command.createArgument().setValue("-p");
>
>         if (!doCompress)
>         {
>             command.createArgument().setValue("-m");
>             command.createArgument().setValue("none");
>         }
>
>         if (cmdOptions != null)
>         {
>             command.createArgument().setValue(cmdOptions);
>         }
>
>         command.createArgument().setValue("n");
>         command.createArgument().setFile(cabFile);
>         command.createArgument().setValue("@" + listFile.getAbsolutePath());
>
>         return command;
>     }
>
>     private static int counter = new Random().nextInt(100000);
>     protected File createTempFile(String prefix, String suffix)
>     {
>         if (suffix == null)
>         {
>             suffix = ".tmp";
>         }
>
>         String name = prefix +
>             new DecimalFormat("#####").format(new Integer(counter++)) +
>             suffix;
>
>         String tmpdir = System.getProperty("java.io.tmpdir");
>
>         // java.io.tmpdir is not present in 1.1
>         if (tmpdir == null)
>             return new File(name);
>         else
>             return new File(tmpdir, name);
>     }
>
>     /**
>      * Creates a list file.  This temporary file contains a list of all files
>      * to be included in the cab, one file per line.
>      */
>     protected File createListFile(Vector files)
>         throws IOException
>     {
>         File listFile = createTempFile("ant", null);
>
>         PrintWriter writer = new PrintWriter(new FileOutputStream(listFile));
>
>         for (int i = 0; i < files.size(); i++)
>         {
>             writer.println(files.elementAt(i).toString());
>         }
>         writer.close();
>
>         return listFile;
>     }
>
>     /**
>      * Append all files found by a directory scanner to a vector.
>      */
>     protected void appendFiles(Vector files, DirectoryScanner ds)
>     {
>         String[] dsfiles = ds.getIncludedFiles();
>
>         for (int i = 0; i < dsfiles.length; i++)
>         {
>             files.addElement(dsfiles[i]);
>         }
>     }
>
>     /**
>      * Get the complete list of files to be included in the cab.  Filenames
>      * are gathered from filesets if any have been added, otherwise from the
>      * traditional include parameters.
>      */
>     protected Vector getFileList() throws BuildException
>     {
>         Vector files = new Vector();
>
>         if (filesets.size() == 0)
>         {
>             // get files from old methods - includes and nested include
>             appendFiles(files, super.getDirectoryScanner(baseDir));
>         }
>         else
>         {
>             // get files from filesets
>             for (int i = 0; i < filesets.size(); i++)
>             {
>                 Object o = filesets.elementAt(i);
>                 FileSet fs;
>                 if (o instanceof FileSet)
>                 {
>                     fs = (FileSet)o;
>                 }
>                 else if (o instanceof Reference)
>                 {
>                     Reference r = (Reference)o;
>                     o = r.getReferencedObject(project);
>
>                     if (o instanceof FileSet)
>                     {
>                         fs = (FileSet)o;
>                     }
>                     else
>                     {
>                         throw new BuildException(
>                             r.getRefId() + " does not denote a fileset",
>                             location);
>                     }
>                 }
>                 else
>                 {
>                     throw new BuildException(
>                         "nested element is not a FileSet or Reference",
>                         location);
>                 }
>
>                 if (fs != null)
>                 {
>                     appendFiles(files, fs.getDirectoryScanner(project));
>                 }
>             }
>         }
>
>         return files;
>     }
>
>     public void execute() throws BuildException {
>         // we must be on Windows to continue
>         if (!isWindows)
>         {
>             log("cannot run on non-Windows platforms: " + myos,
>                 Project.MSG_VERBOSE);
>             return;
>         }
>
>         checkConfiguration();
>
>         Vector files = getFileList();
>
>         // quick exit if the target is up to date
>         if (isUpToDate(files)) return;
>
>         log("Building "+ archiveType +": "+ cabFile.getAbsolutePath());
>
>         try {
>             File listFile = createListFile(files);
>             ExecTask exec = createExec();
>             File outFile = null;
>
>             // die if cabarc fails
>             exec.setFailonerror(true);
>             exec.setDir(baseDir);
>
>             if (!doVerbose)
>             {
>                 outFile = createTempFile("ant", null);
>                 exec.setOutput(outFile);
>             }
>
>             exec.setCommand(createCommand(listFile));
>             exec.execute();
>
>             if (outFile != null)
>             {
>                 outFile.delete();
>             }
>
>             listFile.delete();
>         } catch (IOException ioe) {
>             String msg = "Problem creating " + cabFile + " " + ioe.getMessage();
>             throw new BuildException(msg);
>         }
>     }
> }

Re: New CAB Task, Take 5: Revenge of the Cab Task

Posted by Roger Vaughn <rv...@seaconinc.com>.
Yes, cabarc can also list and extract from cabs.  If it's really
necessary, I can create an uncab task, but honestly I've never run into a
case where one is needed.

Stefan Bodewig wrote:

> Is there something like a corresponding Uncab in the Microsoft world?
>
> That's my curiosity asking, not necessarily a request for a task 8^).
>
> Stefan


Re: New CAB Task, Take 5: Revenge of the Cab Task

Posted by Stefan Bodewig <bo...@bost.de>.
Is there something like a corresponding Uncab in the Microsoft world?

That's my curiosity asking, not necessarily a request for a task 8^).

Stefan