code_tools 4.1.0 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cbaf6f2122fa3302144ef27d0c5484c82a8bec52
4
- data.tar.gz: 2b3eb698101465ed00e6b367cf55e357a1aede36
3
+ metadata.gz: da904aa42c144ba90f9479facf968c63f6c9502f
4
+ data.tar.gz: 090ca4a1c671a2fc91c8259801af3b6c128c21e6
5
5
  SHA512:
6
- metadata.gz: a24bfc3ab574bfbc0fbc38b0568919cf1cf3fabf340c270810ff4cdd8b90b9d825b55cd2f719891c6b78e3bd8a83c59723a72d7225a49cfa9148d6b93ea71dd4
7
- data.tar.gz: ceadd6e3b9b004033420b90e6e4f0bf4d63764765b3e9a2f74efd39060ed42be21309ce6773ad49346a962baba94bd71fb94ba4eb05256296beb1564e6ec65bc
6
+ metadata.gz: 16ad5be70ccf2e1b792f5f8745cd6c88d39c5520366ba3d4ced52104e59262478c73675b281600b5adf29a09cfe08cfaecc24107828aaa5aaad7dfe09720886b
7
+ data.tar.gz: 40d615576784fd90c4c3580e52e96d91c55913ca650622c3610db08802443b72f0bd988820e64a14a7854b71127d89366528c9e483a2b26c84d5724928578ac8
data/bin/code_tools CHANGED
@@ -1 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env ruby
2
+ puts "vamper - Version stamper"
3
+ puts "ender - CR/LF line ending fixer"
4
+ puts "spacer - Space/tab line fixer"
data/bin/ender ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ender'
4
+ Ender.new.execute
data/bin/spacer ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'spacer'
4
+ Spacer.new.execute
data/lib/ender.rb ADDED
@@ -0,0 +1,167 @@
1
+ require 'ostruct'
2
+ require 'optparse'
3
+ require 'colorize'
4
+
5
+ $VERSION='4.2.0-20151225.0'
6
+
7
+ class Ender
8
+
9
+ def parse(args)
10
+ options = OpenStruct.new
11
+ options.output_filename = ''
12
+ options.input_filename = ''
13
+ options.convert_mode = nil
14
+
15
+ opt_parser = OptionParser.new do |opts|
16
+ opts.banner = %Q(Ender Line Ending Fixer. Version #{$VERSION}
17
+ Copyright (c) John Lyon-Smith, 2015.
18
+ Usage: #{File.basename(__FILE__)} [options]
19
+ )
20
+ opts.separator %Q(Options:
21
+ )
22
+
23
+ opts.on("-o", "--output FILE", String, "The output file. Default is the same as the input file.") do |file|
24
+ options.output_filename = File.expand_path(file)
25
+ end
26
+
27
+ opts.on("-m", "--mode MODE", [:auto, :lf, :cr, :crlf], "The convert mode (auto, cr, lf, crlf)",
28
+ "(auto) will use the most commonly occurring ending.",
29
+ "Updates will only be done when this argument is given.") do |mode|
30
+ options.convert_mode = mode
31
+ end
32
+
33
+ opts.on_tail("-?", "--help", "Show this message") do
34
+ puts opts
35
+ exit
36
+ end
37
+ end
38
+
39
+ opt_parser.parse!(args)
40
+ options.input_filename = ARGV.pop
41
+ raise 'Need to specify a file to process' unless options.input_filename
42
+ options.input_filename = File.expand_path(options.input_filename)
43
+ options
44
+ end
45
+
46
+ def execute
47
+ options = self.parse(ARGV)
48
+
49
+ if !File.exist?(options.input_filename)
50
+ error "File #{options.input_filename} does not exist"
51
+ exit
52
+ end
53
+
54
+ if options.output_filename.length == 0
55
+ options.output_filename = options.input_filename
56
+ end
57
+
58
+ # Read the entire file and determine all the different line endings
59
+ file_contents = IO.read(options.input_filename)
60
+ num_cr = 0
61
+ num_lf = 0
62
+ num_crlf = 0
63
+ num_lines = 1
64
+
65
+ i = 0
66
+ while i < file_contents.length do
67
+ c = file_contents[i]
68
+
69
+ if c == "\r"
70
+ if i < file_contents.length - 1 and file_contents[i + 1] == "\n"
71
+ num_crlf += 1
72
+ i += 1
73
+ else
74
+ num_cr += 1
75
+ end
76
+
77
+ num_lines += 1
78
+ elsif c == "\n"
79
+ num_lf += 1
80
+ num_lines += 1
81
+ end
82
+ i += 1
83
+ end
84
+
85
+ num_endings = (num_cr > 0 ? 1 : 0) + (num_lf > 0 ? 1 : 0) + (num_crlf > 0 ? 1 : 0)
86
+ le = num_endings > 1 ? :mixed : num_cr > 0 ? :cr : num_lf > 0 ? :lf : :crlf
87
+ msg = "\"#{options.input_filename}\", #{le.to_s}, #{num_lines} lines"
88
+
89
+ if options.convert_mode == nil
90
+ puts msg
91
+ exit
92
+ end
93
+
94
+ if options.convert_mode == :auto
95
+ # Find the most common line ending and make that the automatic line ending
96
+ auto_line_ending = :lf
97
+ n = num_lf
98
+
99
+ if num_crlf > n
100
+ auto_line_ending = :crlf
101
+ n = num_crlf
102
+ end
103
+
104
+ if num_cr > n
105
+ auto_line_ending = :cr
106
+ end
107
+
108
+ options.convert_mode = auto_line_ending
109
+ end
110
+
111
+ new_num_lines = 1
112
+
113
+ if (options.convert_mode == :cr and num_cr + 1 == num_lines) or
114
+ (options.convert_mode == :lf and num_lf + 1 == num_lines) or
115
+ (options.convert_mode == :crlf and num_crlf + 1 == num_lines)
116
+ # We're not changing the line endings; nothing to do
117
+ new_num_lines = num_lines
118
+ else
119
+ newline_chars =
120
+ options.convert_mode == :cr ? "\r" :
121
+ options.convert_mode == :lf ? "\n" :
122
+ "\r\n"
123
+
124
+ file = nil
125
+
126
+ begin
127
+ file = File.new(options.output_filename, 'w')
128
+
129
+ i = 0
130
+ while i < file_contents.length
131
+ c = file_contents[i]
132
+
133
+ if c == "\r"
134
+ if i < file_contents.length - 1 && file_contents[i + 1] == "\n"
135
+ i += 1
136
+ end
137
+
138
+ new_num_lines += 1
139
+ file.write(newline_chars)
140
+ elsif c == "\n"
141
+ new_num_lines += 1
142
+ file.write(newline_chars)
143
+ else
144
+ file.write(c)
145
+ end
146
+
147
+ i += 1
148
+ end
149
+ rescue Exception => e
150
+ error "unable to write #{options.output_filename}. #{e.to_s}"
151
+ exit
152
+ ensure
153
+ file.close() unless !file
154
+ end
155
+
156
+ msg += " -> \"#{options.output_filename}\", #{options.convert_mode.to_s}, #{new_num_lines} lines"
157
+ end
158
+
159
+ puts msg
160
+ end
161
+
162
+
163
+ def error(msg)
164
+ STDERR.puts "error: #{msg}".colorize(:red)
165
+ end
166
+
167
+ end
data/lib/spacer.rb ADDED
@@ -0,0 +1,405 @@
1
+ require 'ostruct'
2
+ require 'optparse'
3
+ require 'colorize'
4
+
5
+ $VERSION='4.2.0-20151225.0'
6
+
7
+ class Spacer
8
+
9
+ def parse(args)
10
+ options = OpenStruct.new
11
+ options.output_filename = ''
12
+ options.input_filename = nil
13
+ options.convert_mode = nil
14
+ options.tabsize = 4
15
+ options.round_down_spaces = false
16
+
17
+ opt_parser = OptionParser.new do |opts|
18
+ opts.banner = %Q(Spacer Text File Space/Tab Fixer Tool. Version #{$VERSION}
19
+ Copyright (c) John Lyon-Smith, 2015.
20
+ Usage: #{File.basename(__FILE__)} [options]
21
+ )
22
+ opts.separator %Q(Description:
23
+ When reporting the tool indicates beginning-of-line \(BOL\) tabs and spaces.
24
+ When replacing, all tabs not at the beginning of a line are replaced with spaces.
25
+ Spaces and tabs inside multi-line C# strings (@"...") and inside Ruby \%Q\(...\) strings
26
+ are ignored.
27
+ Note that conversion to tabs may still leave the file as mixed as some lines may have
28
+ spaces that are not a whole number multiple of the tabstop size. In that case use the
29
+ -round option to remove smooth out the spurious spaces.
30
+
31
+ )
32
+ opts.separator %Q(Options:
33
+ )
34
+
35
+ opts.on("-o", "--output FILE", String, "The output file. Default is the same as the input file.") do |file|
36
+ options.output_filename = File.expand_path(file)
37
+ end
38
+
39
+ opts.on("-m", "--mode MODE", [:mixed, :tabs, :spaces], "The convert mode (mixed, tabs or spaces)",
40
+ "Default is to just display the files current state.",
41
+ "Updates will only be done when this argument is given.") do |mode|
42
+ options.convert_mode = mode
43
+ end
44
+
45
+ opts.on("-t", "--tabsize SIZE", Integer, "Tab size. Default is 4 spaces.",
46
+ "Default is to just display the files current state.",
47
+ "Updates will only be done when this argument is given.") do |size|
48
+ options.tabsize = size
49
+ end
50
+
51
+ opts.on("-r", "--round", "When tabifying, round BOL spaces down to an exact number of tabs.") do |round|
52
+ options.round_down_spaces = round
53
+ end
54
+
55
+ opts.on_tail("-?", "--help", "Show this message") do
56
+ puts opts
57
+ exit
58
+ end
59
+ end
60
+
61
+ opt_parser.parse!(args)
62
+ options.input_filename = ARGV.pop
63
+ if options.input_filename == nil
64
+ error 'Need to specify a file to process'
65
+ exit
66
+ end
67
+ options.input_filename = File.expand_path(options.input_filename)
68
+ options
69
+ end
70
+
71
+ def execute
72
+ options = self.parse(ARGV)
73
+
74
+ if !File.exist?(options.input_filename)
75
+ error "File #{options.input_filename} does not exist"
76
+ exit
77
+ end
78
+
79
+ if options.output_filename.length == 0
80
+ options.output_filename = options.input_filename
81
+ end
82
+
83
+ if File.extname(options.input_filename) == '.cs'
84
+ file_type = :csharp
85
+ else
86
+ file_type = :other
87
+ end
88
+
89
+ lines = read_file_lines(options.input_filename)
90
+
91
+ if file_type == :csharp
92
+ before = count_csharp_bol_spaces_and_tabs(lines)
93
+ else
94
+ before = count_bol_spaces_and_tabs(lines)
95
+ end
96
+
97
+ if options.convert_mode != nil
98
+ if file_type == :other
99
+ untabify(lines, options)
100
+ else
101
+ csharp_untabify(lines, options)
102
+ end
103
+
104
+ if options.convert_mode == :tabs
105
+ if file_type == :other
106
+ tabify(lines, options)
107
+ else
108
+ csharp_tabify(lines, options)
109
+ end
110
+ end
111
+ end
112
+
113
+ ws = get_whitespace_type(before)
114
+
115
+ msg = "\"#{options.input_filename}\", #{file_type.to_s}, #{ws.to_s}"
116
+
117
+ if options.convert_mode != nil
118
+ if file_type == :csharp
119
+ after = count_csharp_bol_spaces_and_tabs(lines)
120
+ else
121
+ after = count_bol_spaces_and_tabs(lines)
122
+ end
123
+
124
+ ws = get_whitespace_type(after)
125
+ file = nil
126
+
127
+ begin
128
+ file = File.new(options.output_filename, 'w')
129
+
130
+ for line in lines do
131
+ file.write(line)
132
+ end
133
+ ensure
134
+ file.close() unless file == nil
135
+ end
136
+
137
+ msg += " -> \"#{options.output_filename}\", #{ws.to_s}"
138
+ end
139
+
140
+ puts msg
141
+ end
142
+
143
+ def get_whitespace_type(bol)
144
+ (bol.tabs > 0) ? (bol.spaces > 0 ? :mixed : :tabs) : :spaces
145
+ end
146
+
147
+ def read_file_lines(filename)
148
+ # Read the entire file
149
+ file_contents = File.read(filename)
150
+
151
+ # Convert to a list of lines, preserving the end-of-lines
152
+ lines = []
153
+ s = 0
154
+ i = 0
155
+
156
+ while i < file_contents.length do
157
+ c = file_contents[i]
158
+ c1 = i < file_contents.length - 1 ? file_contents[i + 1] : "\0"
159
+
160
+ if c == "\r"
161
+ i += 1
162
+
163
+ if c1 == "\n"
164
+ i += 1
165
+ end
166
+ elsif c == "\n"
167
+ i += 1
168
+ else
169
+ i += 1
170
+ next
171
+ end
172
+
173
+ lines.push(file_contents[s, i - s])
174
+ s = i
175
+ end
176
+
177
+ if s != i
178
+ lines.push(file_contents[s, i - s])
179
+ end
180
+
181
+ lines
182
+ end
183
+
184
+ def count_csharp_bol_spaces_and_tabs(lines)
185
+ bol = OpenStruct.new
186
+ bol.tabs = 0
187
+ bol.spaces = 0
188
+ in_multi_line_string = false
189
+
190
+ for line in lines do
191
+ in_bol = true
192
+ i = 0
193
+ while i < line.length do
194
+ c = line[i]
195
+ c1 = i < line.length - 1 ? line[i + 1] : "\0"
196
+
197
+ if in_multi_line_string and c == "\"" and c1 != "\""
198
+ in_multi_line_string = false
199
+ elsif c == "@" and c1 == "\""
200
+ in_multi_line_string = true
201
+ i += 1
202
+ elsif in_bol and !in_multi_line_string and c == " "
203
+ bol.spaces += 1
204
+ elsif in_bol and !in_multi_line_string and c == "\t"
205
+ bol.tabs += 1
206
+ else
207
+ in_bol = false
208
+ end
209
+ i += 1
210
+ end
211
+ end
212
+
213
+ bol
214
+ end
215
+
216
+ def count_bol_spaces_and_tabs(lines)
217
+ bol = OpenStruct.new
218
+ bol.spaces = 0
219
+ bol.tabs = 0
220
+
221
+ for line in lines do
222
+ for i in 0...line.length do
223
+ c = line[i]
224
+
225
+ if c == " "
226
+ bol.spaces += 1
227
+ elsif c == "\t"
228
+ bol.tabs += 1
229
+ else
230
+ break
231
+ end
232
+ end
233
+ end
234
+
235
+ bol
236
+ end
237
+
238
+ def untabify(lines, options)
239
+ i = 0
240
+ while i < lines.length do
241
+ line = lines[i]
242
+ j = 0
243
+ new_line = ""
244
+
245
+ while j < line.length do
246
+ c = line[j]
247
+
248
+ if c == "\t"
249
+ num_spaces = options.tabsize - (new_line.length % options.tabsize)
250
+ new_line += " " * num_spaces
251
+ else
252
+ new_line += c
253
+ end
254
+ j += 1
255
+ end
256
+
257
+ lines[i] = new_line
258
+ i += 1
259
+ end
260
+ end
261
+
262
+ def tabify(lines, options)
263
+ i = 0
264
+ while i < lines.length do
265
+ line = lines[i]
266
+ j = 0
267
+ bol = true
268
+ num_bol_spaces = 0
269
+ new_line = ""
270
+
271
+ while j < line.length do
272
+ c = line[j]
273
+
274
+ if bol and c == " "
275
+ num_bol_spaces += 1
276
+ elsif bol and c != " "
277
+ bol = false
278
+ new_line += "\t" * (num_bol_spaces / options.tabsize)
279
+
280
+ if !options.round_down_spaces
281
+ new_line += " " * (num_bol_spaces % options.tabsize)
282
+ end
283
+
284
+ new_line += c
285
+ else
286
+ new_line += c
287
+ end
288
+
289
+ j += 1
290
+ end
291
+
292
+ lines[i] = new_line
293
+ i += 1
294
+ end
295
+ end
296
+
297
+ def csharp_untabify(lines, options)
298
+ # Expand tabs anywhere on a line, but not inside @"..." strings
299
+ in_multi_line_string = false
300
+
301
+ i = 0
302
+ while i < lines.length do
303
+ line = lines[i]
304
+ in_string = false
305
+ new_line = ""
306
+ j = 0
307
+
308
+ while j < line.length do
309
+ c_1 = j > 0 ? line[j - 1] : '\0'
310
+ c = line[j]
311
+ c1 = j < line.length - 1 ? line[j + 1] : '\0'
312
+
313
+ raise "line #{i + 1} has overlapping regular and multiline strings" if (in_string and in_multi_line_string)
314
+
315
+ if !in_multi_line_string and c == "\t"
316
+ # Add spaces to next tabstop
317
+ num_spaces = options.tabsize - (new_line.length % options.tabsize)
318
+
319
+ new_line += " " * num_spaces
320
+ elsif !in_multi_line_string and !in_string and c == "\""
321
+ in_string = true
322
+ new_line += c
323
+ elsif !in_multi_line_string and !in_string and c == "@" and c1 == "\""
324
+ in_multi_line_string = true
325
+ new_line += c
326
+ j += 1
327
+ new_line += c1
328
+ elsif in_string and c == "\"" and c_1 != "\\"
329
+ in_string = false
330
+ new_line += c
331
+ elsif in_multi_line_string and c == "\"" and c1 != "\""
332
+ in_multi_line_string = false
333
+ new_line += c
334
+ else
335
+ new_line += c
336
+ end
337
+
338
+ lines[i] = new_line
339
+ j += 1
340
+ end
341
+ i += 1
342
+ end
343
+ end
344
+
345
+ def csharp_tabify(lines, options)
346
+ # Insert tabs for spaces, but only at the beginning of lines and not inside @"..." or "..." strings
347
+ in_multi_line_string = false
348
+ i = 0
349
+
350
+ while i < lines.length do
351
+ line = lines[i]
352
+ in_string = false
353
+ bol = true
354
+ num_bol_spaces = 0
355
+ new_line = ""
356
+ j = 0
357
+
358
+ while j < line.length do
359
+ c_1 = j > 0 ? line[j - 1] : "\0"
360
+ c = line[j]
361
+ c1 = j < line.length - 1 ? line[j + 1] : "\0"
362
+
363
+ if !in_string and !in_multi_line_string and bol and c == " "
364
+ # Just count the spaces
365
+ num_bol_spaces += 1
366
+ elsif !in_string and !in_multi_line_string and bol and c != " "
367
+ bol = false
368
+
369
+ new_line += "\t" * (num_bol_spaces / options.tabsize)
370
+
371
+ if !options.round_down_spaces
372
+ new_line += " " * (num_bol_spaces % options.tabsize)
373
+ end
374
+ # Process this character again as not BOL
375
+ j -= 1
376
+ elsif !in_multi_line_string and !in_string and c == '"'
377
+ in_string = true
378
+ new_line += c
379
+ elsif !in_multi_line_string and !in_string and c == "@" and c1 == "\""
380
+ in_multi_line_string = true
381
+ new_line += c
382
+ j += 1
383
+ new_line += c1
384
+ elsif in_string and c == "\"" and c_1 != "\\"
385
+ in_string = false
386
+ new_line += c
387
+ elsif in_multi_line_string and c == "\"" and c1 != "\""
388
+ in_multi_line_string = false
389
+ new_line += c
390
+ else
391
+ new_line += c
392
+ end
393
+
394
+ lines[i] = new_line
395
+ j += 1
396
+ end
397
+ i += 1
398
+ end
399
+ end
400
+
401
+ def error(msg)
402
+ STDERR.puts "error: #{msg}".colorize(:red)
403
+ end
404
+
405
+ end
data/lib/vamper.rb CHANGED
@@ -2,11 +2,12 @@ require 'tzinfo'
2
2
  require 'nokogiri'
3
3
  require 'ostruct'
4
4
  require 'optparse'
5
+ require 'colorize'
5
6
  require_relative './vamper/version_file.rb'
6
7
  require_relative './vamper/version_config_file.rb'
7
8
  require_relative './core_ext.rb'
8
9
 
9
- $VERSION='4.1.0-20151225.0'
10
+ $VERSION='4.2.0-20151225.0'
10
11
 
11
12
  class Vamper
12
13
 
@@ -16,15 +17,15 @@ class Vamper
16
17
  options.version_file_name = ''
17
18
 
18
19
  opt_parser = OptionParser.new do |opts|
19
- opts.banner = %Q(Version Stamper. Version #{$VERSION}
20
+ opts.banner = %Q(Vamper Version Stamper. Version #{$VERSION}
20
21
  Copyright (c) John Lyon-Smith, 2016.
21
22
  Usage: #{File.basename(__FILE__)} [options]
22
23
  )
23
24
  opts.separator %Q(Options:
24
25
  )
25
26
 
26
- opts.on("-u", "--update", "Increment the build number and update all files") do |dir|
27
- options.do_update = true
27
+ opts.on("-u", "--update", "Increment the build number and update all files") do |update|
28
+ options.do_update = update
28
29
  end
29
30
 
30
31
  opts.on_tail("-?", "--help", "Show this message") do
@@ -189,7 +190,7 @@ Usage: #{File.basename(__FILE__)} [options]
189
190
  end
190
191
 
191
192
  def error(msg)
192
- puts "error: ".red + "#{msg}"
193
+ puts "error: #{msg}".colorize(:red)
193
194
  end
194
195
 
195
196
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code_tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Lyon-smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-25 00:00:00.000000000 Z
11
+ date: 2015-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tzinfo
@@ -38,18 +38,38 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: colorize
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.7.7
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.7.7
41
55
  description: Tools for source code maintenance, including version stamping, line endings
42
56
  and tab/space conversion.
43
57
  email: john@jamoki.com
44
58
  executables:
45
- - vamper
46
59
  - code_tools
60
+ - ender
61
+ - spacer
62
+ - vamper
47
63
  extensions: []
48
64
  extra_rdoc_files: []
49
65
  files:
50
66
  - bin/code_tools
67
+ - bin/ender
68
+ - bin/spacer
51
69
  - bin/vamper
52
70
  - lib/core_ext.rb
71
+ - lib/ender.rb
72
+ - lib/spacer.rb
53
73
  - lib/vamper.rb
54
74
  - lib/vamper/default.version.config
55
75
  - lib/vamper/version_config_file.rb