code_tools 4.0.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8e0734734f903314d2b0ac7652eca0c3a345d498
4
+ data.tar.gz: 4466ac82270d0b13b24bbbacdca8744204e33743
5
+ SHA512:
6
+ metadata.gz: b7d0326b92e82e509fec5dd40c4e251434165682c78191e20d2ab5535ee7912428088c184c0762393b8bc83acd4beee36906fff81f5b34d3536dd2ed0132816c
7
+ data.tar.gz: 8bc0c83868759a9d0cb1e533955fcf80b0cfa7b458b05a7d3fbc968d56e6269b5ea2a301b0f2c5e74074b7db14677b55479014a28702a75c817a5b37e26fa095
data/bin/code_tools ADDED
@@ -0,0 +1 @@
1
+ #!/bin/bash
data/bin/vamper ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'vamper'
4
+ Vamper.new.execute
data/lib/core_ext.rb ADDED
@@ -0,0 +1,54 @@
1
+ class String
2
+ def underscore
3
+ self.gsub(/::/, '/').
4
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
5
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
6
+ tr('-', '_').
7
+ downcase
8
+ end
9
+
10
+ def replace_tags(tags)
11
+ str = self
12
+ tags.each { |name, value|
13
+ str = str.gsub(%r(\$\{#{name.to_s}\})m, value)
14
+ }
15
+ str
16
+ end
17
+
18
+ def replace_tags!(tags)
19
+ tags.each { |name, value|
20
+ self.gsub!(%r(\$\{#{name.to_s}\})m, value)
21
+ }
22
+ self
23
+ end
24
+
25
+ # colorization
26
+ def colorize(color_code)
27
+ "\e[#{color_code}m#{self}\e[0m"
28
+ end
29
+
30
+ def red
31
+ colorize(31)
32
+ end
33
+
34
+ def green
35
+ colorize(32)
36
+ end
37
+
38
+ def yellow
39
+ colorize(33)
40
+ end
41
+
42
+ def blue
43
+ colorize(34)
44
+ end
45
+
46
+ def pink
47
+ colorize(35)
48
+ end
49
+
50
+ def light_blue
51
+ colorize(36)
52
+ end
53
+
54
+ end
@@ -0,0 +1,97 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <VersionConfig>
3
+ <FileType>
4
+ <Name>Version-in-a-text-file</Name>
5
+ <FileSpec>*.version.txt</FileSpec>
6
+ <Write>Release ${Major}.${Minor}.${Build}.${Revision}</Write>
7
+ </FileType>
8
+ <FileType>
9
+ <Name>Windows Manifest File</Name>
10
+ <FileSpec>WMManifest.xml</FileSpec>
11
+ <Update>
12
+ <Search>(?'Before'Version=")([0-9]+\.[0-9]+)(?'After'\.[0-9]+\.[0-9]+")</Search>
13
+ <Replace>${Before}${Major}.${Minor}${After}</Replace>
14
+ </Update>
15
+ </FileType>
16
+ <FileType>
17
+ <Name>C# Source</Name>
18
+ <FileSpec>*.cs</FileSpec>
19
+ <Update>
20
+ <Search>(?'Before'AssemblyVersion\(")([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)(?'After'"\))</Search>
21
+ <Replace>${Before}${Major}.${Minor}.0.0${After}</Replace>
22
+ </Update>
23
+ <Update>
24
+ <Search>(?'Before'AssemblyFileVersion\(")([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)(?'After'"\))</Search>
25
+ <Replace>${Before}${Major}.${Minor}.${Build}.${Revision}${After}</Replace>
26
+ </Update>
27
+ <Update>
28
+ <Search>(?'Before'AssemblyProduct\(")([^"]*)(?'After'"\))</Search>
29
+ <Replace>${Before}${Product}${After}</Replace>
30
+ </Update>
31
+ <Update>
32
+ <Search>(?'Before'AssemblyCopyright\(")([^"]*)(?'After'"\))</Search>
33
+ <Replace>${Before}${Copyright}${After}</Replace>
34
+ </Update>
35
+ <Update>
36
+ <Search>(?'Before'AssemblyCompany\(")([^"]*)(?'After'"\))</Search>
37
+ <Replace>${Before}${Company}${After}</Replace>
38
+ </Update>
39
+ </FileType>
40
+ <FileType>
41
+ <Name>Windows RC File</Name>
42
+ <FileSpec>*.rc</FileSpec>
43
+ <Update>
44
+ <Search>(?'Before'FILEVERSION )([0-9]+,[0-9]+,[0-9]+,[0-9]+)</Search>
45
+ <Replace>${Before}${Major},${Minor},${Build},${Revision}</Replace>
46
+ </Update>
47
+ <Update>
48
+ <Search>(?'Before'PRODUCTVERSION )([0-9]+,[0-9]+,[0-9]+,[0-9]+)</Search>
49
+ <Replace>${Before}${Major},${Minor},${Build},${Revision}</Replace>
50
+ </Update>
51
+ <Update>
52
+ <Search>(?'Before'"FileVersion",[ \t]*")([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)(?'After'")</Search>
53
+ <Replace>${Before}${Major}.${Minor}.${Build}.${Revision}${After}</Replace>
54
+ </Update>
55
+ <Update>
56
+ <Search>(?'Before'"ProductVersion",[ \t]*")([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)(?'After'")</Search>
57
+ <Replace>${Before}${Major}.${Minor}.${Build}.${Revision}${After}</Replace>
58
+ </Update>
59
+ </FileType>
60
+ <FileType>
61
+ <Name>WiX Files</Name>
62
+ <FileSpec>*.wxi</FileSpec>
63
+ <FileSpec>*.wxs</FileSpec>
64
+ <Update>
65
+ <Search>(?'Before'ProductVersion = ")([0-9]+\.[0-9]+)(?'After'")</Search>
66
+ <Replace>${Before}${Major}.${Minor}${After}</Replace>
67
+ </Update>
68
+ <Update>
69
+ <Search>(?'Before'ProductBuild = ")([0-9]+\.([0-9]|[1-9][0-9]))(?'After'")</Search>
70
+ <Replace>${Before}${Build}.${Revision}${After}</Replace>
71
+ </Update>
72
+ </FileType>
73
+ <FileType>
74
+ <Name>.NET Config Files</Name>
75
+ <FileSpec>*.config</FileSpec>
76
+ <Update>
77
+ <Search>(?'Before', +Version=)\d+\.\d+(?'After'\.0\.0 *,)</Search>
78
+ <Replace>${Before}${Major}.${Minor}${After}</Replace>
79
+ </Update>
80
+ </FileType>
81
+ <FileType>
82
+ <Name>Visual Studio Project Files</Name>
83
+ <FileSpec>*.csproj</FileSpec>
84
+ <Update>
85
+ <Search>(?'Before'&lt;OutputName&gt;" + projectName + @"_)([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)(?'After'&lt;/OutputName&gt;)</Search>
86
+ <Replace>${Before}${Major}.${Minor}.${Build}.${Revision}${After}</Replace>
87
+ </Update>
88
+ </FileType>
89
+ <FileType>
90
+ <Name>VSIX Manifest</Name>
91
+ <FileSpec>*.vsixmanifest</FileSpec>
92
+ <Update>
93
+ <Search>(?'Before'&lt;Version&gt;)([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)(?'After'&lt;/Version&gt;)</Search>
94
+ <Replace>${Before}${Major}.${Minor}.${Build}.${Revision}${After}</Replace>
95
+ </Update>
96
+ </FileType>
97
+ </VersionConfig>
@@ -0,0 +1,34 @@
1
+ require 'nokogiri'
2
+ require 'core_ext.rb'
3
+
4
+ class VersionConfigFile
5
+ def initialize(io, tags)
6
+ doc = Nokogiri::XML(io)
7
+
8
+ @file_types = []
9
+ doc.xpath('/VersionConfig/FileType').each do |node|
10
+ file_type_struct = Struct.new(:name, :file_specs, :updates, :write)
11
+ search_replace_struct = Struct.new(:search, :replace)
12
+ file_type = file_type_struct.new
13
+ file_type.name = node.name
14
+ file_type.file_specs = node.xpath('FileSpec').map { |sub_node|
15
+ Regexp.new('^' + Regexp::escape(sub_node.text).gsub('\\*', '.*').gsub('\\?', '.') + '$')
16
+ }
17
+ update_node_set = node.xpath('Update')
18
+ if update_node_set
19
+ file_type.updates = update_node_set.map { |sub_node|
20
+ s_and_r = search_replace_struct.new(
21
+ %r(#{sub_node.at_xpath('Search').text.gsub(/\(\?'(\w+)'/, '(?<\\1>')}),
22
+ sub_node.at_xpath('Replace').text.replace_tags(tags))
23
+ }
24
+ end
25
+ write_node = node.at_xpath('Write')
26
+ if write_node
27
+ file_type.write = write_node.text.replace_tags(tags)
28
+ end
29
+ @file_types.push(file_type)
30
+ end
31
+ end
32
+
33
+ attr_reader :file_types
34
+ end
@@ -0,0 +1,95 @@
1
+ require 'nokogiri'
2
+ require 'core_ext.rb'
3
+
4
+ class BadVersionFile < StandardError; end
5
+
6
+ class VersionFile
7
+ attr_reader :tags
8
+
9
+ def initialize(io)
10
+ if io
11
+ @doc = Nokogiri::XML(io, &:noblanks)
12
+
13
+ unless @doc.root.name == 'Version'
14
+ raise BadVersionFile, 'Root element must be Version'
15
+ end
16
+ else
17
+ @doc = Nokogiri::XML::Document.new
18
+ @doc.root.add_child(Nokogiri::XML::Element.new('Version', @doc))
19
+ end
20
+
21
+ add_attribute @doc.root, :BuildValueType => :JDate
22
+ add_child_list_element @doc.root, :Files, :Tags
23
+ add_child_element tags_element,
24
+ :Major => 1, :Minor => 0, :Build => 0, :Patch => 0, :Revision => 0, :TimeZone => 'UTC'
25
+ add_child_element tags_element, {:StartYear => TZInfo::Timezone.get(self.time_zone).now.year}
26
+ end
27
+
28
+ def add_attribute(parent_node, attr_definitions)
29
+ attr_definitions.each { |attr_symbol, attr_default|
30
+ method_name = attr_symbol.to_s.underscore
31
+ unless parent_node[attr_symbol]
32
+ parent_node[attr_symbol] = attr_default
33
+ end
34
+ define_singleton_method(method_name.to_sym) {
35
+ parent_node[attr_symbol].to_sym
36
+ }
37
+ define_singleton_method((method_name + '=').to_sym) { |value|
38
+ parent_node[attr_symbol] = value.to_s
39
+ }
40
+ }
41
+ end
42
+
43
+ def add_child_list_element(parent_element, *element_symbols)
44
+ element_symbols.each { |element_symbol|
45
+ name = element_symbol.to_s
46
+ elem = parent_element.at(name)
47
+ unless elem
48
+ elem = parent_element.add_child(Nokogiri::XML::Element.new(name, @doc))
49
+ end
50
+
51
+ method_name = name.underscore + '_element'
52
+ define_singleton_method(method_name.to_sym) {
53
+ elem
54
+ }
55
+ }
56
+ end
57
+
58
+ def add_child_element(parent_element, element_definitions)
59
+ element_definitions.each { |element_symbol, element_default|
60
+ name = element_symbol.to_s
61
+ elem = parent_element.at(name)
62
+ unless elem
63
+ elem = parent_element.add_child(Nokogiri::XML::Element.new(name, @doc))
64
+ elem.content = element_default.to_s
65
+ end
66
+
67
+ method_name = name.underscore
68
+ case element_default
69
+ when Fixnum
70
+ define_singleton_method(method_name.to_sym) {
71
+ Integer(elem.content)
72
+ }
73
+ when String
74
+ define_singleton_method(method_name.to_sym) {
75
+ elem.content.to_s
76
+ }
77
+ end
78
+ define_singleton_method((method_name + '=').to_sym) { |value|
79
+ elem.content = value.to_s
80
+ }
81
+ }
82
+ end
83
+
84
+ def write_to(io)
85
+ @doc.write_xml_to(io, :indent_text => ' ', :indent => 2)
86
+ end
87
+
88
+ def tags
89
+ Hash[tags_element.children.select {|node| node.name != 'text'}.map {|node| [node.name.to_sym, node.content]}]
90
+ end
91
+ def files
92
+ files_element.children.select {|node| node.name != 'text'}.map {|node| node.content}
93
+ end
94
+
95
+ end
data/lib/vamper.rb ADDED
@@ -0,0 +1,194 @@
1
+ require 'tzinfo'
2
+ require 'nokogiri'
3
+ require 'vamper/version_file.rb'
4
+ require 'vamper/version_config_file.rb'
5
+ require 'core_ext.rb'
6
+
7
+ $VERSION='4.0.0-20150811.0'
8
+
9
+ class Vamper
10
+
11
+ def initialize
12
+ @do_update = false;
13
+ @version_file_name = ''
14
+ end
15
+
16
+ def parse(args)
17
+ args.each { |arg|
18
+ case arg
19
+ when '-?', '-help'
20
+ print %Q(Version Stamper. Version #{$VERSION}
21
+ Copyright (c) John Lyon-Smith 2015.
22
+
23
+ Syntax: #{File.basename(__FILE__)} [switches] VERSION_FILE
24
+
25
+ Description: Stamps versions into project files
26
+
27
+ Switches:
28
+
29
+ -help|-? Shows this help
30
+ -u|-update Increment the build number and update all files
31
+
32
+ )
33
+ exit(0)
34
+ when '-u', '-update'
35
+ @do_update = true
36
+ else
37
+ @version_file_name = arg
38
+ end
39
+ }
40
+ end
41
+
42
+ def execute
43
+ self.parse(ARGV)
44
+
45
+ if @version_file_name.length == 0
46
+ find_version_file
47
+ end
48
+
49
+ @version_file_name = File.expand_path(@version_file_name)
50
+
51
+ project_name = File.basename(@version_file_name, '.version')
52
+ version_config_file_name = "#{File.dirname(@version_file_name)}/#{project_name}.version.config"
53
+
54
+ puts "Version file is '#{@version_file_name}'"
55
+ puts "Version config is '#{version_config_file_name}'"
56
+ puts "Project name is '#{project_name}'"
57
+
58
+ if File.exists?(@version_file_name)
59
+ version_file = VersionFile.new(File.open(@version_file_name))
60
+ else
61
+ verson_file = VersionFile.new
62
+ end
63
+
64
+ now = TZInfo::Timezone.get(version_file.time_zone).now
65
+
66
+ case version_file.build_value_type
67
+ when :JDate
68
+ build = get_jdate(now, version_file.start_year)
69
+
70
+ if version_file.build != build
71
+ version_file.revision = 0
72
+ version_file.build = build
73
+ else
74
+ version_file.revision += 1
75
+ end
76
+ when :FullDate
77
+ build = get_full_date(now)
78
+
79
+ if version_file.build != build
80
+ version_file.revision = 0
81
+ version_file.build = build
82
+ else
83
+ version_file.revision += 1
84
+ end
85
+ when :Incremental
86
+ version_file.build += 1
87
+ version_file.revision = 0
88
+ end
89
+
90
+ puts 'Version data is:'
91
+ tags = version_file.tags
92
+ tags.each { |key, value|
93
+ puts " #{key}=#{value}"
94
+ }
95
+
96
+ if @do_update
97
+ puts 'Updating version information:'
98
+ end
99
+
100
+ unless File.exists?(version_config_file_name)
101
+ FileUtils.cp(File.join(File.dirname(__FILE__), 'default.version.config'), version_config_file_name)
102
+ end
103
+
104
+ version_config_file = VersionConfigFile.new(File.open(version_config_file_name), tags)
105
+ file_list = version_file.files.map { |file_name| file_name.replace_tags!(tags) }
106
+
107
+ file_list.each do |file_name|
108
+ path = File.expand_path(File.join(File.dirname(@version_file_name), file_name))
109
+ path_file_name = File.basename(path)
110
+ match = false
111
+
112
+ for file_type in version_config_file.file_types do
113
+ match = file_type.file_specs.any? { |file_spec| file_spec.match(path_file_name) }
114
+ unless match
115
+ next
116
+ end
117
+
118
+ if file_type.write
119
+ dir = File.dirname(path)
120
+ unless Dir.exists?(dir)
121
+ error "Directory '#{dir}' does not exist to write file ''#{path_file_name}''"
122
+ exit(1)
123
+ end
124
+
125
+ if @do_update
126
+ IO.write(path, file_type.write)
127
+ end
128
+ else # !file_type.write
129
+ if File.exists?(path)
130
+ if @do_update
131
+ file_type.updates.each do |update|
132
+ content = IO.read(path)
133
+ content.gsub!(%r(#{update.search})m, update.replace.gsub(/\${(\w+)}/,'\\\\k<\\1>'))
134
+ IO.write(path, content)
135
+ end
136
+ end
137
+ else
138
+ error "File #{path} does not exist to update"
139
+ exit(1)
140
+ end
141
+ end
142
+
143
+ break
144
+ end
145
+
146
+ unless match
147
+ error "File '#{path}' has no matching file type in the .version.config"
148
+ exit(1)
149
+ end
150
+
151
+ puts path
152
+
153
+ if @do_update
154
+ version_file.write_to(File.open(@version_file_name, 'w'))
155
+ end
156
+ end
157
+ end
158
+
159
+ def find_version_file
160
+ dir = Dir.pwd
161
+
162
+ while dir.length != 0
163
+ files = Dir.glob('*.version')
164
+ if files.length > 0
165
+ @version_file_name = files[0]
166
+ break
167
+ else
168
+ if dir == '/'
169
+ dir = ''
170
+ else
171
+ dir = File.expand_path('..', dir)
172
+ end
173
+ end
174
+ end
175
+
176
+ if @version_file_name.length == 0
177
+ error 'Unable to find a .version file in this or parent directories.'
178
+ exit(1)
179
+ end
180
+ end
181
+
182
+ def get_full_date(now)
183
+ now.year * 10000 + now.month * 100 + now.mday
184
+ end
185
+
186
+ def get_jdate(now, start_year)
187
+ ((now.year - start_year + 1) * 10000) + (now.month * 100) + now.mday
188
+ end
189
+
190
+ def error(msg)
191
+ puts "error: ".red + "#{msg}"
192
+ end
193
+
194
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: code_tools
3
+ version: !ruby/object:Gem::Version
4
+ version: 4.0.0
5
+ platform: ruby
6
+ authors:
7
+ - John Lyon-smith
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tzinfo
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ description: Tools for source code maintenance, including version stamping, line endings
42
+ and tab/space conversion.
43
+ email: john@jamoki.com
44
+ executables:
45
+ - vamper
46
+ - code_tools
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - lib/vamper.rb
51
+ - lib/core_ext.rb
52
+ - lib/vamper/default.version.config
53
+ - lib/vamper/version_config_file.rb
54
+ - lib/vamper/version_file.rb
55
+ - bin/vamper
56
+ - bin/code_tools
57
+ homepage: http://rubygems.org/gems/code_tools
58
+ licenses:
59
+ - MIT
60
+ metadata: {}
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '2.0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubyforge_project:
77
+ rubygems_version: 2.0.14
78
+ signing_key:
79
+ specification_version: 4
80
+ summary: Source code tools
81
+ test_files: []