You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

AbstractCvsTask.java 25 kB

12 years ago
12 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
8 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package org.apache.tools.ant.taskdefs;
  19. import java.io.BufferedOutputStream;
  20. import java.io.File;
  21. import java.io.IOException;
  22. import java.io.OutputStream;
  23. import java.io.PrintStream;
  24. import java.nio.file.Paths;
  25. import java.util.ArrayList;
  26. import java.util.List;
  27. import java.util.Vector;
  28. import org.apache.tools.ant.BuildException;
  29. import org.apache.tools.ant.Project;
  30. import org.apache.tools.ant.Task;
  31. import org.apache.tools.ant.types.Commandline;
  32. import org.apache.tools.ant.types.Environment;
  33. import org.apache.tools.ant.util.FileUtils;
  34. import org.apache.tools.ant.util.StringUtils;
  35. /**
  36. * original Cvs.java 1.20
  37. * <p>
  38. * NOTE: This implementation has been moved here from Cvs.java with
  39. * the addition of some accessors for extensibility. Another task
  40. * can extend this with some customized output processing.
  41. * </p>
  42. *
  43. * @since Ant 1.5
  44. */
  45. public abstract class AbstractCvsTask extends Task {
  46. /**
  47. * Default compression level to use, if compression is enabled via
  48. * setCompression(true).
  49. */
  50. public static final int DEFAULT_COMPRESSION_LEVEL = 3;
  51. private static final int MAXIMUM_COMRESSION_LEVEL = 9;
  52. private Commandline cmd = new Commandline();
  53. private List<Module> modules = new ArrayList<>();
  54. /** list of Commandline children */
  55. private List<Commandline> commandlines = new Vector<>();
  56. /**
  57. * the CVSROOT variable.
  58. */
  59. private String cvsRoot;
  60. /**
  61. * the CVS_RSH variable.
  62. */
  63. private String cvsRsh;
  64. /**
  65. * the package/module to check out.
  66. */
  67. private String cvsPackage;
  68. /**
  69. * the tag
  70. */
  71. private String tag;
  72. /**
  73. * the default command.
  74. */
  75. private static final String DEFAULT_COMMAND = "checkout";
  76. /**
  77. * the CVS command to execute.
  78. */
  79. private String command = null;
  80. /**
  81. * suppress information messages.
  82. */
  83. private boolean quiet = false;
  84. /**
  85. * suppress all messages.
  86. */
  87. private boolean reallyquiet = false;
  88. /**
  89. * compression level to use.
  90. */
  91. private int compression = 0;
  92. /**
  93. * report only, don't change any files.
  94. */
  95. private boolean noexec = false;
  96. /**
  97. * CVS port
  98. */
  99. private int port = 0;
  100. /**
  101. * CVS password file
  102. */
  103. private File passFile = null;
  104. /**
  105. * the directory where the checked out files should be placed.
  106. */
  107. private File dest;
  108. /**
  109. * whether or not to append stdout/stderr to existing files
  110. */
  111. private boolean append = false;
  112. /**
  113. * the file to direct standard output from the command.
  114. */
  115. private File output;
  116. /**
  117. * the file to direct standard error from the command.
  118. */
  119. private File error;
  120. /**
  121. * If true it will stop the build if cvs exits with error.
  122. * Default is false. (Iulian)
  123. */
  124. private boolean failOnError = false;
  125. /**
  126. * Create accessors for the following, to allow different handling of
  127. * the output.
  128. */
  129. private ExecuteStreamHandler executeStreamHandler;
  130. private OutputStream outputStream;
  131. private OutputStream errorStream;
  132. /**
  133. * sets the handler
  134. * @param handler a handler able of processing the output and error streams from the cvs exe
  135. */
  136. public void setExecuteStreamHandler(ExecuteStreamHandler handler) {
  137. this.executeStreamHandler = handler;
  138. }
  139. /**
  140. * find the handler and instantiate it if it does not exist yet
  141. * @return handler for output and error streams
  142. */
  143. protected ExecuteStreamHandler getExecuteStreamHandler() {
  144. if (this.executeStreamHandler == null) {
  145. setExecuteStreamHandler(new PumpStreamHandler(getOutputStream(),
  146. getErrorStream()));
  147. }
  148. return this.executeStreamHandler;
  149. }
  150. /**
  151. * sets a stream to which the output from the cvs executable should be sent
  152. * @param outputStream stream to which the stdout from cvs should go
  153. */
  154. protected void setOutputStream(OutputStream outputStream) {
  155. this.outputStream = outputStream;
  156. }
  157. /**
  158. * access the stream to which the stdout from cvs should go
  159. * if this stream has already been set, it will be returned
  160. * if the stream has not yet been set, if the attribute output
  161. * has been set, the output stream will go to the output file
  162. * otherwise the output will go to ant's logging system
  163. * @return output stream to which cvs' stdout should go to
  164. */
  165. protected OutputStream getOutputStream() {
  166. if (this.outputStream == null) {
  167. if (output != null) {
  168. try {
  169. setOutputStream(new PrintStream(
  170. new BufferedOutputStream(
  171. FileUtils.newOutputStream(Paths.get(output.getPath()),
  172. append))));
  173. } catch (IOException e) {
  174. throw new BuildException(e, getLocation());
  175. }
  176. } else {
  177. setOutputStream(new LogOutputStream(this, Project.MSG_INFO));
  178. }
  179. }
  180. return this.outputStream;
  181. }
  182. /**
  183. * sets a stream to which the stderr from the cvs exe should go
  184. * @param errorStream an output stream willing to process stderr
  185. */
  186. protected void setErrorStream(OutputStream errorStream) {
  187. this.errorStream = errorStream;
  188. }
  189. /**
  190. * access the stream to which the stderr from cvs should go
  191. * if this stream has already been set, it will be returned
  192. * if the stream has not yet been set, if the attribute error
  193. * has been set, the output stream will go to the file denoted by the error attribute
  194. * otherwise the stderr output will go to ant's logging system
  195. * @return output stream to which cvs' stderr should go to
  196. */
  197. protected OutputStream getErrorStream() {
  198. if (this.errorStream == null) {
  199. if (error != null) {
  200. try {
  201. setErrorStream(new PrintStream(
  202. new BufferedOutputStream(
  203. FileUtils.newOutputStream(Paths.get(error.getPath()),
  204. append))));
  205. } catch (IOException e) {
  206. throw new BuildException(e, getLocation());
  207. }
  208. } else {
  209. setErrorStream(new LogOutputStream(this, Project.MSG_WARN));
  210. }
  211. }
  212. return this.errorStream;
  213. }
  214. /**
  215. * Sets up the environment for toExecute and then runs it.
  216. * @param toExecute the command line to execute
  217. * @throws BuildException if failonError is set to true and the cvs command fails
  218. */
  219. protected void runCommand(Commandline toExecute) throws BuildException {
  220. // TODO: we should use JCVS (www.ice.com/JCVS) instead of
  221. // command line execution so that we don't rely on having
  222. // native CVS stuff around (SM)
  223. // We can't do it ourselves as jCVS is GPLed, a third party task
  224. // outside of Apache repositories would be possible though (SB).
  225. Environment env = new Environment();
  226. if (port > 0) {
  227. Environment.Variable var = new Environment.Variable();
  228. var.setKey("CVS_CLIENT_PORT");
  229. var.setValue(String.valueOf(port));
  230. env.addVariable(var);
  231. // non-standard environment variable used by CVSNT, WinCVS
  232. // and others
  233. var = new Environment.Variable();
  234. var.setKey("CVS_PSERVER_PORT");
  235. var.setValue(String.valueOf(port));
  236. env.addVariable(var);
  237. }
  238. /**
  239. * Need a better cross platform integration with <cvspass>, so
  240. * use the same filename.
  241. */
  242. if (passFile == null) {
  243. File defaultPassFile = new File(
  244. System.getProperty("cygwin.user.home",
  245. System.getProperty("user.home"))
  246. + File.separatorChar + ".cvspass");
  247. if (defaultPassFile.exists()) {
  248. this.setPassfile(defaultPassFile);
  249. }
  250. }
  251. if (passFile != null) {
  252. if (passFile.isFile() && passFile.canRead()) {
  253. Environment.Variable var = new Environment.Variable();
  254. var.setKey("CVS_PASSFILE");
  255. var.setValue(String.valueOf(passFile));
  256. env.addVariable(var);
  257. log("Using cvs passfile: " + String.valueOf(passFile),
  258. Project.MSG_VERBOSE);
  259. } else if (!passFile.canRead()) {
  260. log("cvs passfile: " + String.valueOf(passFile)
  261. + " ignored as it is not readable",
  262. Project.MSG_WARN);
  263. } else {
  264. log("cvs passfile: " + String.valueOf(passFile)
  265. + " ignored as it is not a file",
  266. Project.MSG_WARN);
  267. }
  268. }
  269. if (cvsRsh != null) {
  270. Environment.Variable var = new Environment.Variable();
  271. var.setKey("CVS_RSH");
  272. var.setValue(String.valueOf(cvsRsh));
  273. env.addVariable(var);
  274. }
  275. //
  276. // Just call the getExecuteStreamHandler() and let it handle
  277. // the semantics of instantiation or retrieval.
  278. //
  279. Execute exe = new Execute(getExecuteStreamHandler(), null);
  280. exe.setAntRun(getProject());
  281. if (dest == null) {
  282. dest = getProject().getBaseDir();
  283. }
  284. if (!dest.exists()) {
  285. dest.mkdirs();
  286. }
  287. exe.setWorkingDirectory(dest);
  288. exe.setCommandline(toExecute.getCommandline());
  289. exe.setEnvironment(env.getVariables());
  290. try {
  291. String actualCommandLine = executeToString(exe);
  292. log(actualCommandLine, Project.MSG_VERBOSE);
  293. int retCode = exe.execute();
  294. log("retCode=" + retCode, Project.MSG_DEBUG);
  295. if (failOnError && Execute.isFailure(retCode)) {
  296. throw new BuildException("cvs exited with error code "
  297. + retCode
  298. + StringUtils.LINE_SEP
  299. + "Command line was ["
  300. + actualCommandLine + "]",
  301. getLocation());
  302. }
  303. } catch (IOException e) {
  304. if (failOnError) {
  305. throw new BuildException(e, getLocation());
  306. }
  307. log("Caught exception: " + e.getMessage(), Project.MSG_WARN);
  308. } catch (BuildException e) {
  309. if (failOnError) {
  310. throw(e);
  311. }
  312. Throwable t = e.getCause();
  313. if (t == null) {
  314. t = e;
  315. }
  316. log("Caught exception: " + t.getMessage(), Project.MSG_WARN);
  317. } catch (Exception e) {
  318. if (failOnError) {
  319. throw new BuildException(e, getLocation());
  320. }
  321. log("Caught exception: " + e.getMessage(), Project.MSG_WARN);
  322. }
  323. }
  324. /**
  325. * do the work
  326. * @throws BuildException if failonerror is set to true and the
  327. * cvs command fails.
  328. */
  329. @Override
  330. public void execute() throws BuildException {
  331. String savedCommand = getCommand();
  332. if (this.getCommand() == null && commandlines.isEmpty()) {
  333. // re-implement legacy behaviour:
  334. this.setCommand(AbstractCvsTask.DEFAULT_COMMAND);
  335. }
  336. String c = this.getCommand();
  337. Commandline cloned = null;
  338. if (c != null) {
  339. cloned = (Commandline) cmd.clone();
  340. cloned.createArgument(true).setLine(c);
  341. this.addConfiguredCommandline(cloned, true);
  342. }
  343. try {
  344. commandlines.forEach(this::runCommand);
  345. } finally {
  346. if (cloned != null) {
  347. removeCommandline(cloned);
  348. }
  349. setCommand(savedCommand);
  350. FileUtils.close(outputStream);
  351. FileUtils.close(errorStream);
  352. }
  353. }
  354. private String executeToString(Execute execute) {
  355. String cmdLine = Commandline.describeCommand(execute
  356. .getCommandline());
  357. StringBuilder buf = removeCvsPassword(cmdLine);
  358. String newLine = StringUtils.LINE_SEP;
  359. String[] variableArray = execute.getEnvironment();
  360. if (variableArray != null) {
  361. buf.append(newLine);
  362. buf.append(newLine);
  363. buf.append("environment:");
  364. buf.append(newLine);
  365. for (String variable : variableArray) {
  366. buf.append(newLine);
  367. buf.append("\t");
  368. buf.append(variable);
  369. }
  370. }
  371. return buf.toString();
  372. }
  373. /**
  374. * Removes the cvs password from the command line, if given on the command
  375. * line. This password can be given on the command line in the cvsRoot
  376. * -d:pserver:user:password@server:path
  377. * It has to be noted that the password may be omitted altogether.
  378. * @param cmdLine the CVS command line
  379. * @return a StringBuffer where the password has been removed (if available)
  380. */
  381. private StringBuilder removeCvsPassword(String cmdLine) {
  382. StringBuilder buf = new StringBuilder(cmdLine);
  383. int start = cmdLine.indexOf("-d:");
  384. if (start >= 0) {
  385. int stop = cmdLine.indexOf('@', start);
  386. int startproto = cmdLine.indexOf(':', start);
  387. int startuser = cmdLine.indexOf(':', startproto + 1);
  388. int startpass = cmdLine.indexOf(':', startuser + 1);
  389. if (stop >= 0 && startpass > startproto && startpass < stop) {
  390. for (int i = startpass + 1; i < stop; i++) {
  391. buf.replace(i, i + 1, "*");
  392. }
  393. }
  394. }
  395. return buf;
  396. }
  397. /**
  398. * The CVSROOT variable.
  399. *
  400. * @param root
  401. * the CVSROOT variable
  402. */
  403. public void setCvsRoot(String root) {
  404. // Check if not real cvsroot => set it to null
  405. if (root != null && root.trim().isEmpty()) {
  406. root = null;
  407. }
  408. this.cvsRoot = root;
  409. }
  410. /**
  411. * access the CVSROOT variable
  412. * @return CVSROOT
  413. */
  414. public String getCvsRoot() {
  415. return this.cvsRoot;
  416. }
  417. /**
  418. * The CVS_RSH variable.
  419. *
  420. * @param rsh the CVS_RSH variable
  421. */
  422. public void setCvsRsh(String rsh) {
  423. if (rsh != null && rsh.trim().isEmpty()) {
  424. rsh = null;
  425. }
  426. this.cvsRsh = rsh;
  427. }
  428. /**
  429. * access the CVS_RSH variable
  430. * @return the CVS_RSH variable
  431. */
  432. public String getCvsRsh() {
  433. return this.cvsRsh;
  434. }
  435. /**
  436. * Port used by CVS to communicate with the server.
  437. *
  438. * @param port port of CVS
  439. */
  440. public void setPort(int port) {
  441. this.port = port;
  442. }
  443. /**
  444. * access the port of CVS
  445. * @return the port of CVS
  446. */
  447. public int getPort() {
  448. return this.port;
  449. }
  450. /**
  451. * Password file to read passwords from.
  452. *
  453. * @param passFile password file to read passwords from
  454. */
  455. public void setPassfile(File passFile) {
  456. this.passFile = passFile;
  457. }
  458. /**
  459. * find the password file
  460. * @return password file
  461. */
  462. public File getPassFile() {
  463. return this.passFile;
  464. }
  465. /**
  466. * The directory where the checked out files should be placed.
  467. *
  468. * <p>Note that this is different from CVS's -d command line
  469. * switch as Ant will never shorten pathnames to avoid empty
  470. * directories.</p>
  471. *
  472. * @param dest directory where the checked out files should be placed
  473. */
  474. public void setDest(File dest) {
  475. this.dest = dest;
  476. }
  477. /**
  478. * get the file where the checked out files should be placed
  479. *
  480. * @return directory where the checked out files should be placed
  481. */
  482. public File getDest() {
  483. return this.dest;
  484. }
  485. /**
  486. * The package/module to operate upon.
  487. *
  488. * @param p package or module to operate upon
  489. */
  490. public void setPackage(String p) {
  491. this.cvsPackage = p;
  492. }
  493. /**
  494. * access the package or module to operate upon
  495. *
  496. * @return package/module
  497. */
  498. public String getPackage() {
  499. return this.cvsPackage;
  500. }
  501. /**
  502. * tag or branch
  503. * @return tag or branch
  504. * @since ant 1.6.1
  505. */
  506. public String getTag() {
  507. return tag;
  508. }
  509. /**
  510. * The tag of the package/module to operate upon.
  511. * @param p tag
  512. */
  513. public void setTag(String p) {
  514. // Check if not real tag => set it to null
  515. if (p != null && !p.trim().isEmpty()) {
  516. tag = p;
  517. addCommandArgument("-r" + p);
  518. }
  519. }
  520. /**
  521. * This needs to be public to allow configuration
  522. * of commands externally.
  523. * @param arg command argument
  524. */
  525. public void addCommandArgument(String arg) {
  526. this.addCommandArgument(cmd, arg);
  527. }
  528. /**
  529. * This method adds a command line argument to an external command.
  530. *
  531. * I do not understand what this method does in this class ???
  532. * particularly not why it is public ????
  533. * AntoineLL July 23d 2003
  534. *
  535. * @param c command line to which one argument should be added
  536. * @param arg argument to add
  537. */
  538. public void addCommandArgument(Commandline c, String arg) {
  539. c.createArgument().setValue(arg);
  540. }
  541. /**
  542. * Use the most recent revision no later than the given date.
  543. * @param p a date as string in a format that the CVS executable
  544. * can understand see man cvs
  545. */
  546. public void setDate(String p) {
  547. if (p != null && !p.trim().isEmpty()) {
  548. addCommandArgument("-D");
  549. addCommandArgument(p);
  550. }
  551. }
  552. /**
  553. * The CVS command to execute.
  554. *
  555. * This should be deprecated, it is better to use the Commandline class ?
  556. * AntoineLL July 23d 2003
  557. *
  558. * @param c a command as string
  559. */
  560. public void setCommand(String c) {
  561. this.command = c;
  562. }
  563. /**
  564. * accessor to a command line as string
  565. *
  566. * This should be deprecated
  567. * AntoineLL July 23d 2003
  568. *
  569. * @return command line as string
  570. */
  571. public String getCommand() {
  572. return this.command;
  573. }
  574. /**
  575. * If true, suppress informational messages.
  576. * @param q if true, suppress informational messages
  577. */
  578. public void setQuiet(boolean q) {
  579. quiet = q;
  580. }
  581. /**
  582. * If true, suppress all messages.
  583. * @param q if true, suppress all messages
  584. * @since Ant 1.6
  585. */
  586. public void setReallyquiet(boolean q) {
  587. reallyquiet = q;
  588. }
  589. /**
  590. * If true, report only and don't change any files.
  591. *
  592. * @param ne if true, report only and do not change any files.
  593. */
  594. public void setNoexec(boolean ne) {
  595. noexec = ne;
  596. }
  597. /**
  598. * The file to direct standard output from the command.
  599. * @param output a file to which stdout should go
  600. */
  601. public void setOutput(File output) {
  602. this.output = output;
  603. }
  604. /**
  605. * The file to direct standard error from the command.
  606. *
  607. * @param error a file to which stderr should go
  608. */
  609. public void setError(File error) {
  610. this.error = error;
  611. }
  612. /**
  613. * Whether to append output/error when redirecting to a file.
  614. * @param value true indicated you want to append
  615. */
  616. public void setAppend(boolean value) {
  617. this.append = value;
  618. }
  619. /**
  620. * Stop the build process if the command exits with
  621. * a return code other than 0.
  622. * Defaults to false.
  623. * @param failOnError stop the build process if the command exits with
  624. * a return code other than 0
  625. */
  626. public void setFailOnError(boolean failOnError) {
  627. this.failOnError = failOnError;
  628. }
  629. /**
  630. * Configure a commandline element for things like cvsRoot, quiet, etc.
  631. * @param c the command line which will be configured
  632. * if the commandline is initially null, the function is a noop
  633. * otherwise the function append to the commandline arguments concerning
  634. * <ul>
  635. * <li>
  636. * cvs package
  637. * </li>
  638. * <li>
  639. * compression
  640. * </li>
  641. * <li>
  642. * quiet or reallyquiet
  643. * </li>
  644. * <li>cvsroot</li>
  645. * <li>noexec</li>
  646. * </ul>
  647. */
  648. protected void configureCommandline(Commandline c) {
  649. if (c == null) {
  650. return;
  651. }
  652. c.setExecutable("cvs");
  653. if (cvsPackage != null) {
  654. c.createArgument().setLine(cvsPackage);
  655. }
  656. for (Module m : modules) {
  657. c.createArgument().setValue(m.getName());
  658. }
  659. if (this.compression > 0
  660. && this.compression <= MAXIMUM_COMRESSION_LEVEL) {
  661. c.createArgument(true).setValue("-z" + this.compression);
  662. }
  663. if (quiet && !reallyquiet) {
  664. c.createArgument(true).setValue("-q");
  665. }
  666. if (reallyquiet) {
  667. c.createArgument(true).setValue("-Q");
  668. }
  669. if (noexec) {
  670. c.createArgument(true).setValue("-n");
  671. }
  672. if (cvsRoot != null) {
  673. c.createArgument(true).setLine("-d" + cvsRoot);
  674. }
  675. }
  676. /**
  677. * remove a particular command from a vector of command lines
  678. * @param c command line which should be removed
  679. */
  680. protected void removeCommandline(Commandline c) {
  681. commandlines.remove(c);
  682. }
  683. /**
  684. * Adds direct command-line to execute.
  685. * @param c command line to execute
  686. */
  687. public void addConfiguredCommandline(Commandline c) {
  688. this.addConfiguredCommandline(c, false);
  689. }
  690. /**
  691. * Configures and adds the given Commandline.
  692. * @param c commandline to insert
  693. * @param insertAtStart If true, c is
  694. * inserted at the beginning of the vector of command lines
  695. */
  696. public void addConfiguredCommandline(Commandline c,
  697. boolean insertAtStart) {
  698. if (c == null) {
  699. return;
  700. }
  701. this.configureCommandline(c);
  702. if (insertAtStart) {
  703. commandlines.add(0, c);
  704. } else {
  705. commandlines.add(c);
  706. }
  707. }
  708. /**
  709. * If set to a value 1-9 it adds -zN to the cvs command line, else
  710. * it disables compression.
  711. * @param level compression level 1 to 9
  712. */
  713. public void setCompressionLevel(int level) {
  714. this.compression = level;
  715. }
  716. /**
  717. * If true, this is the same as compressionlevel="3".
  718. *
  719. * @param usecomp If true, turns on compression using default
  720. * level, AbstractCvsTask.DEFAULT_COMPRESSION_LEVEL.
  721. */
  722. public void setCompression(boolean usecomp) {
  723. setCompressionLevel(usecomp
  724. ? AbstractCvsTask.DEFAULT_COMPRESSION_LEVEL : 0);
  725. }
  726. /**
  727. * add a named module/package.
  728. *
  729. * @param m Module
  730. * @since Ant 1.8.0
  731. */
  732. public void addModule(Module m) {
  733. modules.add(m);
  734. }
  735. protected List<Module> getModules() {
  736. return new ArrayList<>(modules);
  737. }
  738. public static final class Module {
  739. private String name;
  740. public void setName(String s) {
  741. name = s;
  742. }
  743. public String getName() {
  744. return name;
  745. }
  746. }
  747. }