mast 1.0.0 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
data/MANIFEST CHANGED
@@ -1,23 +1,20 @@
1
- #!mast bin lib meta test [A-Z]*
2
- bin
1
+ HISTORY.rdoc
2
+ LICENSE
3
+ MANIFEST
4
+ README.rdoc
3
5
  bin/mast
4
- lib
5
6
  lib/mast
7
+ lib/mast.rb
6
8
  lib/mast/cli.rb
7
9
  lib/mast/core_ext.rb
8
10
  lib/mast/manifest.rb
9
- lib/mast.rb
10
- meta
11
11
  meta/authors
12
12
  meta/contact
13
13
  meta/description
14
+ meta/homepage
15
+ meta/namespace
14
16
  meta/package
15
- meta/project
17
+ meta/repository
16
18
  meta/ruby
17
19
  meta/sitemap
18
- meta/version
19
- test
20
- TUTORIAL.rdoc
21
- HISTORY.rdoc
22
- LICENSE
23
- README.rdoc
20
+ meta/version
@@ -1,7 +1,7 @@
1
1
  = Mast
2
2
 
3
- * http://proutils.rubyforge.org
4
- * http://protuils.rubyforge.org/mast
3
+ * home: http://proutils.github.com/mast
4
+ * source: http://github.com/proutils/mast
5
5
 
6
6
 
7
7
  == DESCRIPTION
@@ -11,7 +11,7 @@ It can be useful in conjunction with packaging tools (such as Box), or as a stan
11
11
  tool for monitoring file changes.
12
12
 
13
13
 
14
- == FEATURES/ISSUES
14
+ == FEATURES
15
15
 
16
16
  * Self-referential header makes updating manifests easy.
17
17
  * Checksum lists can highlight changes to current files.
@@ -24,11 +24,86 @@ Please see the HISTORY.rdoc file.
24
24
 
25
25
  == SYNOPSIS
26
26
 
27
- Usage is fairly straight forward.
27
+ Mast is a convenient commandline tool for generating manifest and file hash lists.
28
+ It makes the process very simple, and even allows manifests to be updated
29
+ without repeating inclusion/exclusion criteria by storing the command parameters
30
+ in a comment line at the top of the generated output.
28
31
 
29
- $ mast **/*
32
+ Lets try a simple example. Lets say we have the following folder structure:
30
33
 
31
- Please see the TUTORIAL file for further details.
34
+ $ ls -R
35
+ .:
36
+ demo_rtar mint
37
+
38
+ ./demo_rtar:
39
+ Lorem_ipsum.txt lib meta web
40
+
41
+ ./demo_rtar/lib:
42
+ demo_rock
43
+
44
+ ./demo_rtar/lib/demo_rock:
45
+ tryme.rb
46
+
47
+ ./demo_rtar/meta:
48
+ data
49
+
50
+ ./demo_rtar/web:
51
+ index.html rocklobster.jpg
52
+
53
+ ./mint:
54
+ loremipsum.txt tryme.rb
55
+
56
+ Now lets look at the same folder via 'mast'.
57
+
58
+ $ mast
59
+ #!mast
60
+ demo_rtar
61
+ demo_rtar/Lorem_ipsum.txt
62
+ demo_rtar/lib
63
+ demo_rtar/lib/demo_rock
64
+ demo_rtar/lib/demo_rock/tryme.rb
65
+ demo_rtar/meta
66
+ demo_rtar/meta/data
67
+ demo_rtar/web
68
+ demo_rtar/web/index.html
69
+ demo_rtar/web/rocklobster.jpg
70
+ mint
71
+ mint/loremipsum.txt
72
+ mint/tryme.rb
73
+
74
+ As you can see it has listed all the files contained in the current folder. Notice also the first
75
+ line is empty except for the '#' character. This is a standard shell comment mark. We can specify
76
+ special criteria to the mast command and these options will be reflected on this line. For example,
77
+ lets say the mint directory is extraneous and we do not want it included in the list of files.
78
+
79
+ $ mast -x mint
80
+ #!mast -x mint
81
+ demo_rtar
82
+ demo_rtar/Lorem_ipsum.txt
83
+ demo_rtar/lib
84
+ demo_rtar/lib/demo_rock
85
+ demo_rtar/lib/demo_rock/tryme.rb
86
+ demo_rtar/meta
87
+ demo_rtar/meta/data
88
+ demo_rtar/web
89
+ demo_rtar/web/index.html
90
+ demo_rtar/web/rocklobster.jpg
91
+
92
+ So you can see how the commandline options carry over to the top comment line of the ouput. The advantage of
93
+ this is that if you save the output to a standard location, ie. a file named MANIFEST or meta/manifest with
94
+ an optional .txt prefix (case insensitive), then you can automaitcally update the file by calling +mast update+.
95
+
96
+ $ mast -x mint > MANIFEST
97
+ $ mast update
98
+ MANIFEST updated.
99
+
100
+ You can also add a checksum to the file list.
101
+
102
+ $ mast -x mint -g sha1
103
+
104
+ Mast also provides options for ignoring files based on their basename, as well
105
+ as omitting default excludes and ignores so that all files are lists. Use the
106
+ --help option for more details.
32
107
 
33
108
 
34
109
  == HOW TO INSTALL
@@ -47,11 +122,11 @@ then download the tarball package and type:
47
122
  Windows users use 'ruby setup.rb all'.
48
123
 
49
124
 
50
- == LICENSE
125
+ == COPYRIGHT
51
126
 
52
127
  Copyright (c) 2009 Thomas Sawyer <transfire@gmail.com>
53
128
 
54
- This program is ditributed unser the terms of the GPL license.
129
+ This program is ditributed unser the terms of the MIT license.
55
130
 
56
- See COPYING file for details.
131
+ See LICENSE or COPYING file for details.
57
132
 
@@ -1 +1,5 @@
1
+ module Mast
2
+ VERSION = "1.1" #:till: VERSION="<%= version %>"
3
+ end
4
+
1
5
  require 'mast/manifest'
@@ -18,18 +18,20 @@
18
18
  # Commands:
19
19
  # -c --create Generate a new manifest. (default)
20
20
  # -u --update Update an existing manifest.
21
- # -l --list List the files give in the manifest file. (Use -f to specify an alternate file.)
22
- # -s --show Show all files that would appear in the manifest file if it were updated.
21
+ # -l --list List the files given in the manifest file. (Use -f to specify an alternate file.)
23
22
  # -d --diff Diff manifest file against actual.
24
23
  # -n --new List existant files that are not given in the manifest.
25
24
  # -o --old List files given in the manifest but are non-existent.
26
25
  # --clean Remove non-manifest files. (Will ask for confirmation first.)
27
- # -v --verify (TODO) Verify that a manifest matches actual.
26
+ # -v --verify Verify that a manifest matches actual.
28
27
  # -h --help Display this help message.
29
28
  #
30
29
  # Options:
31
30
  # -a --all Include all files. This deactivates deafult exclusions
32
31
  # so it is possible to make complete list of all contents.
32
+ # --dir When creating a list include directory paths; by default
33
+ # only files are listed.
34
+ # -s --show Show files using the options from the manifest file.
33
35
  # -f --file PATH Path to manifest file. When using update command, if not
34
36
  # given then the file matching 'MANIFEST', case-insensitive
35
37
  # and with an optional '.txt' extension, will be looked for
@@ -40,7 +42,7 @@
40
42
  # -x --exclude PATH Exclude a file or dir from the manifest matching against
41
43
  # full pathname. You can use --exclude repeatedly.
42
44
  # --ignore PATH Exclude a file or dir from the manifest matching against
43
- # an extires basename. You can use --ignore repeatedly.
45
+ # an entries basename. You can use --ignore repeatedly.
44
46
  # -q --quiet Suppress extraneous output.
45
47
 
46
48
  require 'mast'
@@ -70,6 +72,8 @@ module Mast
70
72
  attr_accessor :include
71
73
  attr_accessor :exclude
72
74
  attr_accessor :all
75
+ attr_accessor :dir
76
+ attr_accessor :show
73
77
 
74
78
  #
75
79
  def initialize
@@ -83,8 +87,18 @@ module Mast
83
87
  @command = []
84
88
  end
85
89
 
86
- # Run command.
90
+ #
87
91
  def run
92
+ begin
93
+ run_command
94
+ rescue => err
95
+ raise err if $DEBUG
96
+ report err
97
+ end
98
+ end
99
+
100
+ # Run command.
101
+ def run_command
88
102
  optparse
89
103
  if @command.size > 1
90
104
  raise ArgumentError, "Please issue only one command."
@@ -94,7 +108,7 @@ module Mast
94
108
  when :create then generate
95
109
  when :update then update
96
110
  when :list then list
97
- when :show then show
111
+ #when :show then show
98
112
  when :diff then diff
99
113
  when :new then new
100
114
  when :old then old
@@ -113,15 +127,16 @@ module Mast
113
127
  [ '--digest' , '-g', GetoptLong::REQUIRED_ARGUMENT ],
114
128
  [ '--exclude', '-x', GetoptLong::REQUIRED_ARGUMENT ],
115
129
  #[ '--include', '-i', GetoptLong::REQUIRED_ARGUMENT ],
116
- [ '--ignore', GetoptLong::REQUIRED_ARGUMENT ],
130
+ [ '--ignore' , '-i', GetoptLong::REQUIRED_ARGUMENT ],
117
131
  [ '--all' , '-a', GetoptLong::NO_ARGUMENT ],
132
+ [ '--dir' , GetoptLong::NO_ARGUMENT ],
133
+ [ '--show' , '-s', GetoptLong::NO_ARGUMENT ],
118
134
  [ '--quiet' , '-q', GetoptLong::NO_ARGUMENT ],
119
135
  # commands
120
136
  [ '--help' , '-h', GetoptLong::NO_ARGUMENT ],
121
137
  [ '--create' , '-c', GetoptLong::NO_ARGUMENT ],
122
138
  [ '--update' , '-u', GetoptLong::NO_ARGUMENT ],
123
139
  [ '--list' , '-l', GetoptLong::NO_ARGUMENT ],
124
- [ '--show' , '-s', GetoptLong::NO_ARGUMENT ],
125
140
  [ '--diff' , '-d', GetoptLong::NO_ARGUMENT ],
126
141
  [ '--new' , '-n', GetoptLong::NO_ARGUMENT ],
127
142
  [ '--old' , '-o', GetoptLong::NO_ARGUMENT ],
@@ -139,8 +154,8 @@ module Mast
139
154
  @command << :update
140
155
  when '--list'
141
156
  @command << :list
142
- when '--show'
143
- @command << :show
157
+ #when '--show'
158
+ # @command << :show
144
159
  when '--diff'
145
160
  @command << :diff
146
161
  when '--new'
@@ -162,6 +177,10 @@ module Mast
162
177
  # @include << val
163
178
  #when '--ignore'
164
179
  # @ignore << val
180
+ when '--show'
181
+ @show = true
182
+ when '--dir'
183
+ @dir = true
165
184
  when '--all'
166
185
  @all = true
167
186
  when '--quiet'
@@ -213,10 +232,10 @@ module Mast
213
232
  puts manifest.filelist
214
233
  end
215
234
 
216
- # List files in manifest file.
217
- def show
218
- puts manifest.showlist
219
- end
235
+ #
236
+ #def show
237
+ # puts manifest.showlist
238
+ #end
220
239
 
221
240
  # Show diff comparison between listed and actual.
222
241
  def diff
@@ -282,7 +301,7 @@ module Mast
282
301
 
283
302
  # Options for Manifest class taken from commandline arguments.
284
303
  def manifest_options
285
- { :file=>file, :digest=>digest, :exclude=>exclude, :ignore=>ignore, :all=>all, :include=>include }
304
+ { :file=>file, :digest=>digest, :exclude=>exclude, :ignore=>ignore, :all=>all, :dir=>dir, :include=>include, :show=>show }
286
305
  end
287
306
 
288
307
  # Quiet opertation?
@@ -302,19 +321,24 @@ module Mast
302
321
  ask("The above files will be removed. Continue?", "yN")
303
322
  end
304
323
 
324
+ #
325
+ def report(message)
326
+ $stderr << "#{message}\n" unless quiet?
327
+ end
328
+
305
329
  # Report manifest created.
306
330
  def report_created(file)
307
331
  file = File.basename(file)
308
- puts "#{file} created." unless quiet?
332
+ report "#{file} created."
309
333
  end
310
334
 
311
335
  # Report manifest updated.
312
336
  def report_updated(file)
313
337
  if file
314
338
  file = File.basename(file)
315
- puts "#{file} updated." unless quiet?
339
+ report "#{file} updated."
316
340
  else
317
- puts "Manifest file doesn't exit."
341
+ report "Manifest file doesn't exit."
318
342
  end
319
343
  end
320
344
 
@@ -341,7 +365,7 @@ module Mast
341
365
  puts list.join("\n")
342
366
  end
343
367
 
344
- # Report missing manifest file.
368
+ #
345
369
  def report_whatsold(list)
346
370
  puts list.join("\n")
347
371
  end
@@ -361,30 +385,30 @@ module Mast
361
385
 
362
386
  # Report missing manifest file.
363
387
  def report_manifest_missing
364
- puts "No manifest file."
388
+ report "No manifest file."
365
389
  end
366
390
 
367
391
  # Report action cancelled.
368
392
  def report_cancelled(action)
369
- puts "#{action} cancelled."
393
+ report "#{action} cancelled."
370
394
  end
371
395
 
372
396
  # Report manifest overwrite.
373
397
  def report_overwrite(manifest)
374
- puts "#{manifest.filename} already exists."
398
+ report "#{manifest.filename} already exists."
375
399
  end
376
400
 
377
401
  # Warn that a manifest already exist higher in this hierarchy.
378
402
  def report_warn_shadowing(manifest)
379
- puts "Shadowing #{manifest.file}."
403
+ report "Shadowing #{manifest.file}."
380
404
  end
381
405
 
382
406
  #
383
407
  def report_verify(check)
384
408
  if check
385
- puts "Manifest if good."
409
+ report "Manifest if good."
386
410
  else
387
- puts "Manifest if bad!"
411
+ report "Manifest if bad!"
388
412
  end
389
413
  end
390
414
  end
@@ -17,7 +17,7 @@ module Mast
17
17
  # TODO: Consider adding @include options rather then scanning entire directory.
18
18
  # But this can't be done unless we can write a routine that can look at @include
19
19
  # and reduce it to non-overlapping matches. Eg. [doc, doc/rdoc] should reduce
20
- # to just [doc]. Otherwise we will get duplicate entries, b/c the #output
20
+ # to just [doc]. Otherwise we will get duplicate entries, b/c the #output
21
21
  # method is written for speed and low memory footprint. This might mean @include
22
22
  # can't use file globs.
23
23
  #
@@ -50,7 +50,7 @@ module Mast
50
50
  def self.open(file=nil, options={})
51
51
  unless file
52
52
  file = Dir.glob(filename, File::FNM_CASEFOLD).first
53
- raise LoadError, "Manifest file is required." unless file
53
+ raise NoManifestError, "Manifest file is required." unless file
54
54
  end
55
55
  options[:file] = file
56
56
  new(options)
@@ -68,6 +68,13 @@ module Mast
68
68
  # Do not exclude standard exclusions.
69
69
  attr_accessor :all
70
70
 
71
+ # Include directories.
72
+ attr_accessor :dir
73
+
74
+ # Show as if another manifest (eg. use files options).
75
+ # TODO: Change name?
76
+ attr_accessor :show
77
+
71
78
  # What files to include. Defaults to ['*'].
72
79
  # Note that Mast automatically recurses through
73
80
  # directory entries, so using '**/*' would simply
@@ -89,6 +96,12 @@ module Mast
89
96
  #
90
97
  alias_method :all?, :all
91
98
 
99
+ #
100
+ alias_method :dir?, :dir
101
+
102
+ #
103
+ alias_method :show?, :show
104
+
92
105
  # New Manifest object.
93
106
  #
94
107
  def initialize(options={})
@@ -97,6 +110,8 @@ module Mast
97
110
  @ignore = []
98
111
  @format = 'csf'
99
112
  @all = false
113
+ @dir = false
114
+ @show = false
100
115
  @digest = nil
101
116
  @directory = Dir.pwd
102
117
 
@@ -132,7 +147,7 @@ module Mast
132
147
 
133
148
  #
134
149
  def file
135
- @file ||= Dir[File.join(directory, DEFAULT_FILE)].first || 'MANIFEST'
150
+ @file ||= Dir.glob(File.join(directory, DEFAULT_FILE), File::FNM_CASEFOLD).first || 'MANIFEST'
136
151
  end
137
152
 
138
153
  #
@@ -151,6 +166,7 @@ module Mast
151
166
 
152
167
  # Generate manifest.
153
168
  def generate(out=$stdout)
169
+ parse_topline unless read? if show?
154
170
  out << topline_string
155
171
  output(out)
156
172
  end
@@ -210,8 +226,12 @@ module Mast
210
226
  # Clean non-manifest files.
211
227
  def clean
212
228
  cfiles, cdirs = cleanlist.partition{ |f| !File.directory?(f) }
213
- FileUtils.rm(cfiles)
214
- FileUtils.rmdir(cdirs)
229
+ if cfiles.empty? && cdirs.empty?
230
+ $stderr < "No difference between list and actual.\n"
231
+ else
232
+ FileUtils.rm(cfiles)
233
+ FileUtils.rmdir(cdirs)
234
+ end
215
235
  end
216
236
 
217
237
  # List of current files.
@@ -236,13 +256,16 @@ module Mast
236
256
 
237
257
  #
238
258
  def cleanlist
259
+ showlist - filelist
260
+ end
261
+
262
+ # Files not listed in manifest.
263
+ def unlisted
239
264
  list = []
240
265
  Dir.chdir(directory) do
241
- keep = Dir.glob('*').select{|f| File.directory?(f)} # keep top-level directories?
242
- keep << filename # keep manifest file
243
- list = Dir.glob('**/*') - (filelist + keep)
266
+ list = Dir.glob('**/*')
244
267
  end
245
- list
268
+ list - filelist
246
269
  end
247
270
 
248
271
  #
@@ -293,11 +316,14 @@ module Mast
293
316
  files = files.reject{ |f| ignores.any?{ |i| File.fnmatch(i, File.basename(f)) } }
294
317
  files = files.sort
295
318
  files.each do |file|
296
- sum = checksum(file,digest)
297
- sum = sum + ' ' if sum
298
- out << "#{sum}#{file}"
299
- out << "\n" unless Array === out
300
- if File.directory?(file)
319
+ is_dir = File.directory?(file)
320
+ if !is_dir || (is_dir && dir?)
321
+ sum = checksum(file,digest)
322
+ sum = sum + ' ' if sum
323
+ out << "#{sum}#{file}"
324
+ out << "\n" unless Array === out
325
+ end
326
+ if is_dir
301
327
  rec_output(File.join(file,'*'), out)
302
328
  end
303
329
  end