001/*
002 * Copyright 2007-2021 The jdeb developers.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.vafer.jdeb.ant;
018
019import java.io.File;
020import java.util.ArrayList;
021import java.util.Arrays;
022import java.util.Collection;
023
024import org.apache.tools.ant.BuildException;
025import org.apache.tools.ant.Project;
026import org.apache.tools.ant.taskdefs.MatchingTask;
027import org.apache.tools.ant.taskdefs.Tar;
028import org.apache.tools.ant.types.FileSet;
029import org.vafer.jdeb.Console;
030import org.vafer.jdeb.DataProducer;
031import org.vafer.jdeb.DebMaker;
032import org.vafer.jdeb.PackagingException;
033import org.vafer.jdeb.producers.DataProducerFileSet;
034import org.vafer.jdeb.utils.OutputTimestampResolver;
035
036/**
037 * AntTask for creating debian archives.
038 */
039public class DebAntTask extends MatchingTask {
040
041    /** The Debian package produced */
042    private File deb;
043
044    /** The directory containing the control files to build the package */
045    private File control;
046
047    /** The file containing the PGP keys */
048    private File keyring;
049
050    /** The key to use in the keyring */
051    private String key;
052
053    /** The passphrase for the key to sign the changes file */
054    private String passphrase;
055
056    /** The file to read the changes from */
057    private File changesIn;
058
059    /** The file where to write the changes to */
060    private File changesOut;
061
062    /** The file where to write the changes of the changes input to */
063    private File changesSave;
064
065    /** The compression method used for the data file (none, gzip, bzip2 or xz) */
066    private String compression = "gzip";
067
068    /**
069     * The digest algorithm to use.
070     *
071     * @see org.bouncycastle.bcpg.HashAlgorithmTags
072     */
073    private String digest = "SHA256";
074
075    /** Trigger the verbose mode detailing all operations */
076    private boolean verbose;
077
078    private Collection<Link> links = new ArrayList<>();
079
080    private Collection<DataProducer> dataProducers = new ArrayList<>();
081    private Collection<DataProducer> conffilesProducers = new ArrayList<>();
082
083
084    public void setDestfile( File deb ) {
085        this.deb = deb;
086    }
087
088    public void setControl( File control ) {
089        this.control = control;
090    }
091
092    public void setChangesIn( File changes ) {
093        this.changesIn = changes;
094    }
095
096    public void setChangesOut( File changes ) {
097        this.changesOut = changes;
098    }
099
100    public void setChangesSave( File changes ) {
101        this.changesSave = changes;
102    }
103
104    public void setKeyring( File keyring ) {
105        this.keyring = keyring;
106    }
107
108    public void setKey( String key ) {
109        this.key = key;
110    }
111
112    public void setPassphrase( String passphrase ) {
113        this.passphrase = passphrase;
114    }
115
116    public void setCompression( String compression ) {
117        this.compression = compression;
118    }
119
120    public void setVerbose( boolean verbose ) {
121        this.verbose = verbose;
122    }
123
124    public void addFileSet( FileSet fileset ) {
125        dataProducers.add(new DataProducerFileSet(fileset));
126    }
127
128    public void addTarFileSet( Tar.TarFileSet fileset ) {
129        dataProducers.add(new DataProducerFileSet(fileset));
130    }
131
132    public void addData( Data data ) {
133        dataProducers.add(data);
134    }
135
136    public void addLink( Link link ) {
137        links.add(link);
138    }
139
140    public void setDigest(String digest) {
141        this.digest = digest;
142    }
143
144    public void execute() {
145        // add the data producers for the links
146        for (Link link : links) {
147            dataProducers.add(link.toDataProducer());
148        }
149
150        // validate the type of the <data> elements
151        for (DataProducer dataProducer : dataProducers) {
152            if (dataProducer instanceof Data) {
153                Data data = (Data) dataProducer;
154                if (data.getType() == null) {
155                    throw new BuildException("The type of the data element wasn't specified (expected 'file', 'directory' or 'archive')");
156                } else if (!Arrays.asList("file", "directory", "archive").contains(data.getType().toLowerCase())) {
157                    throw new BuildException("The type '" + data.getType() + "' of the data element is unknown (expected 'file', 'directory' or 'archive')");
158                }
159                if (data.getConffile() != null && data.getConffile()) {
160                    conffilesProducers.add(dataProducer);
161                }
162            }
163        }
164
165        Console console = new TaskConsole(this, verbose);
166
167        DebMaker debMaker = new DebMaker(console, dataProducers, conffilesProducers);
168        debMaker.setDeb(deb);
169        debMaker.setControl(control);
170        debMaker.setChangesIn(changesIn);
171        debMaker.setChangesOut(changesOut);
172        debMaker.setChangesSave(changesSave);
173        debMaker.setKeyring(keyring);
174        debMaker.setKey(key);
175        debMaker.setPassphrase(passphrase);
176        debMaker.setCompression(compression);
177        debMaker.setDigest(digest);
178        Long outputTimestampMs = new OutputTimestampResolver(console).resolveOutputTimestamp(null);
179        debMaker.setOutputTimestampMs(outputTimestampMs);
180
181        try {
182            debMaker.validate();
183            debMaker.makeDeb();
184
185        } catch (PackagingException e) {
186            log("Failed to create the Debian package " + deb, e, Project.MSG_ERR);
187            throw new BuildException("Failed to create the Debian package " + deb, e);
188        }
189    }
190}