mast 1.0.0 → 1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +17 -671
- data/MANIFEST +9 -12
- data/README.rdoc +84 -9
- data/lib/mast.rb +4 -0
- data/lib/mast/cli.rb +49 -25
- data/lib/mast/manifest.rb +40 -14
- data/meta/homepage +1 -0
- data/meta/{project → namespace} +0 -0
- data/meta/repository +1 -0
- data/meta/version +1 -1
- metadata +13 -15
- data/TUTORIAL.rdoc +0 -83
data/MANIFEST
CHANGED
@@ -1,23 +1,20 @@
|
|
1
|
-
|
2
|
-
|
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/
|
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
|
data/README.rdoc
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
= Mast
|
2
2
|
|
3
|
-
* http://proutils.
|
4
|
-
* http://
|
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
|
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
|
-
|
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
|
-
|
32
|
+
Lets try a simple example. Lets say we have the following folder structure:
|
30
33
|
|
31
|
-
|
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
|
-
==
|
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
|
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
|
|
data/lib/mast.rb
CHANGED
data/lib/mast/cli.rb
CHANGED
@@ -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
|
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
|
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
|
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
|
-
#
|
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',
|
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
|
-
|
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
|
-
#
|
217
|
-
def show
|
218
|
-
|
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
|
-
|
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
|
-
|
339
|
+
report "#{file} updated."
|
316
340
|
else
|
317
|
-
|
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
|
-
#
|
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
|
-
|
388
|
+
report "No manifest file."
|
365
389
|
end
|
366
390
|
|
367
391
|
# Report action cancelled.
|
368
392
|
def report_cancelled(action)
|
369
|
-
|
393
|
+
report "#{action} cancelled."
|
370
394
|
end
|
371
395
|
|
372
396
|
# Report manifest overwrite.
|
373
397
|
def report_overwrite(manifest)
|
374
|
-
|
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
|
-
|
403
|
+
report "Shadowing #{manifest.file}."
|
380
404
|
end
|
381
405
|
|
382
406
|
#
|
383
407
|
def report_verify(check)
|
384
408
|
if check
|
385
|
-
|
409
|
+
report "Manifest if good."
|
386
410
|
else
|
387
|
-
|
411
|
+
report "Manifest if bad!"
|
388
412
|
end
|
389
413
|
end
|
390
414
|
end
|
data/lib/mast/manifest.rb
CHANGED
@@ -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
|
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
|
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
|
-
|
214
|
-
|
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
|
-
|
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
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
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
|