mast 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/mast/manifest.rb CHANGED
@@ -71,9 +71,8 @@ module Mast
71
71
  # Include directories.
72
72
  attr_accessor :dir
73
73
 
74
- # Show as if another manifest (eg. use files options).
75
- # TODO: Change name?
76
- attr_accessor :show
74
+ # Show as if another manifest (i.e. use file's bang options).
75
+ attr_accessor :bang
77
76
 
78
77
  # What files to include. Defaults to ['*'].
79
78
  # Note that Mast automatically recurses through
@@ -100,7 +99,7 @@ module Mast
100
99
  alias_method :dir?, :dir
101
100
 
102
101
  #
103
- alias_method :show?, :show
102
+ alias_method :bang?, :bang
104
103
 
105
104
  # New Manifest object.
106
105
  #
@@ -111,7 +110,7 @@ module Mast
111
110
  @format = 'csf'
112
111
  @all = false
113
112
  @dir = false
114
- @show = false
113
+ @bang = false
115
114
  @digest = nil
116
115
  @directory = Dir.pwd
117
116
 
@@ -155,6 +154,15 @@ module Mast
155
154
  @read
156
155
  end
157
156
 
157
+ # Is the current mainfest in need of updating?
158
+ def changed?
159
+ raise NoManifestError unless file and FileTest.file?(file)
160
+ txt = File.read(file)
161
+ out = StringIO.new #('', 'w')
162
+ generate(out)
163
+ out.string != txt
164
+ end
165
+
158
166
  # Create a digest/manifest file. This saves the list of files
159
167
  # and optionally their checksum.
160
168
  #def create(options=nil)
@@ -166,7 +174,7 @@ module Mast
166
174
 
167
175
  # Generate manifest.
168
176
  def generate(out=$stdout)
169
- parse_topline unless read? if show?
177
+ parse_topline unless read? if bang?
170
178
  out << topline_string
171
179
  output(out)
172
180
  end
@@ -433,7 +441,9 @@ module Mast
433
441
  def checksum(file, digest=nil)
434
442
  return nil unless digest
435
443
  if FileTest.directory?(file)
436
- @null_string ||= digester(digest).hexdigest("")
444
+ #@null_string ||= digester(digest).hexdigest("")
445
+ listing = (Dir.entries(file) - %w{. ..}).join("\n")
446
+ digester(digest).hexdigest(listing)
437
447
  else
438
448
  digester(digest).hexdigest(File.read(file))
439
449
  end
@@ -515,20 +525,27 @@ module Mast
515
525
  [ '-i', '--ignore' , GetoptLong::REQUIRED_ARGUMENT ],
516
526
  [ '-a', '--all' , GetoptLong::NO_ARGUMENT ]
517
527
  )
518
- a, d, x, i = false, nil, [], []
528
+ a, d, g, x, i = false, false, nil, [], []
519
529
  opts.each do |opt, arg|
520
530
  case opt
521
- when '-g': d = arg.downcase
522
- when '-a': a = true
523
- when '-x': x << arg
524
- when '-i': i << arg
531
+ when '-g'
532
+ g = arg.downcase
533
+ when '-a'
534
+ a = true
535
+ when '-x'
536
+ x << arg
537
+ when '-i'
538
+ i << arg
539
+ when '-d'
540
+ d = true
525
541
  end
526
542
  end
527
543
 
528
544
  @all = a
529
- @digest = d
545
+ @digest = g
530
546
  @exclude = x
531
547
  @ignore = i
548
+ @dir = d
532
549
  @include = ARGV.empty? ? nil : ARGV.dup
533
550
  end
534
551
  end
@@ -560,6 +577,7 @@ module Mast
560
577
  #end
561
578
  top = []
562
579
  top << "-a" if all?
580
+ top << "-d" if dir?
563
581
  top << "-g #{digest.to_s.downcase}" if digest
564
582
  exclude.each do |e|
565
583
  top << "-x #{e}"
@@ -0,0 +1,25 @@
1
+ module Mast
2
+
3
+ def self.package
4
+ @package ||= (
5
+ require 'yaml'
6
+ YAML.load(File.new(File.dirname(__FILE__) + '/package'))
7
+ )
8
+ end
9
+
10
+ def self.profile
11
+ @profile ||= (
12
+ require 'yaml'
13
+ YAML.load(File.new(File.dirname(__FILE__) + '/profile'))
14
+ )
15
+ end
16
+
17
+ def self.const_missing(name)
18
+ key = name.to_s.downcase
19
+ package[key] || profile[key] || super(name)
20
+ end
21
+
22
+ end
23
+
24
+ # becuase Ruby 1.8~ gets in the way
25
+ Object.__send__(:remove_const, :VERSION) if Object.const_defined?(:VERSION)
@@ -0,0 +1,8 @@
1
+ name : mast
2
+ date : 2010-11-21
3
+ version : 1.3.0
4
+
5
+ requires:
6
+ - syckle (build)
7
+ - qed (test)
8
+
@@ -0,0 +1,21 @@
1
+ ---
2
+ title : Mast
3
+ suite : proutils
4
+ contact: proutils@googlegroups.com
5
+ summary: Mast is a command line tool for generating manifests and digests.
6
+
7
+ authors:
8
+ - Thomas Sawyer
9
+
10
+ description:
11
+ Mast is a command line tool for generating manifests and digests.
12
+ Mast makes it easy to compare a manifest to a current directory structure,
13
+ and to update the manifest with a simple command by storing the command
14
+ option it the manifest file itself.
15
+
16
+ resources:
17
+ homepage: http://proutils.github.com/mast
18
+ repository: git://github.com/proutils/mast.git
19
+ wiki: http://wiki.github.com/proutils/mast/
20
+ download: http://github.com/proutils/mast/downloads
21
+
@@ -4,12 +4,15 @@ module Syckle::Plugins
4
4
  #
5
5
  class Mast < Service
6
6
 
7
- precycle :main, :package => :generate
7
+ # Pre-package phase.
8
+ precycle :main, :package do
9
+ generate
10
+ end
8
11
 
9
12
  cycle :main, :reset
10
13
  cycle :main, :clean
11
14
 
12
- # not that this is necessary, but ...
15
+ # Not that this is necessary, but ...
13
16
  available do |project|
14
17
  begin
15
18
  require 'mast'
@@ -23,14 +26,14 @@ module Syckle::Plugins
23
26
  DEFAULT_FILENAME = 'MANIFEST'
24
27
 
25
28
  # Default files/dirs to include.
26
- DEFAULT_INCLUDE = %w{ bin lib meta script test [A-Z]* }
29
+ DEFAULT_INCLUDE = %w{ bin data etc features lib man meta qed script spec test [A-Z]* }
27
30
 
28
31
  # Default files/dirs to exclude.
29
- DEFAULT_EXCLUDE = %w{ }
32
+ DEFAULT_EXCLUDE = nil #%w{}
30
33
 
31
34
  # Default files/dirs to ignore. Unlike exclude, this work
32
- # on files basenames, and not full pathnames.
33
- DEFAULT_IGNORE = %w{ .svn }
35
+ # on path basenames, and not full pathnames.
36
+ DEFAULT_IGNORE = nil #%w{}
34
37
 
35
38
  #
36
39
  attr_accessor :include
@@ -51,13 +54,19 @@ module Syckle::Plugins
51
54
 
52
55
  #
53
56
  def manifest
54
- @manifest ||= Manifest.new(options)
57
+ @manifest ||= ::Mast::Manifest.new(options)
55
58
  end
56
59
 
57
60
  # Generate manifest.
61
+ # TODO: don't overwrite if it hasn't changed
58
62
  def generate
59
- manifest.generate
60
- report "Updated #{output.to_s.sub(Dir.pwd+'/','')}"
63
+ if manifest.changed?
64
+ file = manifest.save #update #generate
65
+ report "Updated #{file.to_s.sub(Dir.pwd+'/','')}"
66
+ #report "Updated #{output.to_s.sub(Dir.pwd+'/','')}"
67
+ else
68
+ report "#{output.to_s.sub(Dir.pwd+'/','')} is current"
69
+ end
61
70
  end
62
71
 
63
72
  # Mark MANIFEST as out-of-date.
@@ -66,7 +75,7 @@ module Syckle::Plugins
66
75
  end
67
76
 
68
77
  # Remove MANIFEST.
69
- # TODO: Currently a noop. Not sure removing manfest is a good idea.
78
+ # TODO: Currently a noop. Not sure removing manfest is ever a good idea.
70
79
  def clean
71
80
  end
72
81
 
data/man/man1/mast.1 ADDED
@@ -0,0 +1,97 @@
1
+ .\" generated with Ronn/v0.7.3
2
+ .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
+ .
4
+ .TH "MAST" "1" "November 2010" "RubyWorks" "Mast"
5
+ .
6
+ .SH "NAME"
7
+ \fBmast\fR \- manifest generator
8
+ .
9
+ .SH "SYNOPSIS"
10
+ \fBmast [<command>] [<options>\.\.\.]\fR
11
+ .
12
+ .SH "DESCRIPTION"
13
+ The manifest listing tool is used to list, create or update a manifest for a directory (eg\. to define a "package"), or compare a manifest to actual directory contents\. Mast is part of the ProUtils set of tools\.
14
+ .
15
+ .P
16
+ When no command is given, a manifest is dumped to standard out\. If \-\-file is specified, it will generate to that file instead\.
17
+ .
18
+ .SH "COMMANDS"
19
+ .
20
+ .TP
21
+ \fB\-c\fR, \fB\-\-create\fR
22
+ Generate a new manifest\. (default)
23
+ .
24
+ .TP
25
+ \fB\-u\fR, \fB\-\-update\fR
26
+ Update an existing manifest\.
27
+ .
28
+ .TP
29
+ \fB\-l\fR, \fB\-\-list\fR
30
+ List the files given in the manifest file\. (Use \-f to specify an alternate file\.)
31
+ .
32
+ .TP
33
+ \fB\-D\fR, \fB\-\-diff\fR
34
+ Diff manifest file against actual\.
35
+ .
36
+ .TP
37
+ \fB\-n\fR, \fB\-\-new\fR
38
+ List existant files that are not given in the manifest\.
39
+ .
40
+ .TP
41
+ \fB\-o\fR, \fB\-\-old\fR
42
+ List files given in the manifest but are non\-existent\.
43
+ .
44
+ .TP
45
+ \fB\-v\fR, \fB\-\-verify\fR
46
+ Verify that a manifest matches actual\.
47
+ .
48
+ .TP
49
+ \fB\-\-clean\fR
50
+ Remove non\-manifest files\. (Will ask for confirmation first\.)
51
+ .
52
+ .TP
53
+ \fB\-h\fR, \fB\-\-help\fR
54
+ Display this help message\.
55
+ .
56
+ .SH "OPTIONS"
57
+ .
58
+ .TP
59
+ \fB\-a\fR, \fB\-\-all\fR
60
+ Include all files\. This deactivates deafult exclusions so it is possible to make complete list of all contents\.
61
+ .
62
+ .TP
63
+ \fB\-d\fR, \fB\-\-dir\fR
64
+ When creating a list include directory paths; by default only files are listed\.
65
+ .
66
+ .TP
67
+ \fB\-b\fR, \fB\-\-bang\fR
68
+ Generate manifest using the options from the bang line of the manifest file\.
69
+ .
70
+ .TP
71
+ \fB\-f\fR, \fB\-\-file PATH\fR
72
+ Path to manifest file\. This applies to comparison commands\. If not given then the file matching \'MANIFEST\', case\-insensitive and with an optional \'\.txt\' extension, in the current directory is used\. If the path of the manifest file is anything else then the \-\-file option must be specified\.
73
+ .
74
+ .TP
75
+ \fB\-g\fR, \fB\-\-digest TYPE\fR
76
+ Include crytographic signiture\. Type can be either md5, sha1, sha128, sha256, or sha512\.
77
+ .
78
+ .TP
79
+ \fB\-x\fR, \fB\-\-exclude PATH\fR
80
+ Exclude a file or dir from the manifest matching against full pathname\. You can use \-\-exclude repeatedly\.
81
+ .
82
+ .TP
83
+ \fB\-i\fR, \fB\-\-ignore PATH\fR
84
+ Exclude a file or dir from the manifest matching against an entries basename\. You can use \-\-ignore repeatedly\.
85
+ .
86
+ .TP
87
+ \fB\-q\fR, \fB\-\-quiet\fR
88
+ Suppress any extraneous output\.
89
+ .
90
+ .SH "EXAMPLES"
91
+ \fBmast\fR
92
+ .
93
+ .br
94
+ \fBmast \-u \-f PUBLISH\fR
95
+ .
96
+ .SH "SEE ALSO"
97
+ ls(1)
data/meta/data.rb ADDED
@@ -0,0 +1,25 @@
1
+ module Mast
2
+
3
+ def self.package
4
+ @package ||= (
5
+ require 'yaml'
6
+ YAML.load(File.new(File.dirname(__FILE__) + '/package'))
7
+ )
8
+ end
9
+
10
+ def self.profile
11
+ @profile ||= (
12
+ require 'yaml'
13
+ YAML.load(File.new(File.dirname(__FILE__) + '/profile'))
14
+ )
15
+ end
16
+
17
+ def self.const_missing(name)
18
+ key = name.to_s.downcase
19
+ package[key] || profile[key] || super(name)
20
+ end
21
+
22
+ end
23
+
24
+ # becuase Ruby 1.8~ gets in the way
25
+ Object.__send__(:remove_const, :VERSION) if Object.const_defined?(:VERSION)
data/meta/package ADDED
@@ -0,0 +1,8 @@
1
+ name : mast
2
+ date : 2010-11-21
3
+ version : 1.3.0
4
+
5
+ requires:
6
+ - syckle (build)
7
+ - qed (test)
8
+
data/meta/profile ADDED
@@ -0,0 +1,21 @@
1
+ ---
2
+ title : Mast
3
+ suite : proutils
4
+ contact: proutils@googlegroups.com
5
+ summary: Mast is a command line tool for generating manifests and digests.
6
+
7
+ authors:
8
+ - Thomas Sawyer
9
+
10
+ description:
11
+ Mast is a command line tool for generating manifests and digests.
12
+ Mast makes it easy to compare a manifest to a current directory structure,
13
+ and to update the manifest with a simple command by storing the command
14
+ option it the manifest file itself.
15
+
16
+ resources:
17
+ homepage: http://proutils.github.com/mast
18
+ repository: git://github.com/proutils/mast.git
19
+ wiki: http://wiki.github.com/proutils/mast/
20
+ download: http://github.com/proutils/mast/downloads
21
+
@@ -0,0 +1,60 @@
1
+ require 'fileutils'
2
+ require 'open3'
3
+
4
+ def assert_bash(text)
5
+ lines = text.lines.to_a
6
+ bash = lines[0]
7
+ result = lines[1..-1].join.strip
8
+
9
+ bash.sub!('$', '')
10
+
11
+ stdin, stdout, stderr = Open3.popen3(bash)
12
+
13
+ output = (stderr.read + stdout.read).strip
14
+
15
+ result.assert == output
16
+ end
17
+
18
+ Before :demo do
19
+ if /tmp\/qed$/ =~ Dir.pwd
20
+ Dir['*'].each do |file|
21
+ FileUtils.rm_r(file)
22
+ end
23
+ end
24
+ end
25
+
26
+ When "Let say we have a directory containing a set of files as follows" do |text|
27
+ text.lines.each do |line|
28
+ file = line.strip
29
+ FileUtils.mkdir_p(File.dirname(file))
30
+ File.open(file, 'w') do |f|
31
+ f << file
32
+ end
33
+ end
34
+ end
35
+
36
+ When "let's say we have a new file" do |text|
37
+ text.lines.each do |line|
38
+ file = line.strip
39
+ FileUtils.mkdir_p(File.dirname(file))
40
+ File.open(file, 'w') do |f|
41
+ f << file
42
+ end
43
+ end
44
+ end
45
+
46
+ When "let's remove a file" do |text|
47
+ text.lines.each do |line|
48
+ file = line.strip
49
+ FileUtils.rm(file)
50
+ end
51
+ end
52
+
53
+ When :data do |step|
54
+ text = step.sample_text
55
+ if text.start_with?('$')
56
+ assert_bash(text)
57
+ end
58
+ end
59
+
60
+