gravitext-devtools 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.rdoc ADDED
@@ -0,0 +1,2 @@
1
+ === 1.0.0 (2010-4-21)
2
+ * Initial release.
data/Manifest.txt ADDED
@@ -0,0 +1,18 @@
1
+ History.rdoc
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ bin/gt-cleanws
6
+ bin/gt-header
7
+ bin/gt-manifest
8
+ lib/gravitext-devtools/base.rb
9
+ lib/gravitext-devtools.rb
10
+ lib/gravitext-devtools/header_writer.rb
11
+ lib/gravitext-devtools/manifest_writer.rb
12
+ templates/format/format.java
13
+ templates/format/format.rb
14
+ templates/format/format.txt
15
+ templates/format/format.xml
16
+ templates/license/apache
17
+ templates/license/bsd
18
+ templates/license/mit
data/README.rdoc ADDED
@@ -0,0 +1,31 @@
1
+ = gravitext-devtools
2
+
3
+ * http://github.com/dekellum/gravitext-devtools
4
+
5
+ == Description
6
+
7
+ A collection of development support tools.
8
+
9
+ gt-manifest:: Maintain manifest from git ls-files minus exclusions.
10
+ gt-cleanws:: Cleanup whitespace in files.
11
+ gt-header:: Add and maintain file license headers.
12
+
13
+ == Synopsis
14
+
15
+ [TBD]
16
+
17
+ == License
18
+
19
+ Copyright (c) 2008-2010 David Kellum
20
+
21
+ Licensed under the Apache License, Version 2.0 (the "License"); you
22
+ may not use this file except in compliance with the License. You
23
+ may obtain a copy of the License at:
24
+
25
+ http://www.apache.org/licenses/LICENSE-2.0
26
+
27
+ Unless required by applicable law or agreed to in writing, software
28
+ distributed under the License is distributed on an "AS IS" BASIS,
29
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
30
+ implied. See the License for the specific language governing
31
+ permissions and limitations under the License.
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ # -*- ruby -*-
2
+
3
+ $LOAD_PATH << './lib'
4
+ require 'gravitext-devtools/base'
5
+
6
+ require 'rubygems'
7
+ gem 'rjack-tarpit', '~> 1.2.1'
8
+ require 'rjack-tarpit'
9
+
10
+ t = RJack::TarPit.new( 'gravitext-devtools', Gravitext::DevTools::VERSION )
11
+
12
+ t.specify do |h|
13
+ h.developer( 'David Kellum', 'dek-oss@gravitext.com' )
14
+ end
15
+
16
+ task :check_history_version do
17
+ t.test_line_match( 'History.rdoc', /^==/, / #{ t.version } / )
18
+ end
19
+ task :check_history_date do
20
+ t.test_line_match( 'History.rdoc', /^==/, /\([0-9\-]+\)$/ )
21
+ end
22
+
23
+ task :gem => [ :check_history_version, ]
24
+ task :tag => [ :check_history_version, :check_history_date ]
25
+ task :push => [ :check_history_version, :check_history_date ]
26
+
27
+ task :test #noop
28
+
29
+ t.define_tasks
data/bin/gt-cleanws ADDED
@@ -0,0 +1,227 @@
1
+ #!/usr/bin/ruby
2
+ #--
3
+ # Copyright (c) 2008-2010 David Kellum
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
6
+ # may not use this file except in compliance with the License. You may
7
+ # obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14
+ # implied. See the License for the specific language governing
15
+ # permissions and limitations under the License.
16
+ #++
17
+
18
+ require 'fileutils'
19
+ require 'optparse'
20
+ require 'stringio'
21
+
22
+ require 'rubygems'
23
+ require 'rainbow'
24
+
25
+ class CleanWS
26
+ include FileUtils
27
+
28
+ class NullIO
29
+ def puts(*a)
30
+ end
31
+ end
32
+
33
+ CMAP = {}
34
+
35
+ def self.mk_tag( name, color )
36
+ tag = name.foreground( color )
37
+ CMAP[ tag ] = color
38
+ tag
39
+ end
40
+
41
+ CLEAN = mk_tag( "CLEAN", :green )
42
+ DIRTY = mk_tag( "DIRTY", :red )
43
+ WROTE = mk_tag( "WROTE", :red )
44
+ FIXED = mk_tag( "FIXED", :yellow )
45
+ NOTXT = mk_tag( "NOTXT", :blue )
46
+
47
+ def initialize
48
+ @do_write = false
49
+ @verbose = false
50
+ @show_clean = true
51
+ @fout = NullIO.new
52
+ @git_ls = false
53
+ @log = $stdout
54
+ @llines = 0
55
+ end
56
+
57
+ def parse_flags( args )
58
+ opts = OptionParser.new do |opts|
59
+ opts.banner = "Usage: cleanws [-w | -t] file ..."
60
+ opts.on( "-w", "--write", "Update file in place") do
61
+ @do_write = true
62
+ end
63
+ opts.on( "-v", "--verbose",
64
+ "Output filtered files and verbose logging.") do
65
+ @fout = $stdout
66
+ log = $stderr
67
+ @verbose = true
68
+ end
69
+ opts.on( "-d", "--dirty", "Show dirty status only.") do
70
+ @show_clean = false
71
+ end
72
+ opts.on( "-g", "--git-updates",
73
+ "Get input files from modified/untracked git working tree" ) do
74
+ @git_ls = "-m -o --exclude-standard"
75
+ end
76
+ opts.on( "-G", "--git-cached",
77
+ "Get input files from tracked/cached git files" ) do
78
+ @git_ls = "-c"
79
+ end
80
+ end
81
+ opts.parse!( args )
82
+ end
83
+
84
+ def main( args )
85
+
86
+ parse_flags( args )
87
+
88
+ if @git_ls
89
+ gcmd = [ 'git ls-files', @git_ls, args ].flatten.join(' ')
90
+ @log.puts gcmd if @verbose
91
+ args = IO.popen( gcmd ).readlines.map { |f| f.strip }
92
+ args.reject! { |f| f =~ /\.ws(~|\.tmp)$/ }
93
+ end
94
+
95
+ args.sort!
96
+
97
+ ftypes = check_file_types( args )
98
+
99
+ any_dirty = false
100
+
101
+ ftypes.each do |ifile, type|
102
+ d = process( ifile, type )
103
+ any_dirty ||= d
104
+ end
105
+
106
+ header if @llines > 20
107
+ exit( any_dirty ? 1 : 0 )
108
+ end
109
+
110
+ def check_file_types( files )
111
+ fmap = {}
112
+ # 1: keep only regular files in fmap
113
+ files.each do |f|
114
+ if File.file?( f ) && ! File.symlink?( f )
115
+ fmap[f] = :file
116
+ end
117
+ end
118
+
119
+ # 2: Use UNIX 'file' command to test for text files
120
+ unless fmap.empty?
121
+ IO.popen( "file " + fmap.keys.join( ' ' ) ) do |outf|
122
+ outf.each do |line|
123
+ # <filename>: <type string with /text/ or not>
124
+ if line =~ /^(.+):(.+)$/
125
+ fmap[ $1 ] = ( ( $2 =~ /text/ ) ? :text : :binary )
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ fmap.sort
132
+ end
133
+
134
+ def header
135
+ @log.puts( "%5s %4s %4s %4s %4s %s" %
136
+ [ "", "WS", "BLNK", "TABS", "LINE", "FILE" ] )
137
+ end
138
+
139
+ def process( ifile, type )
140
+ @log.puts( "CLEAN f: #{ifile} :::" ) if @verbose
141
+
142
+ ofile = nil
143
+
144
+ chg, blank, tabs, total =
145
+ if type == :text
146
+ ofile = ifile + ".ws.tmp"
147
+
148
+ fout = @do_write ? open( ofile, 'w' ) : @fout
149
+
150
+ result = open( ifile, 'r' ) do |fin|
151
+ filter( fin, fout )
152
+ end
153
+
154
+ fout.close if @do_write
155
+ result
156
+ else
157
+ [0,0,0,0]
158
+ end
159
+
160
+ change = ( ( chg + blank ) > 0 )
161
+ dirty = change || ( tabs > 0 )
162
+
163
+ state = if dirty
164
+ if @do_write
165
+ ( tabs == 0 ) ? FIXED : WROTE
166
+ else
167
+ DIRTY
168
+ end
169
+ else
170
+ ( type == :text ) ? CLEAN : NOTXT
171
+ end
172
+
173
+ if dirty || @show_clean
174
+ header if @llines == 0
175
+ @log.puts( "%s %4d %4d %4d %4d %s" %
176
+ [ state, chg, blank, tabs, total,
177
+ ifile.dup.foreground( CMAP[ state ] ) ] )
178
+ @llines += 1
179
+ end
180
+
181
+ if @do_write && ofile
182
+ if change
183
+ cp( ifile, ifile + ".ws~", :preserve => true )
184
+ cp( ofile, ifile )
185
+ end
186
+ rm( ofile )
187
+ end
188
+ dirty
189
+ end
190
+
191
+ # Filters files fin to fout
192
+ # All whitespace at end of line is replaced with '\n'
193
+ # Only one blank line allowed consecutively.
194
+ # Last non-empty line is terminated with '\n'
195
+ # No trailing additional lines in file.
196
+ def filter( fin, fout )
197
+ dropped_lines = 0
198
+ changed_lines = 0
199
+ tab_lines = 0
200
+ empty_lines = 0
201
+ total = 0
202
+ while( line = fin.gets )
203
+ total += 1
204
+ lstr = line.rstrip
205
+
206
+ changed_lines += 1 if ( line != ( lstr + "\n" ) )
207
+
208
+ if lstr.empty?
209
+ empty_lines += 1
210
+ else
211
+ if empty_lines > 0
212
+ fout.puts
213
+ dropped_lines += empty_lines - 1
214
+ empty_lines = 0
215
+ end
216
+ tab_lines += 1 if lstr =~ /\t/
217
+ # line.gsub!( /\t/, " " )
218
+ fout.puts lstr
219
+ end
220
+ end
221
+ dropped_lines += empty_lines
222
+ [ changed_lines, dropped_lines, tab_lines, total ]
223
+ end
224
+
225
+ end
226
+
227
+ CleanWS.new.main( ARGV )
data/bin/gt-header ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/ruby
2
+ #--
3
+ # Copyright (c) 2008-2010 David Kellum
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
6
+ # may not use this file except in compliance with the License. You may
7
+ # obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14
+ # implied. See the License for the specific language governing
15
+ # permissions and limitations under the License.
16
+ #++
17
+
18
+ $LOAD_PATH.unshift File.join( File.dirname( __FILE__ ), "..", "lib" )
19
+
20
+ require 'gravitext-devtools/header_writer'
21
+
22
+ Gravitext::DevTools::HeaderWriter.new.run
data/bin/gt-manifest ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/ruby
2
+ #--
3
+ # Copyright (c) 2008-2010 David Kellum
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
6
+ # may not use this file except in compliance with the License. You may
7
+ # obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14
+ # implied. See the License for the specific language governing
15
+ # permissions and limitations under the License.
16
+ #++
17
+
18
+ $LOAD_PATH.unshift File.join( File.dirname( __FILE__ ), "..", "lib" )
19
+
20
+ require 'gravitext-devtools/manifest_writer'
21
+
22
+ Gravitext::DevTools::ManifestWriter.new.run
@@ -0,0 +1,131 @@
1
+ #--
2
+ # Copyright (c) 2008-2010 David Kellum
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
5
+ # may not use this file except in compliance with the License. You may
6
+ # obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
+ # implied. See the License for the specific language governing
14
+ # permissions and limitations under the License.
15
+ #++
16
+
17
+ require 'gravitext-devtools/base.rb'
18
+ require 'optparse'
19
+
20
+ module Gravitext
21
+ module DevTools
22
+
23
+ def self.configure
24
+ yield Gravitext::DevTools::Config
25
+ end
26
+
27
+ def self.load_config_from_pwd
28
+ count = 0
29
+ pwd = File.expand_path( Dir.pwd )
30
+ while( File.directory?( pwd ) )
31
+ cfile = File.join( pwd, '.gt-config' )
32
+ if File.exist?( cfile )
33
+ Config::load_config( cfile )
34
+ break
35
+ end
36
+ break if File.exist?( File.join( pwd, '.git' ) )
37
+ pwd = File.dirname( pwd )
38
+ break if ( count += 1 ) > 4
39
+ break if pwd == '/'
40
+ end
41
+ end
42
+
43
+ module Config
44
+
45
+ def self.load_config( file )
46
+ puts "Loading config #{file}."
47
+ load file
48
+ end
49
+
50
+ def self.method_missing( method, *arguments, &block )
51
+ ccall = caller[0]
52
+ puts "Method %s from %s not defined, ignored" % [ method, ccall ]
53
+ end
54
+ end
55
+
56
+ class GitFileLister
57
+
58
+ # Exclusions to the list expressed in various ways
59
+ # Array<Regexp|Proc|String>
60
+ attr_accessor :exclusions
61
+
62
+ # Flags for use in call to git ls-files
63
+ # Array<~to_s>
64
+ attr_accessor :git_flags
65
+
66
+ # Additional files to add to files list
67
+ # Array<~to_s>
68
+ attr_accessor :extra_files
69
+
70
+ def initialize
71
+ @args = []
72
+ @files = nil
73
+ @exclusions = [ %r{(^|/).gitignore$}, # gt-manifest, gt-header
74
+ %r{(^|/).gt-config$}, # gt-manifest, (gt-header)
75
+ %r{(^|/)src(/|$)}, # gt-manifest
76
+ 'lib/**/*.jar', # all
77
+ 'Manifest.static' ] # gt-manifest, gt-header
78
+ @git_flags = []
79
+ @extra_files = []
80
+ end
81
+
82
+ def parse_options( args = ARGV, &block )
83
+ opts = OptionParser.new do |opts|
84
+ opts.on( "-g", "--git-updates",
85
+ "Include files from modified/untracked git working tree" ) do
86
+ @git_flags += %w[ -m -o --exclude-standard ]
87
+ end
88
+ block.call( opts ) if block
89
+ end
90
+ @args = opts.parse( args )
91
+ end
92
+
93
+ def files
94
+ @files ||= generate_list
95
+ end
96
+
97
+ def generate_list( args = @args )
98
+
99
+ files, dirs = args.partition { |a| File.file?( a ) }
100
+
101
+ if files.empty? || ! dirs.empty?
102
+ gcmd = [ 'git', 'ls-files', @git_flags, dirs ].flatten.compact.join( ' ' )
103
+ files += IO.popen( gcmd ) { |inp| inp.readlines }
104
+ end
105
+
106
+ files += extra_files
107
+
108
+ files.map! { |f| f.strip }
109
+ files.uniq!
110
+ files.reject { |f| exclude?( f ) }
111
+ end
112
+
113
+ def exclude?( fname )
114
+ @exclusions.any? do |ex|
115
+ case ex
116
+ when Proc
117
+ ex.call( fname )
118
+ when Regexp
119
+ fname =~ ex
120
+ when /[*?]/
121
+ File.fnmatch?( ex, fname, File::FNM_PATHNAME )
122
+ else
123
+ fname == ex
124
+ end
125
+ end
126
+ end
127
+
128
+ end
129
+
130
+ end
131
+ end
@@ -0,0 +1,21 @@
1
+ #--
2
+ # Copyright (c) 2008-2010 David Kellum
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
5
+ # may not use this file except in compliance with the License. You may
6
+ # obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
+ # implied. See the License for the specific language governing
14
+ # permissions and limitations under the License.
15
+ #++
16
+
17
+ module Gravitext
18
+ module DevTools
19
+ VERSION = "1.0.0"
20
+ end
21
+ end
@@ -0,0 +1,298 @@
1
+ #--
2
+ # Copyright (c) 2008-2010 David Kellum
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
5
+ # may not use this file except in compliance with the License. You may
6
+ # obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
+ # implied. See the License for the specific language governing
14
+ # permissions and limitations under the License.
15
+ #++
16
+
17
+ require 'gravitext-devtools'
18
+ require 'fileutils'
19
+ require 'erb'
20
+ require 'rubygems'
21
+ require 'rainbow'
22
+
23
+ module Gravitext
24
+ module DevTools
25
+
26
+ module Config
27
+ def self.header
28
+ hw = HeaderWriter.instance
29
+ raise "HeaderWriter not initialized" unless hw
30
+ yield hw
31
+ end
32
+ end
33
+
34
+ class HeaderWriter
35
+ include FileUtils
36
+
37
+ attr_accessor :verbose
38
+ attr_accessor :holder
39
+ attr_accessor :inception
40
+ attr_accessor :license
41
+ attr_accessor :exclusions
42
+
43
+ class << self
44
+ attr_accessor :instance
45
+ end
46
+
47
+ def initialize
48
+ @verbose = false
49
+ @do_write = false
50
+ @license = :apache
51
+ @inception = Time.now.year
52
+
53
+ @git_lister = GitFileLister.new
54
+
55
+ @exclusions = [ '**/.gitignore',
56
+ '**/.gt-config',
57
+ '**/History.rdoc',
58
+ '**/History.txt',
59
+ '**/Manifest.static',
60
+ '**/Manifest.txt',
61
+ '**/*.jar',
62
+ '**/Rakefile',
63
+ '**/pom.xml',
64
+ '**/assembly.xml']
65
+
66
+ @cached_header = {}
67
+
68
+ HeaderWriter.instance = self # The last created
69
+ end
70
+
71
+ def parse_options( args = ARGV )
72
+
73
+ @git_lister.parse_options( args ) do |opts|
74
+ opts.banner = "Usage: gt-manifest [dir|file] ..."
75
+ opts.on( "-v", "--verbose",
76
+ "Output full manifest details" ) do
77
+ @verbose = true
78
+ end
79
+ opts.on( "-w", "--write",
80
+ "Write headers if needed" ) do
81
+ @do_write = true
82
+ end
83
+
84
+ end
85
+ end
86
+
87
+ def run( args = ARGV )
88
+
89
+ parse_options( args )
90
+
91
+ Gravitext::DevTools.load_config_from_pwd
92
+
93
+ @git_lister.exclusions = @exclusions
94
+ # puts @exclusions.inspect
95
+
96
+ files = @git_lister.files
97
+
98
+ # puts cached_header( :rb )
99
+ # exit
100
+
101
+ files.each do |fname|
102
+ HeaderProcessor.new( fname, @do_write ).process
103
+ end
104
+ end
105
+
106
+ TDIR = File.expand_path( File.join( File.dirname( __FILE__ ),
107
+ '..', '..', 'templates' ) )
108
+
109
+ def cached_header( format )
110
+ @cached_header[ format ] ||= gen_header( format )
111
+ end
112
+
113
+ def gen_header( format )
114
+ efile = File.join( TDIR, 'format', "format.#{format}" )
115
+ license = cached_license
116
+ expand( IO.read( efile ), binding )
117
+ end
118
+
119
+ def cached_license
120
+ @cached_license ||= gen_license
121
+ end
122
+
123
+ def gen_license
124
+ template = if license.is_a?( Symbol )
125
+ IO.read( File.join( TDIR, 'license', license.to_s ) )
126
+ else
127
+ license.to_s
128
+ end
129
+ expand( template, binding )
130
+ end
131
+
132
+ def expand( template, bnd )
133
+ ERB.new( template, nil, '%' ).result( bnd ).map { |l| l.rstrip }
134
+ end
135
+
136
+ def years
137
+ @years ||= [ inception, Time.now.year ].uniq.join( '-' )
138
+ end
139
+ end
140
+
141
+ class HeaderProcessor
142
+
143
+ CMAP = {}
144
+
145
+ def self.mk_tag( name, color )
146
+ tag = name.foreground( color )
147
+ CMAP[ tag ] = color
148
+ tag
149
+ end
150
+
151
+ GOOD = mk_tag( "GOOD ", :green )
152
+ NONE = mk_tag( "NONE ", :red )
153
+ DATE = mk_tag( "DATE ", :cyan )
154
+ EMPTY = mk_tag( "EMPTY", :yellow )
155
+ WROTE = mk_tag( "WROTE", :yellow )
156
+
157
+ def initialize( fname, do_write = false )
158
+ @cpos = 0
159
+ @do_write = do_write
160
+ @fname = fname
161
+ @format = case fname
162
+ when /\.java$/
163
+ :java
164
+ when /\.xml$/
165
+ :xml
166
+ when /\.rb$/
167
+ :rb
168
+ else
169
+ :txt
170
+ end
171
+ @state = :first
172
+ @writer = HeaderWriter.instance
173
+ end
174
+
175
+ def process
176
+ state = GOOD
177
+ @lines = IO.readlines( @fname )
178
+ if @lines.empty?
179
+ state = EMPTY
180
+ else
181
+ scan_prolog
182
+ if find_copyright
183
+ if !check_copyright
184
+ if @do_write
185
+ rewrite_file
186
+ state = WROTE
187
+ else
188
+ state = DATE
189
+ end
190
+ end
191
+ else
192
+ if @do_write
193
+ insert_header
194
+ rewrite_file
195
+ state = WROTE
196
+ else
197
+ state = NONE
198
+ end
199
+ end
200
+ end
201
+ puts( "%s %s" %
202
+ [ state, @fname.dup.foreground( CMAP[ state ] ) ] )
203
+ end
204
+
205
+ def rewrite_file
206
+ open( @fname, "w" ) { |fout| fout.puts( @lines ) }
207
+ end
208
+
209
+ def scan_prolog
210
+
211
+ if @lines[0] =~ /^#\!([^\s]+)/
212
+ @format = :rb if $1 =~ /ruby$/
213
+ @cpos = 1
214
+ end
215
+
216
+ if @lines[0] =~ /^<\?xml/
217
+ @format = :xml
218
+ @cpos = 1
219
+ end
220
+
221
+ @lines.each_index do |i|
222
+ line = @lines[i]
223
+ if line =~ /^#.*-\*-\s*ruby\s*-\*-/
224
+ @format = :rb
225
+ @cpos = i+1
226
+ break
227
+ else
228
+ break if line !~ /^\s*#/
229
+ end
230
+ end
231
+
232
+ end
233
+
234
+ def find_copyright
235
+ @cline = nil
236
+ @lines.each_index do |i|
237
+ line = @lines[i]
238
+ case @format
239
+ when :rb
240
+ case line
241
+ when /^#\s+Copyright/
242
+ @cline = i
243
+ break
244
+ when /^\s*$/
245
+ when /^\s*[^#]/
246
+ break
247
+ end
248
+ when :java
249
+ case line
250
+ when /^\s*\*\s+Copyright/
251
+ @cline = i
252
+ break
253
+ when /^\s*$/
254
+ when /^\s*[^\/\*]/
255
+ break
256
+ end
257
+ else
258
+ if line =~ /Copyright \([cC]\)/
259
+ @cline = i
260
+ break
261
+ end
262
+ end
263
+ end
264
+ @cline
265
+ end
266
+
267
+ def check_copyright
268
+ passes =
269
+ if @lines[@cline] =~ /Copyright \(c\) (\d{4})(-(\d{4}))? (\S.*)\s*$/
270
+ ldate = $3 || $1 #last date
271
+ ldate && ( ldate == Time.now.year.to_s ) && ( $4 == @writer.holder )
272
+ else
273
+ false
274
+ end
275
+
276
+ unless passes
277
+ start = @lines[@cline].match( /^.*Copyright/ )
278
+ @lines[@cline] = [ start, "(c)",
279
+ @writer.years, @writer.holder ].join( ' ' )
280
+ end
281
+
282
+ passes
283
+ end
284
+
285
+ def insert_header
286
+ header = @writer.cached_header( @format )
287
+ @lines.insert( @cpos, *header )
288
+ @cpos += header.length
289
+ # Insert an extra line break if needed.
290
+ unless @lines[ @cpos ] =~ /^\s*$/ || @format == :xml
291
+ @lines.insert( @cpos, "" )
292
+ end
293
+ end
294
+
295
+ end
296
+
297
+ end
298
+ end
@@ -0,0 +1,135 @@
1
+ #--
2
+ # Copyright (c) 2008-2010 David Kellum
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
5
+ # may not use this file except in compliance with the License. You may
6
+ # obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
+ # implied. See the License for the specific language governing
14
+ # permissions and limitations under the License.
15
+ #++
16
+
17
+ require 'gravitext-devtools'
18
+ require 'fileutils'
19
+
20
+ module Gravitext
21
+ module DevTools
22
+
23
+ class ManifestWriter
24
+ include FileUtils
25
+ include Gravitext::DevTools
26
+
27
+ # Set true if Manifest.txt should be written instead of Manifest.txt.
28
+ # (Default: true if Manifest.static exists)
29
+ # Boolean
30
+ attr_accessor :static
31
+
32
+ def initialize
33
+ @verbose = false
34
+ @static = File.exist?( 'Manifest.static' )
35
+
36
+ @git_lister = GitFileLister.new
37
+
38
+ @git_lister.exclusions = [ %r{(^|/).gitignore$},
39
+ %r{(^|/).gt-config$},
40
+ %r{(^|/)src(/|$)},
41
+ 'lib/**/*.jar',
42
+ 'Manifest.static' ]
43
+ end
44
+
45
+ def parse_options( args = ARGV )
46
+
47
+ @git_lister.parse_options( args ) do |opts|
48
+ opts.banner = "Usage: gt-manifest [dir|file] ..."
49
+ opts.on( "-v", "--verbose",
50
+ "Output full manifest details" ) do
51
+ @verbose = true
52
+ end
53
+ opts.on( "-s", "--static",
54
+ "Write to Manifest.static instead of Manifest.txt" ) do
55
+ @static = true
56
+ end
57
+ end
58
+ end
59
+
60
+ def run( args = ARGV )
61
+
62
+ parse_options( args )
63
+
64
+ @git_lister.extra_files << 'Manifest.txt' unless @static
65
+ @git_lister.git_flags << '-c' # Include cached by default
66
+
67
+ files = @git_lister.files
68
+
69
+ files.map! do |f|
70
+ f = f.split( File::SEPARATOR )
71
+ f.shift if f[0] == '.'
72
+ f
73
+ end
74
+ files.uniq!
75
+ files = sort( files )
76
+ files.map! { |f| File.join( f ) }
77
+
78
+ open( 'Manifest.' + ( @static ? 'static' : 'txt' ), 'w' ) do |out|
79
+ files.each do |fname|
80
+ puts fname if @verbose
81
+ out.puts fname
82
+ end
83
+ end
84
+ end
85
+
86
+ def sort( files )
87
+
88
+ files = files.sort do |a,b|
89
+ i = 0
90
+ o = 0
91
+ while( o == 0 )
92
+ o = -1 if ( a.length == i+1 ) && a.length < b.length
93
+ o = 1 if ( b.length == i+1 ) && a.length > b.length
94
+ o = a[i] <=> b[i] if o == 0
95
+ i += 1
96
+ end
97
+ o
98
+ end
99
+
100
+ files = priority_to_base( files )
101
+
102
+ files
103
+ end
104
+
105
+ # Move up any foo/base.rb or version.rb files. By convention
106
+ # (originally based on rdoc issues) these come before a foo.rb, i.e:
107
+ #
108
+ # lib/foo/base.rb
109
+ # lib/foo.rb
110
+ # lib/foo/other.rb
111
+ #
112
+ def priority_to_base( files )
113
+
114
+ bases, nfiles = files.partition { |f| f.last =~ /^(base|version)\.rb$/ }
115
+
116
+ bases.each do |base|
117
+ key = base[0..-2]
118
+ key[-1] += ".rb"
119
+ nfiles.each_with_index do |file, i|
120
+ if file == key
121
+ nfiles.insert( i, base )
122
+ base = nil
123
+ break
124
+ end
125
+ end
126
+ return files if base
127
+ end
128
+
129
+ nfiles
130
+ end
131
+
132
+ end
133
+
134
+ end
135
+ end
@@ -0,0 +1,5 @@
1
+ /*
2
+ % license.each do |line|
3
+ * <%=line%>
4
+ % end
5
+ */
@@ -0,0 +1,5 @@
1
+ #--
2
+ % license.each do |line|
3
+ # <%=line%>
4
+ % end
5
+ #++
@@ -0,0 +1,3 @@
1
+ % license.each do |line|
2
+ <%=line%>
3
+ % end
@@ -0,0 +1,5 @@
1
+ <!--
2
+ % license.each do |line|
3
+ <%=line%>
4
+ % end
5
+ -->
@@ -0,0 +1,13 @@
1
+ Copyright (c) <%= years %> <%= holder %>
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License"); you
4
+ may not use this file except in compliance with the License. You may
5
+ obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12
+ implied. See the License for the specific language governing
13
+ permissions and limitations under the License.
@@ -0,0 +1,27 @@
1
+ Copyright (c) <%= years %> <%= holder %>
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are
6
+ met:
7
+
8
+ * Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+ * Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+ * Neither the name of RJack nor the names of its contributors may be
14
+ used to endorse or promote products derived from this software
15
+ without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,21 @@
1
+ Copyright (c) <%= years %> <%= holder %>
2
+ All rights reserved.
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gravitext-devtools
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - David Kellum
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-04-21 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rjack-tarpit
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.1
24
+ version:
25
+ description: |-
26
+ A collection of development support tools.
27
+
28
+ gt-manifest:: Maintain manifest from git ls-files minus exclusions.
29
+ gt-cleanws:: Cleanup whitespace in files.
30
+ gt-header:: Add and maintain file license headers.
31
+ email:
32
+ - dek-oss@gravitext.com
33
+ executables:
34
+ - gt-cleanws
35
+ - gt-header
36
+ - gt-manifest
37
+ extensions: []
38
+
39
+ extra_rdoc_files:
40
+ - Manifest.txt
41
+ - templates/format/format.txt
42
+ - README.rdoc
43
+ - History.rdoc
44
+ files:
45
+ - History.rdoc
46
+ - Manifest.txt
47
+ - README.rdoc
48
+ - Rakefile
49
+ - bin/gt-cleanws
50
+ - bin/gt-header
51
+ - bin/gt-manifest
52
+ - lib/gravitext-devtools/base.rb
53
+ - lib/gravitext-devtools.rb
54
+ - lib/gravitext-devtools/header_writer.rb
55
+ - lib/gravitext-devtools/manifest_writer.rb
56
+ - templates/format/format.java
57
+ - templates/format/format.rb
58
+ - templates/format/format.txt
59
+ - templates/format/format.xml
60
+ - templates/license/apache
61
+ - templates/license/bsd
62
+ - templates/license/mit
63
+ has_rdoc: true
64
+ homepage: http://github.com/dekellum/gravitext-devtools
65
+ licenses: []
66
+
67
+ post_install_message:
68
+ rdoc_options:
69
+ - --main
70
+ - README.rdoc
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ requirements: []
86
+
87
+ rubyforge_project: gravitext-devtools
88
+ rubygems_version: 1.3.5
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: A collection of development support tools
92
+ test_files: []
93
+