001: // CvsRunner.java
002: // $Id: CvsRunner.java,v 1.34 2003/06/04 09:06:55 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1997.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.cvs;
007:
008: import java.io.BufferedInputStream;
009: import java.io.BufferedOutputStream;
010: import java.io.BufferedReader;
011: import java.io.DataInputStream;
012: import java.io.File;
013: import java.io.FileOutputStream;
014: import java.io.FilterInputStream;
015: import java.io.FilterOutputStream;
016: import java.io.IOException;
017: import java.io.InputStream;
018: import java.io.InputStreamReader;
019: import java.io.OutputStream;
020: import java.io.PrintStream;
021: import java.io.Reader;
022:
023: import java.util.NoSuchElementException;
024: import java.util.StringTokenizer;
025:
026: //
027: // FIXME add extra environment parameter to all public methods
028: // witch run cvs.
029: //
030:
031: class CvsRunner implements CVS {
032: // private static final File tmpdir = new File("/tmp");
033: public static boolean debug = true;
034:
035: /**
036: * Dump the given string into a temporary file.
037: * This is used for th <code>-f</code> argument of the cvs commit command.
038: * This method should only be used from a synchronized method.
039: * @param string The string to dump.
040: */
041:
042: File getTemporaryFile(String string) throws CvsException {
043: // Create a pseudo-random temporary filename
044: String fn = "cvs-" + System.currentTimeMillis() + "-"
045: + string.length();
046: File temp = null;
047: try {
048: temp = File.createTempFile(fn, "-" + string.length());
049: temp.deleteOnExit();
050: PrintStream out = new PrintStream(
051: new FileOutputStream(temp));
052: out.print(string);
053: out.close();
054: return temp;
055: } catch (IOException ex) {
056: error("temporaryFile",
057: "unable to create/use temporary file: "
058: + temp.getAbsolutePath());
059: }
060: return temp;
061: }
062:
063: /**
064: * Emit an error.
065: * Some abnormal situation occured, emit an error message.
066: * @param mth The method in which the error occured.
067: * @param msg The message to emit.
068: * @exception CvsException The exception that will be thrown as a
069: * result of the error.
070: */
071:
072: protected void error(String mth, String msg) throws CvsException {
073: String emsg = this .getClass().getName() + "[" + mth + "]: "
074: + msg;
075: System.err.println(emsg);
076: throw new CvsException(emsg);
077: }
078:
079: /**
080: * Read the given input stream as a text.
081: * @param in The input stream to read from.
082: * @param into The StringBuffer to fill.
083: * @return The provided StringBuffer, filled with the stream content.
084: */
085:
086: private StringBuffer readText(InputStream procin, StringBuffer into)
087: throws IOException {
088: DataInputStream in = new DataInputStream(procin);
089: String line = null;
090:
091: while ((line = in.readLine()) != null) {
092: if (into != null)
093: into.append(line + "\n");
094: }
095: return into;
096: }
097:
098: /**
099: * Get a filename between quote contained in this String.
100: * @return the filename of null.
101: */
102: protected String getQuotedFilename(String line) {
103: int idx = line.indexOf('\'');
104: if (idx == -1)
105: return null;
106: char ch;
107: StringBuffer buffer = new StringBuffer();
108: try {
109: while ((ch = line.charAt(idx++)) != '\'')
110: buffer.append(ch);
111: } catch (ArrayIndexOutOfBoundsException ex) {
112: }
113: return buffer.toString();
114: }
115:
116: /**
117: * Parse the error message and throw an exception if necessary.
118: * @exception UpToDateCheckFailedException if file was not up to date.
119: * @exception CvsAddException if an error ocurs during add.
120: * @exception IOException if an IO error occurs.
121: */
122: protected StringBuffer readError(InputStream procin,
123: StringBuffer into) throws IOException, CvsException {
124: DataInputStream in = new DataInputStream(procin);
125: String line = null;
126:
127: while ((line = in.readLine()) != null) {
128: if (into != null)
129: into.append(line + "\n");
130: if (line.startsWith("cvs commit:")) {
131: line = line.substring(12);
132: if (line.startsWith("Up-to-date check failed")) {
133: String filename = getQuotedFilename(line);
134: throw new UpToDateCheckFailedException(filename);
135: } else {
136: throw new CvsCommitException(line);
137: }
138: } else if (line.startsWith("cvs add:")) {
139: throw new CvsAddException(line.substring(8));
140: } else if (line.startsWith("cvs update:")) {
141: throw new CvsUpdateException(line.substring(11));
142: }
143: }
144: return into;
145: }
146:
147: /**
148: * Wait for the underlying CVS process to finish.
149: * Once the process is terminated, all relevant streams are closed, and
150: * an exception if potentially thrown if the process indicated failure.
151: * @param proc The CVS process.
152: * @param ccode Should we expect a zero status from the child process.
153: * @exception CvsException If a zero status is expected, and the CVS
154: * process exit status is not zero.
155: */
156:
157: protected synchronized void waitForCompletion(Process proc,
158: boolean ccode) throws CvsException {
159: while (true) {
160: try {
161: CvsException exception = null;
162: // Try reading the error stream:
163: StringBuffer errorlog = new StringBuffer();
164: try {
165: errorlog = readError(proc.getErrorStream(),
166: errorlog);
167: } catch (IOException ex) {
168: ex.printStackTrace();
169: } catch (CvsException cvs_ex) {
170: exception = cvs_ex;
171: } finally {
172: // Close all streams, just to make sure...
173: try {
174: proc.getInputStream().close();
175: } catch (Exception ex) {
176: }
177: try {
178: proc.getOutputStream().close();
179: } catch (Exception ex) {
180: }
181: try {
182: proc.getErrorStream().close();
183: } catch (Exception ex) {
184: }
185: // Check ecode if requested to do so:
186: proc.waitFor();
187: }
188: //no exception thrown, that's an unknown exception.
189: int ecode = proc.exitValue();
190: if (ecode != 0) {
191: String msg = ("Process exited with error code: "
192: + ecode + " error [" + errorlog + "]");
193: if (debug)
194: System.err.println(msg);
195: if (ccode) {
196: if (exception == null)
197: throw new CvsException(msg);
198: else
199: throw exception;
200: }
201: }
202: return;
203: } catch (InterruptedException e) {
204: }
205: }
206: }
207:
208: /**
209: * Run a cvs command, return the process object.
210: * @param args The command to run.
211: * @exception IOException If the process couldn't be launched.
212: */
213:
214: protected Process runCvsProcess(String args[]) throws IOException {
215: if (debug) {
216: for (int i = 0; i < args.length; i++)
217: System.out.print(args[i] + " ");
218: System.out.println();
219: }
220: return Runtime.getRuntime().exec(args);
221: }
222:
223: /**
224: * Run a cvs command, return the process object.
225: * @param args The command to run.
226: * @param env The extra environment.
227: * @exception IOException If the process couldn't be launched.
228: */
229:
230: protected Process runCvsProcess(String args[], String env[])
231: throws IOException {
232: if (debug) {
233: for (int i = 0; i < args.length; i++)
234: System.out.print(args[i] + " ");
235: System.out.println();
236: }
237: return Runtime.getRuntime().exec(args, env);
238: }
239:
240: /**
241: * Get the CVS command String array.
242: * @param cvs The target CvsDirectory in which the command is to be run.
243: * @param cvsopts The CVS wide options.
244: * @param cmdopts The command, and its optional options.
245: * @return A String array, giving the command to be executed.
246: */
247:
248: protected String[] getCommand(CvsDirectory cvs, String cvsopts[],
249: String cmdopts[]) {
250: String cvswrapper[] = cvs.getCvsWrapper();
251: String cvsdefs[] = cvs.getCvsDefaults();
252: String cmd[] = new String[cvswrapper.length + cvsdefs.length
253: + ((cvsopts != null) ? cvsopts.length : 0)
254: + ((cmdopts != null) ? cmdopts.length : 0)];
255: int cmdptr = 0;
256: // Copy everything into the command:
257: if (cvswrapper != null) {
258: for (int i = 0; i < cvswrapper.length; i++)
259: cmd[cmdptr++] = cvswrapper[i];
260: }
261: if (cvsdefs != null) {
262: for (int i = 0; i < cvsdefs.length; i++)
263: cmd[cmdptr++] = cvsdefs[i];
264: }
265: if (cvsopts != null) {
266: for (int i = 0; i < cvsopts.length; i++)
267: cmd[cmdptr++] = cvsopts[i];
268: }
269: if (cmdopts != null) {
270: for (int i = 0; i < cmdopts.length; i++)
271: cmd[cmdptr++] = cmdopts[i];
272: }
273: return cmd;
274: }
275:
276: // private void parseUpdateDirectoriesOutput(InputStream procin,
277: // UpdateHandler handler)
278: // throws IOException, CvsException
279: // {
280: // DataInputStream in = new DataInputStream (procin) ;
281: // String line = null ;
282: // while ((line = in.readLine()) != null) {
283: // // Make sure the line isn't empty:
284: // if ( line.length() <= 0 )
285: // continue;
286: // System.out.println("READING : "+line);
287: // if ( line.startsWith("cvs update:") ) {
288: // line = line.substring(13);
289: // if ( line.startsWith("Updating") ) {
290: // String dirname = line.substring(9);
291: // if ( dirname.equals(".") )
292: // continue;
293: // System.out.println("Found Ckecked out : "+dirname);
294: // //handler.notifyEntry(dirname, DIR_CO);
295: // } else if ( line.startsWith("New directory") ) {
296: // int idx = 15;
297: // char ch;
298: // StringBuffer buffer = new StringBuffer();
299: // while ( (ch = line.charAt(idx++)) != '\'' ) {
300: // buffer.append(ch);
301: // }
302: // String dirname = buffer.toString();
303: // System.out.println("Found UnCkecked out : "+dirname);
304: // //handler.notifyEntry(dirname, DIR_NCO);
305: // }
306: // }
307: // }
308: // }
309:
310: /**
311: * Parse the CVS output for the update command.
312: * @param procin The CVS process output.
313: * @param handler The handler to callback.
314: * @exception IOException If IO error occurs.
315: * @exception CvsException If the CVS process failed.
316: */
317:
318: private void parseUpdateOutput(InputStream procin,
319: UpdateHandler handler) throws IOException, CvsException {
320: DataInputStream in = new DataInputStream(procin);
321: String line = null;
322: while ((line = in.readLine()) != null) {
323: // Make sure the line isn't empty:
324: if (line.length() <= 0)
325: continue;
326: int status = -1;
327: int ch = line.charAt(0);
328: // Skip CVS verbose:
329: if (line.charAt(1) != ' ')
330: continue;
331: // Parse the status:
332: switch (ch) {
333: case 'U':
334: status = FILE_OK;
335: break;
336: case 'A':
337: status = FILE_A;
338: break;
339: case 'R':
340: status = FILE_R;
341: break;
342: case 'M':
343: status = FILE_M;
344: break;
345: case 'C':
346: status = FILE_C;
347: break;
348: case '?':
349: status = FILE_Q;
350: break;
351: default:
352: // We just ignore this right now.
353: continue;
354: }
355: // Notify handler:
356: handler.notifyEntry(line.substring(2), status);
357: }
358: }
359:
360: private void parseStatusOutput(InputStream procin,
361: StatusHandler handler) throws IOException, CvsException {
362: BufferedReader reader = new BufferedReader(
363: new InputStreamReader(procin));
364: String line = null;
365: StringTokenizer st = null;
366: String file = null;
367: String revision = null;
368: String token = null;
369: String st_opt = null;
370:
371: while ((line = reader.readLine()) != null) {
372: if (line.length() <= 0)
373: continue;
374: if (line.startsWith("==")) {
375: file = null;
376: revision = null;
377: continue;
378: }
379: st = new StringTokenizer(line);
380:
381: if (st.hasMoreTokens()) {
382: try {
383: token = st.nextToken();
384: if (token.equals("File:")) {
385: file = st.nextToken();
386: if (file.equals("no") && st.hasMoreTokens()) {
387: token = st.nextToken();
388: if (token.equals("file")
389: && st.hasMoreTokens())
390: file = st.nextToken();
391: }
392: } else if (token.equals("Repository")
393: && st.nextToken().equals("revision:")) {
394: revision = st.nextToken();
395: } else if (token.equals("Sticky")) {
396: token = st.nextToken();
397: if (token.equals("Tag:")) {
398: // sticky tag
399: } else if (token.equals("Date:")) {
400: // sticky date
401: } else if (token.equals("Options:")) {
402: st_opt = st.nextToken();
403: if (st_opt.equals("(none)")) {
404: st_opt = null;
405: }
406: }
407: }
408: } catch (NoSuchElementException ex) {
409: ex.printStackTrace();
410: file = null;
411: revision = null;
412: }
413: }
414:
415: if ((file != null) && (revision != null)) {
416: handler.notifyEntry(file, revision, st_opt);
417: file = null;
418: revision = null;
419: st_opt = null;
420: }
421: }
422: }
423:
424: /**
425: * Parse the CVS output for the commit command.
426: * @param procin The CVS process output.
427: * @param handler The handler to callback.
428: * @exception IOException If some IO error occur.
429: * @exception CvsException If the CVS process failed.
430: */
431:
432: private void parseCommitOutput(InputStream procin,
433: CommitHandler handler) throws IOException, CvsException {
434: DataInputStream in = new DataInputStream(procin);
435: String line = null;
436: while ((line = in.readLine()) != null) {
437: if (!line.startsWith("Checking in "))
438: continue;
439: String filename = line.substring("Checking in ".length(),
440: line.length() - 1);
441: handler.notifyEntry(filename, FILE_OK);
442: }
443: return;
444: }
445:
446: /**
447: * Run the 'update -p -r <revision>' command.
448: * @param cvs The target CvsDirectory in which the command is to be run.
449: * @param name The file name to which the update command applies.
450: * @param revision The revision to retrieve
451: * @param out The OutputStream
452: * @exception CvsException If the underlying CVS process fails
453: */
454: void cvsRevert(CvsDirectory cvs, String name, String revision,
455: OutputStream out, String env[]) throws CvsException {
456: String cmdopts[] = { "update", "-p", "-r", revision, name };
457: String command[] = getCommand(cvs, null, cmdopts);
458: try {
459: Process proc = runCvsProcess(command, env);
460: // dump the process inputStream in the file.
461: BufferedInputStream in = new BufferedInputStream(proc
462: .getInputStream());
463: BufferedOutputStream bout = new BufferedOutputStream(out);
464: byte buf[] = new byte[4096];
465: try {
466: for (int got = 0; (got = in.read(buf)) > 0;)
467: bout.write(buf, 0, got);
468: bout.flush();
469: } catch (IOException ex) {
470: throw new CvsException(ex.getMessage());
471: } finally {
472: try {
473: bout.close();
474: } catch (Exception ex) {
475: }
476: }
477: waitForCompletion(proc, true);
478: } catch (IOException ex) {
479: ex.printStackTrace();
480: throw new CvsException(ex.getMessage());
481: }
482: }
483:
484: /**
485: * Run the 'update -p -r <revision>' command.
486: * @param cvs The target CvsDirectory in which the command is to be run.
487: * @param name The file name to which the update command applies.
488: * @param revision The revision to retrieve
489: * @param file The local file
490: * @exception CvsException If the underlying CVS process fails
491: */
492: void cvsRevert(CvsDirectory cvs, String name, String revision,
493: File file, String env[]) throws CvsException {
494: try {
495: cvsRevert(cvs, name, revision, new FileOutputStream(file),
496: env);
497: } catch (IOException ex) {
498: ex.printStackTrace();
499: throw new CvsException(ex.getMessage());
500: }
501: }
502:
503: // void cvsUpdateDirectories(CvsDirectory cvs, UpdateHandler handler)
504: // throws CvsException
505: // {
506: // String cvsopts[] = { "-n" };
507: // String cmdopts[] = new String[2];
508: // cmdopts[0] = "update";
509: // cmdopts[1] = "-d";
510: // String command[] = getCommand(cvs, cvsopts, cmdopts);
511: // try {
512: // Process proc = runCvsProcess(command);
513: // parseUpdateDirectoriesOutput(proc.getInputStream(), handler);
514: // waitForCompletion(proc, false);
515: // } catch (IOException ex) {
516: // ex.printStackTrace();
517: // throw new CvsException(ex.getMessage());
518: // }
519: // }
520:
521: /**
522: * Run the update command.
523: * @param names The file names to which the update command applies.
524: * @param handler The CVS output parsing handler.
525: * @exception CvsException If the underlying CVS process fails.
526: * @see UpdateHandler
527: */
528:
529: void cvsUpdate(CvsDirectory cvs, String names[],
530: UpdateHandler handler) throws CvsException {
531: // Build the CVS command:
532: String cmdopts[] = new String[names.length + 1];
533: cmdopts[0] = "update";
534: System.arraycopy(names, 0, cmdopts, 1, names.length);
535: String command[] = getCommand(cvs, null, cmdopts);
536: // Now run it !
537: try {
538: Process proc = runCvsProcess(command);
539: parseUpdateOutput(proc.getInputStream(), handler);
540: waitForCompletion(proc, true);
541: } catch (IOException ex) {
542: ex.printStackTrace();
543: throw new CvsException(ex.getMessage());
544: }
545: }
546:
547: /**
548: * Run the update command on the whole directory. (not recursivly)
549: * @param cvs The target CvsDirectory in which the command is to be run.
550: * @param handler The CVS output handler.
551: * @exception CvsException If something failed.
552: */
553:
554: void cvsUpdate(CvsDirectory cvs, UpdateHandler handler)
555: throws CvsException {
556: // Build the CVS command:
557: String cmdopts[] = { "update", "-l" };
558: // "-d",
559: // cvs.getDirectory().getAbsolutePath() };
560: String command[] = getCommand(cvs, null, cmdopts);
561: // Now run it !
562: try {
563: Process proc = runCvsProcess(command);
564: parseUpdateOutput(proc.getInputStream(), handler);
565: waitForCompletion(proc, true);
566: } catch (Exception ex) {
567: ex.printStackTrace();
568: throw new CvsException(ex.getMessage());
569: }
570: }
571:
572: /**
573: * Check this file status.
574: * We just run the update command with the -n toggle.
575: * @param cvs The target CvsDirectory in which the command is to be run.
576: * @param handler The underlying update handler callback.
577: * @exception CvsException If the CVS process failed.
578: */
579: void cvsLoad(CvsDirectory cvs, String filename,
580: UpdateHandler handler) throws CvsException {
581: // Build the CVS command:
582: String cvsopts[] = { "-n" };
583: String cmdopts[] = { "update", "-I", "!", filename };
584: String command[] = getCommand(cvs, cvsopts, cmdopts);
585: // Run it:
586: try {
587: Process proc = runCvsProcess(command);
588: parseUpdateOutput(proc.getInputStream(), handler);
589: waitForCompletion(proc, false);
590: } catch (IOException ex) {
591: ex.printStackTrace();
592: throw new CvsException(ex.getMessage());
593: }
594: }
595:
596: /**
597: * Check this file status.
598: * We just run the update command and the status with the -n toggle.
599: * @param cvs The target CvsDirectory in which the command is to be run.
600: * @param handler The underlying update handler callback.
601: * @param statush The underlying status handler callback.
602: * @exception CvsException If the CVS process failed.
603: */
604: void cvsLoad(CvsDirectory cvs, String filename,
605: UpdateHandler handler, StatusHandler statush)
606: throws CvsException {
607: // Build the CVS command:
608: String cvsopts[] = { "-n" };
609: String cmdopts[] = { "update", "-I", "!", filename };
610: String command[] = getCommand(cvs, cvsopts, cmdopts);
611: // Run it:
612: try {
613: Process proc = runCvsProcess(command);
614: parseUpdateOutput(proc.getInputStream(), handler);
615: waitForCompletion(proc, false);
616: } catch (IOException ex) {
617: ex.printStackTrace();
618: throw new CvsException(ex.getMessage());
619: }
620: // now get revisions number
621: String cmdstatus[] = new String[2];
622: cmdstatus[0] = "status";
623: cmdstatus[1] = filename;
624: command = getCommand(cvs, null, cmdstatus);
625: try {
626: Process proc = runCvsProcess(command);
627: parseStatusOutput(proc.getInputStream(), statush);
628: waitForCompletion(proc, false);
629: } catch (IOException ex) {
630: ex.printStackTrace();
631: throw new CvsException(ex.getMessage());
632: }
633: }
634:
635: /**
636: * Check all this directory files status.
637: * We just run the update command and the status with the -n toggle.
638: * @param cvs The target CvsDirectory in which the command is to be run.
639: * @param handler The underlying update handler callback.
640: * @param statush The underlying status handler callback.
641: * @exception CvsException If the CVS process failed.
642: */
643:
644: void cvsLoad(CvsDirectory cvs, UpdateHandler handler,
645: StatusHandler statush) throws CvsException {
646: // Build the CVS command:
647: String cvsopts[] = { "-n" };
648: String cmdopts[] = { "update", "-I", "!", "-l" };
649: String command[] = getCommand(cvs, cvsopts, cmdopts);
650: // Run it:
651: try {
652: Process proc = runCvsProcess(command);
653: parseUpdateOutput(proc.getInputStream(), handler);
654: waitForCompletion(proc, false);
655: } catch (IOException ex) {
656: ex.printStackTrace();
657: throw new CvsException(ex.getMessage());
658: }
659: // now get revisions number
660: String cmdstatus[] = { "status", "-l" };
661: command = getCommand(cvs, null, cmdstatus);
662: try {
663: Process proc = runCvsProcess(command);
664: parseStatusOutput(proc.getInputStream(), statush);
665: waitForCompletion(proc, false);
666: } catch (IOException ex) {
667: ex.printStackTrace();
668: throw new CvsException(ex.getMessage());
669: }
670: }
671:
672: /**
673: * Check this directory file status.
674: * We just run the update command with the -n toggle.
675: * @param cvs The target CvsDirectory in which the command is to be run.
676: * @param statush The underlying status handler callback.
677: * @exception CvsException If the CVS process failed.
678: */
679: void cvsStatus(CvsDirectory cvs, String filename,
680: StatusHandler statush) throws CvsException {
681: String cmdstatus[] = new String[2];
682: cmdstatus[0] = "status";
683: cmdstatus[1] = filename;
684: String command[] = getCommand(cvs, null, cmdstatus);
685:
686: try {
687: Process proc = runCvsProcess(command);
688: parseStatusOutput(proc.getInputStream(), statush);
689: waitForCompletion(proc, false);
690: } catch (IOException ex) {
691: ex.printStackTrace();
692: throw new CvsException(ex.getMessage());
693: }
694: }
695:
696: /**
697: * Run the commit command on the given set of files.
698: * @param cvs The target CvsDirectory in which the command is to be run.
699: * @param names The name of files to commit.
700: * @param comment Description of the file changes.
701: * @param handler The CVS output callback.
702: * @exception CvsException If the CVS process failed.
703: */
704:
705: void cvsCommit(CvsDirectory cvs, String names[], String comment,
706: CommitHandler handler) throws CvsException {
707: cvsCommit(cvs, names, comment, handler, null);
708: }
709:
710: /**
711: * Run the commit command on the given set of files.
712: * @param cvs The target CvsDirectory in which the command is to be run.
713: * @param names The name of files to commit.
714: * @param comment Description of the file changes.
715: * @param handler The CVS output callback.
716: * @param env The extra env to use during commit.
717: * @exception CvsException If the CVS process failed.
718: */
719:
720: void cvsCommit(CvsDirectory cvs, String names[], String comment,
721: CommitHandler handler, String env[]) throws CvsException {
722: // Build the CVS command:
723: String cmdopts[] = new String[names.length + 3];
724: File tmpfile = getTemporaryFile(comment);
725: cmdopts[0] = "commit";
726: cmdopts[1] = "-F";
727: cmdopts[2] = tmpfile.getAbsolutePath();
728: System.arraycopy(names, 0, cmdopts, 3, names.length);
729: String command[] = getCommand(cvs, null, cmdopts);
730: // Run it !
731: try {
732: Process proc = runCvsProcess(command, env);
733: parseCommitOutput(proc.getInputStream(), handler);
734: waitForCompletion(proc, true);
735: } catch (IOException ex) {
736: ex.printStackTrace();
737: throw new CvsException(ex.getMessage());
738: } finally {
739: tmpfile.delete();
740: }
741: }
742:
743: /**
744: * Ru the commit comamnd in the given directory.
745: * @param cvs The target CvsDirectory in which the command is to be run.
746: * @param msg Description of directory changes since last commit.
747: * @param handler The CVS output callback.
748: * @exception CvsException If the CVS process failed.
749: */
750:
751: void cvsCommit(CvsDirectory cvs, String msg, CommitHandler handler)
752: throws CvsException {
753: cvsCommit(cvs, msg, handler, (String[]) null);
754: }
755:
756: /**
757: * Ru the commit comamnd in the given directory.
758: * @param cvs The target CvsDirectory in which the command is to be run.
759: * @param msg Description of directory changes since last commit.
760: * @param handler The CVS output callback.
761: * @param env The extra env to use during commit.
762: * @exception CvsException If the CVS process failed.
763: */
764:
765: void cvsCommit(CvsDirectory cvs, String msg, CommitHandler handler,
766: String env[]) throws CvsException {
767: // Build the CVS command:
768: File tmpfile = getTemporaryFile(msg);
769: String cmdopts[] = new String[3];//5
770: cmdopts[0] = "commit";
771: cmdopts[1] = "-F";
772: cmdopts[2] = tmpfile.getAbsolutePath();
773: // cmdopts[3] = "-d";
774: // cmdopts[4] = cvs.getDirectory().getAbsolutePath();
775: String command[] = getCommand(cvs, null, cmdopts);
776: // Run it:
777: try {
778: Process proc = runCvsProcess(command, env);
779: parseCommitOutput(proc.getInputStream(), handler);
780: waitForCompletion(proc, true);
781: } catch (IOException ex) {
782: ex.printStackTrace();
783: throw new CvsException(ex.getMessage());
784: } finally {
785: tmpfile.delete();
786: }
787: }
788:
789: /**
790: * perform a cvs get
791: */
792: void cvsGet(CvsDirectory cvs, String path) throws CvsException {
793: String cmdopts[] = new String[2];
794: cmdopts[0] = "get";
795: cmdopts[1] = path;
796: String command[] = getCommand(cvs, null, cmdopts);
797: //Run it
798: try {
799: Process proc = runCvsProcess(command);
800: readText(proc.getInputStream(), null);
801: waitForCompletion(proc, true);
802: } catch (IOException ex) {
803: ex.printStackTrace();
804: throw new CvsException(ex.getMessage());
805: }
806: }
807:
808: /**
809: * Run the log command on the given file
810: * @param cvs The target CvsDirectory in which the command is to be run.
811: * @param name The name of the file to log.
812: * @exception CvsException If the CVS command failed.
813: * @return A String containing the file's log.
814: */
815:
816: String cvsLog(CvsDirectory cvs, String name) throws CvsException {
817: // Build the CVS command:
818: String cmdopts[] = new String[2];
819: cmdopts[0] = "log";
820: cmdopts[1] = name;
821: String command[] = getCommand(cvs, null, cmdopts);
822: StringBuffer into = new StringBuffer();
823: // Run it:
824: try {
825: Process proc = runCvsProcess(command);
826: readText(proc.getInputStream(), into);
827: waitForCompletion(proc, false);
828: } catch (IOException ex) {
829: ex.printStackTrace();
830: throw new CvsException(ex.getMessage());
831: }
832: return into.toString();
833: }
834:
835: /**
836: * Run the diff command on the given file
837: * @param cvs The target CvsDirectory in which the command is to be run.
838: * @param name The name of the file to diff.
839: * @exception CvsException If the CVS command failed.
840: * @return A String containing the diff, or <strong>null</strong> if the
841: * file is in sync with the repository.
842: */
843:
844: String cvsDiff(CvsDirectory cvs, String name) throws CvsException {
845: // Build the CVS command:
846: String cmdopts[] = new String[2];
847: cmdopts[0] = "diff";
848: cmdopts[1] = name;
849: String command[] = getCommand(cvs, null, cmdopts);
850: StringBuffer into = new StringBuffer();
851: // Run it:
852: try {
853: Process proc = runCvsProcess(command);
854: readText(proc.getInputStream(), into);
855: waitForCompletion(proc, false);
856: } catch (IOException ex) {
857: ex.printStackTrace();
858: throw new CvsException(ex.getMessage());
859: }
860: return (into.length() > 0) ? into.toString() : null;
861: }
862:
863: /**
864: * Run the remove command.
865: * @param cvs The target CvsDirectory in which the command is to be run.
866: * @param names The name of the files to remove locally.
867: * @exception CvsException If the CVS command failed.
868: */
869:
870: void cvsRemove(CvsDirectory cvs, String names[])
871: throws CvsException {
872: // Build the command:
873: String cmdopts[] = new String[names.length + 1];
874: cmdopts[0] = "remove";
875: System.arraycopy(names, 0, cmdopts, 1, names.length);
876: String command[] = getCommand(cvs, null, cmdopts);
877: // Run it:
878: try {
879: Process proc = runCvsProcess(command);
880: readText(proc.getInputStream(), null);
881: waitForCompletion(proc, true);
882: } catch (IOException ex) {
883: ex.printStackTrace();
884: throw new CvsException(ex.getMessage());
885: }
886: }
887:
888: /**
889: * Run the add command
890: * @param cvs The target CvsDirectory in which the command is to be run.
891: * @param names The name of the files to add locally.
892: * @exception CvsException If the CVS command failed.
893: */
894:
895: void cvsAdd(CvsDirectory cvs, String names[]) throws CvsException {
896: cvsAdd(cvs, names, null);
897: }
898:
899: /**
900: * Run the add command
901: * @param cvs The target CvsDirectory in which the command is to be run.
902: * @param names The name of the files to add locally.
903: * @param env The extra env to use during the process.
904: * @exception CvsException If the CVS command failed.
905: */
906:
907: void cvsAdd(CvsDirectory cvs, String names[], String env[])
908: throws CvsException {
909: // Build the command:
910: String cmdopts[] = new String[names.length + 1];
911: cmdopts[0] = "add";
912: System.arraycopy(names, 0, cmdopts, 1, names.length);
913: String command[] = getCommand(cvs, null, cmdopts);
914: // Run it:
915: try {
916: Process proc = runCvsProcess(command, env);
917: readText(proc.getInputStream(), null);
918: waitForCompletion(proc, true);
919: } catch (IOException ex) {
920: ex.printStackTrace();
921: throw new CvsException(ex.getMessage());
922: }
923: }
924:
925: /**
926: * Run the admin command
927: * @param cvs The target CvsDirectory in which the command is to be run.
928: * @param command The rcs command
929: * @exception CvsException If the CVS command failed.
930: */
931: void cvsAdmin(CvsDirectory cvs, String command[])
932: throws CvsException {
933: String cmdopts[] = new String[command.length + 1];
934: cmdopts[0] = "admin";
935: System.arraycopy(command, 0, cmdopts, 1, command.length);
936: String cvscommand[] = getCommand(cvs, null, cmdopts);
937: try {
938: Process proc = runCvsProcess(cvscommand);
939: readText(proc.getInputStream(), null);
940: waitForCompletion(proc, true);
941: } catch (IOException ex) {
942: ex.printStackTrace();
943: throw new CvsException(ex.getMessage());
944: }
945: }
946:
947: /**
948: * Update a directory.
949: * @param cvs The target CvsDirectory in which the command is to be run.
950: * @param subdir The sub-directory of the above that needs to be updated.
951: * @param handler The CVS output handler.
952: * @exception CvsException If the CVS process fails.
953: */
954:
955: void cvsUpdateDirectory(CvsDirectory cvs, File subdir,
956: UpdateHandler handler) throws CvsException {
957: // Build the command:
958: String cmdopts[] = new String[4];
959: cmdopts[0] = "update";
960: cmdopts[1] = "-l";
961: cmdopts[2] = "-d";
962: cmdopts[3] = subdir.getName();
963: String command[] = getCommand(cvs, null, cmdopts);
964: // Run the command:
965: try {
966: Process proc = runCvsProcess(command);
967: parseUpdateOutput(proc.getInputStream(), handler);
968: waitForCompletion(proc, true);
969: } catch (IOException ex) {
970: ex.printStackTrace();
971: throw new CvsException(ex.getMessage());
972: }
973: }
974:
975: }
|