modusoperandi 1.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.
Files changed (3) hide show
  1. data/bin/mo +223 -0
  2. data/bin/mo.bat +2 -0
  3. metadata +57 -0
data/bin/mo ADDED
@@ -0,0 +1,223 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ftools'
4
+ require 'fileutils'
5
+
6
+ def usage
7
+ puts "mo [options] <project> <context> [<version>]"
8
+ puts "\noptions"
9
+ puts " -quiet Suppress normal output"
10
+ exit 1
11
+ end
12
+
13
+ def quiet_puts(string = "")
14
+ puts string unless @quiet
15
+ end
16
+
17
+ def check_project
18
+ File.makedirs File.join(ENV['HOME'], '.modusoperandi')
19
+
20
+ @src_dir = File.join(ENV['HOME'], '.modusoperandi', @project)
21
+
22
+ if !(File.directory?(File.join(@src_dir, '.git')))
23
+ if !File.exists?('.modusoperandi')
24
+ print "\nPlease enter a valid git repository URL (e.g. git@217.33.244.230:lvscm_example.git): "
25
+ url = $stdin.gets.chomp
26
+ `git clone #{url} #{@src_dir}`
27
+ end
28
+ end
29
+
30
+ File.makedirs File.join(@src_dir, 'ModusOperandi')
31
+
32
+ end
33
+
34
+
35
+ def dest_dir
36
+ filename = File.join(@src_dir, 'ModusOperandi', 'target.dat')
37
+ if File.file? filename
38
+ @dest_dir = File.read(filename).chomp
39
+ else
40
+ print "\nPlease enter the target folder: "
41
+ @dest_dir = $stdin.gets.chomp
42
+ File.open(filename, 'w') { |f| f.puts @dest_dir }
43
+ end
44
+ end
45
+
46
+
47
+ def check_git
48
+ version = `git --version`
49
+ path = `git --exec-path`
50
+ quiet_puts "Running #{version.chomp} found in '#{path.chomp}'"
51
+ end
52
+
53
+
54
+ def check_context(exit_on_fail = false)
55
+ ok = false
56
+ filename = File.join(@src_dir, 'ModusOperandi', 'contexts.dat')
57
+ unless File.file? filename
58
+ puts "WARNING: #{filename} does not exist. Context validation skipped."
59
+ return true
60
+ end
61
+
62
+ contexts = File.read(filename).split("\n")
63
+
64
+ contexts.each do |c|
65
+ expr = Regexp.new(c)
66
+ if @context =~ expr
67
+ ok = true
68
+ break
69
+ end
70
+ end
71
+
72
+ if ok
73
+ quiet_puts "Context '#{@context}'"
74
+ else
75
+ puts "Context '#{@context}' is not valid."
76
+ exit 1 if exit_on_fail
77
+ end
78
+ ok
79
+ end
80
+
81
+
82
+ def do_version
83
+ if @version
84
+ expr = Regexp.new("#{@version}\n")
85
+ if `git --git-dir=#{@src_dir}/.git branch` =~ expr
86
+ quiet_puts "Using version '#{@version}'"
87
+ `git --git-dir=#{@src_dir}/.git --work-tree=#{@src_dir} checkout #{@version}`
88
+ `git --git-dir=#{@src_dir}/.git --work-tree=#{@src_dir} reset --hard`
89
+ else
90
+ puts "Version '#{@version}' is not valid."
91
+ exit 1
92
+ end
93
+ else
94
+ version = (`git --git-dir=#{@src_dir}/.git branch`.match(/\*\s\w+\n/))[0].split[1]
95
+ quiet_puts "Version '#{version}'"
96
+ end
97
+ end
98
+
99
+
100
+ def parse_data(src, dest)
101
+ input = File.open(src, 'r')
102
+ data = input.readline
103
+
104
+ # # The first line should contain the patterm "modusoperandi n.n.n" and some option include / exclude tags terminated by CR LF.
105
+ matchdata = data.match(/modusoperandi v(\d+\.\d+\.\d+)(.*?)[\r\n]+/)
106
+ if matchdata.nil?
107
+ # This is not a valid MO file, do not attempt to interpret it.
108
+ input.close
109
+ quiet_puts " COPY | #{src}"
110
+ File.copy(src, dest)
111
+ return
112
+ end
113
+
114
+ quiet_puts " PARSE | #{src}"
115
+ version = matchdata[1]
116
+ conditions = matchdata[2]
117
+
118
+ matchdata = conditions.match(/(include|exclude)_for\s*\((.*?)\)/)
119
+ if !matchdata.nil?
120
+ include = true
121
+ if (matchdata[1] == 'exclude')
122
+ include = false
123
+ end
124
+
125
+ expr = Regexp.new(matchdata[2])
126
+ if (include)
127
+ if (@context !~ expr)
128
+ File.delete(dest) if File.file?(dest)
129
+ return
130
+ end
131
+ else
132
+ if (@context =~ expr)
133
+ quiet_puts " SKIP | #{src}"
134
+ File.delete(dest) if File.file?(dest)
135
+ return
136
+ end
137
+ end
138
+ end
139
+
140
+ output = File.open(dest, 'w')
141
+
142
+ data = input.read
143
+ input.close
144
+
145
+
146
+ # 1. Match either 'include' or 'exclude' [1]
147
+ # 2. Match '_for'
148
+ # 3. Match 0 or more spaces
149
+ # 4. Match '('
150
+ # 5. Match all characters (non-greedy) [2]
151
+ # 6. Match ')'
152
+ # 7. Match 0 or more spaces, carriage returns or linefeeds
153
+ # 8. Match '{'
154
+ # 9. Match 0 or more spaces, carriage returns or linefeeds
155
+ # 10. Match all characters (non-greedy) [3]
156
+ # 11. Match '}'
157
+ # 12. Match a space, carriage return or linefeed
158
+ while (matchdata = data.match(/(include|exclude)_for\s*\((.*?)\)\s*\{\s*(.*?)\}\s/m))
159
+
160
+ output.print matchdata.pre_match
161
+ include = true
162
+ if (matchdata[1] == 'exclude')
163
+ include = false
164
+ end
165
+
166
+ expr = Regexp.new(matchdata[2])
167
+
168
+ if (include)
169
+ if (@context =~ expr)
170
+ output.puts matchdata[3]
171
+ end
172
+ end
173
+
174
+ if (!include and @context !~ expr)
175
+ output.puts matchdata[3]
176
+ end
177
+
178
+ data = matchdata.post_match
179
+ end
180
+
181
+ output.print data
182
+ output.close
183
+ end
184
+
185
+ @quiet = false
186
+ ARGS = ARGV.delete_if do |arg|
187
+ @quiet = true if arg == '-quiet'
188
+ arg[0].chr == '-'
189
+ end
190
+
191
+ usage() unless ARGS.size > 1
192
+
193
+ @project = ARGS[0]
194
+ @context = ARGS[1]
195
+ @version = ARGS[2] # If no tag is set, we will always continue with the current git branch
196
+
197
+ check_project() # Will check the project exists in $HOME/.modusoperandi and then set @src_dir
198
+
199
+ dest_dir()
200
+
201
+ check_git()
202
+ check_context(true)
203
+ do_version()
204
+
205
+ quiet_puts "Destination '#{@dest_dir}'\n\n"
206
+
207
+ olddir = Dir.pwd
208
+ Dir.chdir(@src_dir)
209
+
210
+ File.makedirs @dest_dir
211
+
212
+ Dir["**/*"].each do |file|
213
+ if file !~ /^ModusOperandi/
214
+ dest = File.join(@dest_dir, file)
215
+ if File.directory?(file)
216
+ File.makedirs(dest)
217
+ else
218
+ parse_data(file, dest)
219
+ end
220
+ end
221
+ end
222
+ Dir.chdir(olddir)
223
+ quiet_puts
data/bin/mo.bat ADDED
@@ -0,0 +1,2 @@
1
+ @echo off
2
+ ruby %~dp0mo %1 %2 %3 %4 %5 %6
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: modusoperandi
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Simon Ordish
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-09-29 00:00:00 +02:00
13
+ default_executable: mo
14
+ dependencies: []
15
+
16
+ description:
17
+ email: simon.ordish@lvs.co.uk
18
+ executables:
19
+ - mo
20
+ - mo.bat
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - bin/mo
27
+ - bin/mo.bat
28
+ has_rdoc: true
29
+ homepage:
30
+ licenses: []
31
+
32
+ post_install_message:
33
+ rdoc_options: []
34
+
35
+ require_paths:
36
+ - bin
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: "0"
42
+ version:
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ requirements: []
50
+
51
+ rubyforge_project:
52
+ rubygems_version: 1.3.5
53
+ signing_key:
54
+ specification_version: 3
55
+ summary: A utility to manage configuration files
56
+ test_files: []
57
+