workEnv 0.1.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.
@@ -0,0 +1,278 @@
1
+ module WorkEnvs
2
+
3
+ # Class used by WorkEnv commands to add option to select an env (or sub env versions)
4
+ #
5
+ # It provides all the standard way (sha1, version, rev files, etc), to select which
6
+ # version of each envClass needs to be selected
7
+ #
8
+ # It also provides the --list option to list available envs
9
+ class VersionSelector
10
+
11
+ # Default number of environment versions in a list
12
+ WORK_ENV_DEF_LIST_SIZE = 20
13
+
14
+ # Constructor
15
+ #
16
+ # - opts: Program option struct to add the defaults values
17
+ # - optsParser: Program option parser to add the options
18
+ #
19
+ # This is called by WorkEnvs::versionSelectorPrepare
20
+ def initialize(opts, optsParser)
21
+ @options={
22
+ :infos => WorkEnvs::Dependencies.new(),
23
+ :infos_extra => WorkEnvs::Dependencies.new(),
24
+ :envOpts => WorkEnvs::EnvOpts.new(),
25
+ :list => false,
26
+ :branch => nil,
27
+ :hudson => [],
28
+ :sub_sha1 => [],
29
+ :flags => {
30
+ :ignore_empty => false,
31
+ }
32
+ }
33
+ @rev_files=[]
34
+
35
+ optsParser.separator "\nVersion Selection:"
36
+ optsParser.on("-v", "--version <package name>", String,
37
+ "Name of the package to install.") {|val| @options[:version] = val}
38
+ optsParser.on("-c", "--copy-env <.env_config>", String,
39
+ "Checkout the versions specified in this environment.") {|val| @options[:copyEnv] = val}
40
+ optsParser.on("-s", "--sha1 <SHA1>", String, "Full or short SHA1 of the package to install.") {|val| @options[:sha1] = val}
41
+ optsParser.on("-l", "--list [#result|all]", String,
42
+ "List possible packages."+
43
+ " Shows the last #{WORK_ENV_DEF_LIST_SIZE} by default") {|val| @options[:list] = val}
44
+ optsParser.on("-L", "--latest", nil, "Get the latest possible version.") {|val| @options[:latest] = true}
45
+ optsParser.on("-H", "--hudson <rev_file>", String, "Hudson mode.") {|val| @options[:hudson] << val}
46
+ optsParser.on("-A", "--hudson-auto", nil, "Hudson Auto mode.") {|val| @options[:hudsonAuto] = true}
47
+ optsParser.on("--sub-sha1 <(project|+rev_file name)>:<full sha1>", String,
48
+ "SHA1 for dependency.") {|val| @options[:sub_sha1] << val}
49
+ optsParser.on("-B", "--branch <branch_name>", String, "Filter list or latest by branch name.") {|val|
50
+ @options[:branch] = val}
51
+ optsParser.on("--ignore-empty", nil, "Exit without error if no packages are found.") {|val|
52
+ @options[:flags][:ignore_empty] = val}
53
+
54
+ end
55
+
56
+ # Finalize option parsing
57
+ #
58
+ # It validates all the option passed and fills a Dependencies object
59
+ # or simply list the latest packages
60
+ #
61
+ # It fills the Depencencies with:
62
+ # - Existing Dependencies from opts[ :infos ]
63
+ # - version from the latest package if --latest is used
64
+ # - version specified using --version
65
+ # - SHA1 specified using --sha1
66
+ # - Dependencies from another env if --copy-env is used
67
+ # - Rev files provided by the --hudson option
68
+ # - Rev files found using the --hudson-auto option
69
+ # - SHA1 from sub envs if --sub-sha1 is used
70
+ #
71
+ # Note that at this point, dependencies are NOT extracted from the packages.
72
+ # This is done much later by WorkEnvs::Core itself when generating package lists
73
+ #
74
+ # Note that an additional Dependencies is created (infos_extras).
75
+ # It contains dependencies extracted from the rev_file and sub-sha1 to envClass that
76
+ # are not parent of this env
77
+ #
78
+ # Throws an exception if there are dependencies incompatibilites
79
+ #
80
+ # Returns:
81
+ # - A flag hash (:ignore_empty)
82
+ # - a Depencencies for the env
83
+ # - a Depencencies object for dependencies not part of this env (infos_extras)
84
+ # - an EnvOpts object fetched by --copy-env
85
+ #
86
+ # This is called by WorkEnvs::versionSelectorFinal
87
+ def finalize(opts, env)
88
+ #Handle hudson file selection
89
+ @options[:infos].concat(opts[:infos]) if opts[:infos] != nil && !opts[:infos].empty?
90
+ @options[:infos_extra].concat(opts[:infos]) if opts[:infos_extra] != nil && !opts[:infos_extra].empty?
91
+
92
+ @options[:infos].ignore_conflicts = true if env != nil && env.ignore_conflicts == true
93
+
94
+ downloader = nil
95
+ if env != nil then
96
+ downloader = env.get_downloader(opts)
97
+ else
98
+ downloader = WorkEnvs::PackageDownloader.new()
99
+ downloader.be_silent = !VERBOSE
100
+ end
101
+ @options[:infos].downloader = downloader
102
+ @options[:infos_extra].downloader = downloader
103
+
104
+ # Handle version listing
105
+ list_versions(env, downloader) if @options[:list] != false
106
+
107
+ # Find all _revision files
108
+ if @options[:hudsonAuto] != nil then
109
+ dirs = runCmd('find . -name "*_revision" -type f | while read dir; do '+
110
+ 'dirname "$dir"; done | sort -u', true).split("\n")
111
+ @options[:hudson] = @options[:hudson].concat(dirs)
112
+ end
113
+
114
+ # File to only store the valid rev files
115
+ @options[:revFileList] = []
116
+
117
+ @options[:hudson].each(){|revfile|
118
+ if File.exist?(revfile) && File.directory?(revfile) then
119
+ puts "INFO: Looking at directory '#{revfile}' for dependencies..."
120
+ @options[:revFileList] +=
121
+ Dir.entries(revfile).map() { |file|
122
+ if !File.file?(revfile + "/" + file) || file !~ /.*_revision$/ then
123
+ nil
124
+ else
125
+ revfile + "/" + file
126
+ end
127
+ } .compact()
128
+ elsif File.exist?(revfile) == false then
129
+ puts "INFO: Revision file #{revfile} does not exist. Skipping...."
130
+ else
131
+ @options[:revFileList].push(revfile)
132
+ end
133
+ }
134
+
135
+ #Select the right --latest
136
+ if @options[:latest] == true then
137
+ begin
138
+ packages = env.getPackages(downloader ,@options[:branch], 1)
139
+ latest = packages[0]
140
+ puts "Latest version is:\n\t" + latest.to_s
141
+ WorkEnvs::Confirm.new("Do you want to update with this version?")
142
+ @options[:sha1] = latest.sha1
143
+ rescue WorkEnvs::EmptyQueryException => e
144
+ raise e if @options[:flags][:ignore_empty] != true
145
+ end
146
+ end
147
+
148
+ # Convert package name to actual version
149
+ if @options[:version] != nil
150
+ @options[:infos].push_name(env, @options[:version])
151
+ end
152
+ #Convert SHA1 to actual version
153
+ if @options[:sha1] != nil
154
+ @options[:infos].push_sha1(env, @options[:sha1])
155
+ end
156
+
157
+ # Fetch copy env dependencies
158
+ if @options[:copyEnv] != nil then
159
+ copy_env = WorkEnvs::loadEnvPath(@options[:copyEnv])
160
+ if copy_env.deps_infos == nil || copy_env.deps_infos.empty? == true then
161
+ puts "WARNING: env_config provided contains no environment description (Either too old or env is empty..)"
162
+ else
163
+ @options[:infos].concat(copy_env.deps_infos)
164
+
165
+ if copy_env.setup_options != nil then
166
+ @options[:envOpts].concat(copy_env.setup_options)
167
+ end
168
+ end
169
+ end
170
+
171
+ viableClassList = WorkEnvs::familyTreeList(env) if env != nil
172
+
173
+ # Add deps provided by hudson options
174
+ @options[:revFileList].each(){|revfile|
175
+ @options[:infos].partialEnv = true
176
+
177
+ optsKey = :infos
178
+
179
+ fileName = File.basename(revfile)
180
+ envClasses = WorkEnvs::revFileToClasses(fileName)
181
+ if envClasses == nil
182
+ STDERR.puts("WARNING: Unknown rev file type '#{fileName}'. Ignoring...")
183
+ next
184
+ end
185
+ revision = runCmd("cat #{revfile}", true).split("\n")[0]
186
+ raise("Invalid revision '#{revision}' in #{revfile}") if revision !~ /^[a-f0-9]{40}$/
187
+
188
+ WorkEnvs::dputs("Looking at rev file: '#{revfile}")
189
+ process_classes(env, envClasses, revision, viableClassList)
190
+ @rev_files << { :file => revfile, :revision => revision, :envClasses => envClasses }
191
+ }
192
+ @options[:sub_sha1].each(){|str|
193
+ @options[:infos].partialEnv = true
194
+
195
+ type, revision = str.split(':')
196
+
197
+ envClasses = nil
198
+ if type[0] == "+"
199
+ fileName = type[1..-1]
200
+ envClasses = WorkEnvs::revFileToClasses(fileName)
201
+ else
202
+ envClasses = [ WorkEnvs::stringToEnvClass(type) ]
203
+ end
204
+
205
+ if envClasses == nil || envClasses[0] == nil then
206
+ STDERR.puts "WARNING: Unknown env type '#{type}'. Skipping..."
207
+ next
208
+ end
209
+ process_classes(env, envClasses, revision, viableClassList)
210
+ }
211
+
212
+ # Flush data to global options
213
+ return @options[:flags], @options[:infos], @options[:infos_extra], @options[:envOpts]
214
+ end
215
+
216
+ # Returns an array of hash containing
217
+ # * :file => name of the rev file
218
+ # * :revision => SHA1 in the rev file
219
+ # * :envClasses => List of Classes using this rev file
220
+ def getRevFiles()
221
+ return @rev_files
222
+ end
223
+
224
+ # Add dependencies to a revision on a list of env Classes
225
+ #
226
+ # - env is the top env we are looking at
227
+ # - envClasses is an array of env Classes that share the same revision
228
+ # - revision is the SHA1 to use for the dependency
229
+ # - viableClassList is a list of all env Class that are parents to env
230
+ #
231
+ # For each class in envClasses, the dependency is pushed in the Dependencies
232
+ # object @options[ :infos] or @options [ :infos_extra ] depending on
233
+ # the class being a viable class or not
234
+ def process_classes(env, envClasses, revision, viableClassList)
235
+ envClasses.each(){|envClass|
236
+ optsKey = :infos
237
+ envType = WorkEnvs::getEnvType(envClass)
238
+
239
+ if env != nil && viableClassList.index(envClass) == nil then
240
+ STDERR.puts("WARNING: Cannot checkout a #{envType} in "+
241
+ "a #{env.type} environment. Ignoring...")
242
+ optsKey = :infos_extra
243
+ end
244
+
245
+ added = @options[optsKey].push_sha1(envClass, revision, false)
246
+ if added
247
+ puts "Add dependency '#{@options[optsKey].get_version(envType)}' for envType #{envType}" if VERBOSE == true
248
+ elsif optsKey != :infos_extra
249
+ puts "WARNING: Could not find version associated to SHA1 #{revision}"
250
+ end
251
+ }
252
+ end
253
+ private :process_classes
254
+
255
+ # Display a list of possible top packages to use with --sha1 or --version
256
+ # and exit
257
+ #
258
+ # Throws EmptyQueryException if no package was found
259
+ def list_versions(env, downloader)
260
+ qty = WORK_ENV_DEF_LIST_SIZE.to_i
261
+ case @options[:list]
262
+ when nil
263
+ qty = WORK_ENV_DEF_LIST_SIZE.to_i
264
+ when "all"
265
+ qty = 0
266
+ else
267
+ qty = @options[:list].to_i
268
+ end
269
+ begin
270
+ env.listPackages(downloader, qty, @options[:branch])
271
+ rescue WorkEnvs::EmptyQueryException => e
272
+ raise e if @options[:flags][:ignore_empty] != true
273
+ end
274
+ exit 0
275
+ end
276
+ private :list_versions
277
+ end
278
+ end
@@ -0,0 +1,10 @@
1
+ require_relative 'Common/Defines'
2
+ require_relative 'Common/Config'
3
+ require_relative 'Common/VersionSelector'
4
+ require_relative 'Common/Arch'
5
+ require_relative 'Common/DBInterface'
6
+ require_relative 'Common/PackageDownloader'
7
+ require_relative 'Common/Dependencies'
8
+ require_relative 'Common/EnvOpts'
9
+ require_relative 'Common/Confirm'
10
+ require_relative 'Common/Package'