modusoperandi 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+