File: create.lisp

package info (click to toggle)
mcvs 1.0.13-17
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 676 kB
  • ctags: 648
  • sloc: lisp: 5,091; ansic: 223; sh: 190; makefile: 58
file content (164 lines) | stat: -rw-r--r-- 5,560 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
;;; This source file is part of the Meta-CVS program, 
;;; which is distributed under the GNU license.
;;; Copyright 2002 Kaz Kylheku

(require "dirwalk")
(require "system")
(require "mapping")
(require "types")
(require "chatter")
(require "options")
(require "restart")
(provide "create")

(defun mcvs-create (module release &optional global-options command-options)
  (multiple-value-bind (path created) (ensure-directories-exist *mcvs-map*)
    (declare (ignore path))
    (if (not created) 
      (error "A ~a directory already exists here." *mcvs-dir*)))

  (let ((preserve-mcvs-dir nil))
    (unwind-protect 
      (progn
	(let (filemap types)
	  (chatter-debug "Mapping.~%")
	  
	  ;; Gather up list of files to import, and build up mapping,
	  ;; as well as list of suffixes (file types).
	  (for-each-file-info (fi ".")
	    (cond
	      ((regular-p fi)
		 (let* ((path (canonicalize-path (file-name fi)))
			(suffix (suffix (file-name fi)))
			(file (mapping-generate-id :suffix suffix)))
		   (chatter-info "~a <- ~a~%" file path)
		   (push (make-mapping-entry :kind :file
					     :id file
					     :path path
					     :executable (executable-p 
							   fi))
			 filemap)
		   (when suffix
		     (setf types (adjoin (list suffix :default) 
					 types :test #'equal)))))
	      ((symlink-p fi)
		 (let ((path (canonicalize-path (file-name fi)))
		       (id (mapping-generate-id :prefix "S-" :no-dir t)))
		   (chatter-info "~a <- ~a~%" id path)
		   (push (make-mapping-entry :kind :symlink
					     :id id
					     :path path
					     :target (readlink path))
			 filemap)))))
				

	  ;; Write out types to file and allow user to edit.
	  (setf types (types-let-user-edit types *mcvs-types*))

	  ;; Detect backup files or other crud written by 
	  ;; user's text editor.
	  (current-dir-restore
	    (chdir *mcvs-dir*) 
	    (let (crud)
	      (for-each-path (p ".")
		(let ((cp (canonicalize-path p)))
		  (unless (or (path-equal cp *mcvs-types-name*)
			      (path-equal cp *this-dir*))
		    (push cp crud))))
	      (when crud
		(setf preserve-mcvs-dir t)
		(super-restart-case
		  (error "Unexpected files found in ~a directory. (Text editor backups?)"
			 *mcvs-dir*)
		  (continue ()
		    :report "Delete the unexpected files."
		    (unwind))
		  (info ()
		    :report "List the names of the unexpected files."
		    (dolist (cp crud)
		      (write-line cp))))
		(dolist (cp crud)
		  (unlink cp))
		(setf preserve-mcvs-dir nil))))

	  ;; User has edited, so now we must honor all of the :IGNORE
	  ;; entries in the types, and remove the matching files from the
	  ;; mapping.
	  (setf filemap (types-remove-ignores types filemap))

	  ;; Create F-files by hard linking
	  (dolist (entry filemap)
	    (with-slots (kind id path) entry
	      (when (eq kind :file)
		(link path id))))

	  ;; Write out mapping.
	  (mapping-write filemap *mcvs-map* :sort-map t)

	  ;; Create .cvsignore file.
	  (with-open-file (f (make-pathname :directory `(:relative ,*mcvs-dir*) 
					    :name ".cvsignore")
			     :direction :output)
	    (write-line *mcvs-map-local-name* f)
	    (write-line *mcvs-displaced-name* f))

	  (loop
	    (restart-case
	      (current-dir-restore
		(chdir *mcvs-dir*) 
		(chatter-debug "Invoking CVS.~%")

		(if (not (execute-program `("cvs" ,@(format-opt global-options) 
					   "import" "-I" "!"
					   ,@(format-opt command-options)
					   ,@(types-to-import-wrapper-args types)
					   ,module "Created-by-Meta-CVS" ,release)))
		  (error "CVS import failed."))
		(return))
	      (retry ()
		:report "Try invoking CVS again.")))))
      (if preserve-mcvs-dir
	(chatter-info "not removing ~a directory~%" *mcvs-dir*)
	(progn 
	  (chatter-debug "removing ~a directory~%" *mcvs-dir*)
	  (delete-recursive *mcvs-dir*)))))
  (values))

(defun mcvs-create-wrapper (cvs-options cvs-command-options mcvs-args)
  (if (< (length mcvs-args) 2)
    (error "specify module and release tag."))
  (destructuring-bind (module release &rest superfluous) mcvs-args
    (when superfluous
      (error "specify only module and release tag."))
    (mcvs-create module release cvs-options cvs-command-options)))

(defconstant *create-help*
"Syntax:

  mcvs create [ options ] module-name release-tag

Options:

  -d                Use a file's modification time as time of creation.
  -k subst-mode     Set default RCS keyword substitution mode.
  -I ignore-spec    Specify files to ignore in addition to whatever
                    is specified interactively. May cause problems;
                    since Meta-CVS will map these files anwyay.
  -b branch-num     Vendor branch number for CVS import. Deprecated
                    brain-damage; you should never need this.
  -m \"text ...\"     Log message.
  -W wrap-spec      CVS wrappers specification line. Keep in mind that 
                    Meta-CVS preserves suffixes only; CVS sees a
                    name like \"F-D3BC...30D5.html\".
Semantics:

  The create command makes a new Meta-CVS module from the files and symbolic
  links in the current directory, and all of its subdirectories. To work with
  the newly created module, you must check it out to create a working copy.
  The release-tag symbolically identifies the original baseline.

  There are some interactive steps involved. If any of the files have
  suffixes, like .c or .html, Meta-CVS will identify and tabulate them. 
  A text editor will pop up presenting you with an opportunity to edit
  a symbolic specification that assigns to each file type a CVS keyword
  expansion mode.")