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,749 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'pathname'
3
+
4
+
5
+ module WorkEnvs
6
+
7
+ # DEBUG mode.
8
+ #
9
+ # Enabled by ENV["DEBUG"] is set
10
+ DEBUG = ((ENV["DEBUG"] != nil) ? true: false)
11
+
12
+ # Array of all supported Environment classes
13
+ ENV_TYPES = WorkEnvs.constants.delete_if {|c|
14
+ theObject = WorkEnvs.const_get(c)
15
+ !(Class === theObject) ||
16
+ getEnvType(theObject) == nil
17
+ }.map(){|x| WorkEnvs.const_get(x)}
18
+
19
+ @@checkedUpdates = false
20
+ @@checkedEnvs = false
21
+
22
+ # Debug print macro.
23
+ # * Only prints if DEBUG=1
24
+ # * Print backtrace if bt == true
25
+ def dputs(str, bt = false)
26
+ return if DEBUG != true
27
+
28
+ puts "DEBUG: " + str
29
+ if bt == true then
30
+ puts caller
31
+ end
32
+ end
33
+ module_function :dputs
34
+
35
+ # More complete check of the WorkEnvs
36
+ # Mostly checks for coherency error within the ruby scripts themselves.
37
+ #
38
+ # This is not called automatically, unless DEBUG is set
39
+ def selfCheckFull()
40
+ return if !DEBUG
41
+ #Check that the envClass really redefined itself
42
+ global = {
43
+ :types => {},
44
+ :main => {}
45
+ }
46
+
47
+ ENV_LIST.each(){|e|
48
+ envClass = WorkEnvs.const_get(e + "Env")
49
+ type = getEnvType(envClass)
50
+ raise("Both #{global[:types][type]} and #{envClass} use environment type '#{type}'") if global[:types][type] != nil && type != :dev
51
+ global[:types][type] = envClass
52
+
53
+ mains = getMainPackage(envClass)
54
+ mains.each(){|main|
55
+ if global[:main][main] != nil then
56
+ STDERR.puts "WARNING: Both #{global[:main][main]} and #{envClass} use the same main package '#{main}'"
57
+ end
58
+ global[:main][main] = envClass
59
+ }
60
+ }
61
+
62
+ end
63
+ module_function :selfCheckFull
64
+
65
+ # WorkEnvs global safety checks
66
+ # and eventual self update
67
+ def checkEnvs(force_update = false)
68
+ return if @@checkedEnvs == true
69
+ # Check required thing that would break everything
70
+ # Autocalled on requiring this file so no worries
71
+ selfCheckFull() if DEBUG == true
72
+
73
+ if !File.directory?(WORK_ENVS) then
74
+ STDERR.puts "#{WORK_ENVS} needs to be created to use Work Environments"
75
+ STDERR.puts "Please run: mkdir -p #{WORK_ENVS}"
76
+ raise("Missing #{WORK_ENVS}")
77
+ end
78
+ if !File.directory?(WORK_ENV_CACHE_DIR) then
79
+ runCmd("mkdir -p #{WORK_ENV_CACHE_DIR}", !VERBOSE)
80
+ end
81
+ @@checkedEnvs = true
82
+ end
83
+ module_function :checkEnvs
84
+
85
+ # Get the name of the current environment
86
+ def getCurrentEnvName()
87
+ return ENV["WORK_ENV_CURRENT"]
88
+ end
89
+ module_function :getCurrentEnvName
90
+
91
+ # Get path to the current environment
92
+ def getCurrentEnvPath()
93
+ return ENV["WORK_ENV_PATH"]
94
+ end
95
+ module_function :getCurrentEnvPath
96
+
97
+ # Get the list of all dirs to store envs
98
+ #
99
+ # Return a hash (label | :default) => dirpath
100
+ def getDirList()
101
+ settings = settings()
102
+ dirs = { :default => WORK_ENVS }
103
+
104
+ settings[:global][:custom_env_dirs].each{|name, dirpath|
105
+ next if !File.exist?(dirpath)
106
+ dirs[name] = dirpath
107
+ }
108
+ return dirs
109
+ end
110
+ module_function :getDirList
111
+
112
+ # Get the top dir of an env from its label
113
+ def getDirPathFromLabel(label)
114
+ return WORK_ENVS if label.to_s() == "" || label == :default
115
+
116
+ settings[:global][:custom_env_dirs].each{|d_label, dirpath|
117
+ return dirpath if d_label == label
118
+ }
119
+ raise("Invalid wenv directory label '#{label}'")
120
+ end
121
+ module_function :getDirPathFromLabel
122
+
123
+ # Get the label top dir from its path
124
+ def getDirLabelFromPath(path)
125
+ settings[:global][:custom_env_dirs].each{|label, dirpath|
126
+ return label if dirpath == path
127
+ }
128
+ return nil
129
+ end
130
+ module_function :getDirLabelFromPath
131
+
132
+ # Extract label and name from an env name string
133
+ #
134
+ # Format is label::name
135
+ #
136
+ # Returns label,name
137
+ #
138
+ # If the env is in the default dir, label=nil
139
+ def strToLabelName(str)
140
+ a = str.split("::")
141
+ env_name = str
142
+ label = nil
143
+ if a.length > 1 then
144
+ env_name = a[1]
145
+ label = a[0]
146
+ end
147
+ return label,env_name
148
+ end
149
+ module_function :strToLabelName
150
+
151
+ # Generate an env name string from a label and the env name
152
+ #
153
+ # Returns a string with the full name
154
+ def labelNameToStr(label, name)
155
+ if label.to_s() == "" || label == :default
156
+ return name
157
+ else
158
+ return label.to_s() + "::" + name.to_s()
159
+ end
160
+ end
161
+ module_function :labelNameToStr
162
+
163
+ # Check if the name match a valid environment
164
+ #
165
+ # This returns true wheteher the environment is switchable or not
166
+ def isEnv?(name)
167
+ checkEnvs()
168
+ # Does this name matches a valid environment
169
+ label, name = strToLabelName(name)
170
+
171
+ confFile = getDirPathFromLabel(label) + "/" + name + "/" + ENV_CONF
172
+ # Skip unconfigured envs
173
+ return false if !File.exist?(confFile)
174
+ return true
175
+ end
176
+ module_function :isEnv?
177
+
178
+ # Load environment from its name using loadEnv
179
+ #
180
+ # name MUST be a valid environment
181
+ def getEnv(name)
182
+ checkEnvs()
183
+ label, name = strToLabelName(name)
184
+
185
+ # Create an workEnv object (from it's file) using its name (must be valid)
186
+ path = getDirPathFromLabel(label) + "/" + name + "/" + ENV_CONF
187
+ env = loadEnvPath(path)
188
+ env.label = label if env != nil
189
+ return env
190
+ end
191
+ module_function :getEnv
192
+
193
+ def YAMLLoad(data)
194
+
195
+ begin
196
+ return YAML::load(data)
197
+ rescue Psych::DisallowedClass
198
+ # If data is a file, don't forget to rewind back to its beginning
199
+ data.rewind() if data.is_a?(File)
200
+ y = YAML::load(data,
201
+ permitted_classes:
202
+ ENV_LIST.map(){|x| WorkEnvs.const_get(x+ "Env") } +
203
+ [ WorkEnvs::EnvOpts, Symbol ])
204
+ end
205
+ end
206
+ module_function :YAMLLoad
207
+
208
+ # Load environment from a YAML file
209
+ # * Path points to a YAML description file
210
+ # * Environment are self migrated on load
211
+ def loadEnvPath(path)
212
+ migrate = false
213
+ desc = File.open(path, "r")
214
+ begin
215
+ env = YAMLLoad(desc)
216
+ rescue => e
217
+ raise("Failed to load environment description for environment '#{path}': #{e}")
218
+ end
219
+ desc.close()
220
+
221
+ #Check for broken Envs
222
+ expectedName = File.basename(File.dirname(path))
223
+ if env.name != expectedName then
224
+ STDERR.puts "ERROR: Environment internal name does not match directory name..."
225
+ STDERR.puts "ERROR: Directory name is '#{expectedName}'. Internal name is '#{env.name}'"
226
+ rep = 't'
227
+ while rep != "y" && rep != "n" && rep != '' do
228
+ puts "Do you wish to update this environment internal name to '#{expectedName} ? (y/N): "
229
+ rep = STDIN.gets.chomp()
230
+ end
231
+ if rep == "y" then
232
+ env.name = expectedName
233
+ env.dump()
234
+ else
235
+ raise("Cannot continue until this environment name is fixed or #{File.dirname(path)} is moved outside #{WORK_ENVS}.")
236
+ end
237
+ end
238
+
239
+ #Update the env if necessary
240
+ env = env.migrate()
241
+
242
+ return env
243
+ end
244
+ module_function :loadEnvPath
245
+
246
+ # Return the current environment object
247
+ def getCurrentEnv()
248
+ # Return the current environment in we are in one
249
+
250
+ envName = getCurrentEnvName()
251
+ if envName == nil || envName == "" then
252
+ STDERR.puts "No current environment"
253
+ return nil
254
+ end
255
+ dirpath = File.dirname(getCurrentEnvPath())
256
+ label = getDirLabelFromPath(dirpath)
257
+ name_str = labelNameToStr(label, envName)
258
+ if !isEnv?(name_str)
259
+ STDERR.puts "'#{curEnv} is not a valid environment"
260
+ return nil
261
+ end
262
+ # Load environment
263
+ return getEnv(name_str)
264
+ end
265
+ module_function :getCurrentEnv
266
+
267
+ # Return an array of all existing environments object
268
+ def getEnvs()
269
+ checkEnvs()
270
+ settings = settings()
271
+
272
+ envs=[]
273
+ dirs = getDirList()
274
+ dirs.each(){|label, dirpath|
275
+ Dir.foreach(dirpath).sort().each() {|dirname|
276
+ # Skip hidden directories
277
+ next if dirname[0] == "."
278
+
279
+ # Skip bad environment
280
+ next if !isEnv?(labelNameToStr(label, dirname))
281
+
282
+ # Load environment
283
+ begin
284
+ envs << getEnv(labelNameToStr(label, dirname))
285
+ rescue => e
286
+ # Environment might be broken. Skip
287
+ puts e.to_s
288
+ next
289
+ end
290
+ }
291
+ }
292
+ return envs
293
+ end
294
+ module_function :getEnvs
295
+
296
+ # Return an array of all existing environments names
297
+ def getEnvNames()
298
+ settings = settings()
299
+ envs = []
300
+ dirs = getDirList()
301
+ dirs.each(){|label, dirpath|
302
+ Dir.foreach(dirpath).sort().each() {|dirname|
303
+ # Skip hidden directories
304
+ next if dirname[0] == "."
305
+
306
+ # Skip bad environment
307
+ next if !isEnv?(labelNameToStr(label, dirname))
308
+ envs << dirname
309
+ }
310
+ }
311
+ return envs
312
+ end
313
+ module_function :getEnvNames
314
+
315
+ # Check if 'type' is a valid environment type
316
+ #
317
+ # type can either be String or Symbol
318
+ def isValidType?(type)
319
+ envTypes = listEnvTypes()
320
+ return false if envTypes[type.to_sym()] == nil
321
+ return true
322
+ end
323
+ module_function :isValidType?
324
+
325
+ # Check if 'name' is a valid environment name
326
+ def isValidName?(name)
327
+ # Can the name be used for an environment
328
+ return false if name !~ /^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/
329
+ return true
330
+ end
331
+ module_function :isValidName?
332
+
333
+ # Check if we can safely switch to an environment from its name
334
+ #
335
+ # This checks that the environment has contents (unless it's a dev environment),
336
+ # and that the versions of the files within the environment are the
337
+ # versions expected
338
+ #
339
+ # 'name' must be a valid name.
340
+ def isSwitchable?(name)
341
+
342
+ # Load the environment object
343
+ env = getEnv(name)
344
+
345
+ # Check that all required packages are initialized
346
+ return env.isSwitchable?()
347
+ end
348
+ module_function :isSwitchable?
349
+
350
+ # Convert en environment type (Symbol or String) to the
351
+ # associated environment Class
352
+ #
353
+ # Returns nil if none or multiple environment match
354
+ def symbolToClass(name)
355
+ envClass = listEnvs().select {|c|
356
+ getEnvType(c) == name.to_sym()
357
+ }
358
+ return nil if envClass == nil || envClass.length != 1
359
+ return envClass[0]
360
+ end
361
+ module_function :symbolToClass
362
+
363
+ # Returns an array of environment class that use
364
+ # 'file' as theuir REV_FILE
365
+ #
366
+ # Returns nil if no environment matches
367
+ def revFileToClasses(file)
368
+ name = File.basename(file)
369
+ envClasses = listEnvs().select {|c|
370
+ getRevFile(c) == name
371
+ }
372
+
373
+ return nil if envClasses == nil || envClasses.length == 0
374
+ return envClasses
375
+ end
376
+ module_function :revFileToClasses
377
+
378
+ # Add all env specific options to the opt Parser
379
+ # so it shows up in the usage
380
+ def addEnvToOptParser(optsParser)
381
+ envHash = listEnvTypes()
382
+ optsParser.separator "Environment Types:"
383
+ envHash.each(){|sym, tClass|
384
+ legend = getEnvDescription(tClass)
385
+ char='-'
386
+ char='*' if sym.to_s == WORK_ENV_DEFAULT_TYPE
387
+ optsParser.separator(" #{char} " + sym.to_s.ljust(59) + legend)
388
+ }
389
+ end
390
+ module_function :addEnvToOptParser
391
+
392
+ # Return an array of all environment classes
393
+ def listEnvs()
394
+ return ENV_TYPES
395
+ end
396
+ module_function :listEnvs
397
+
398
+ # Return a hash containing environment type => environment class
399
+ def listEnvTypes()
400
+ envClass = listEnvs()
401
+ envHash = {}
402
+ envClass.each(){|theClass|
403
+ envHash[getEnvType(theClass)] = theClass
404
+ }
405
+ return envHash
406
+ end
407
+ module_function :listEnvTypes
408
+
409
+ # Create a memory instance of an environment
410
+ #
411
+ # * name: instance name
412
+ # * type: environment type
413
+ # * machine: hash returned by getArch() to configure the environment
414
+ # host/arch
415
+ # * release: Name of the default table in the DB to search for versions
416
+ #
417
+ # All environment are checked for validity
418
+ # Return a pointer to a BasicEnv object on success
419
+ def instantiateEnv(name, type, machine, release)
420
+ label, name = strToLabelName(name)
421
+ envClass = stringToEnvClass(type)
422
+ env = envClass.new(name, machine, release)
423
+ env.label = label
424
+ return env
425
+ end
426
+ module_function :instantiateEnv
427
+
428
+ # Return if an environment with this name exists
429
+ def existsEnv?(name)
430
+ checkEnvs()
431
+ label, name = strToLabelName(name)
432
+ dirpath = getDirPathFromLabel(label)
433
+ return File.exist?(dirpath + "/" + name) && File.exist?(dirpath + "/" + name + "/" + ENV_CONF)
434
+ end
435
+ module_function :existsEnv?
436
+
437
+ # Create an environment.
438
+ #
439
+ # * Instantiate a environment using instantiatEnv
440
+ # * Saves it on disk
441
+ def createEnv(name, type, release)
442
+ checkEnvs()
443
+ raise("Environment already exists") if existsEnv?(name) == true
444
+ env = instantiateEnv(name, type, nil, release)
445
+ dirpath = getDirPathFromLabel(env.label)
446
+
447
+ Dir.mkdir(dirpath + "/" + env.name)
448
+ env.dump()
449
+ return env
450
+ end
451
+ module_function :createEnv
452
+
453
+ # Generic code to support version selection in the opt parser
454
+ #
455
+ # * --sha1/--version
456
+ # * --hudson/--hudson-auto
457
+ # * --sub-sha1
458
+ # * --list/--latest
459
+ # * etc...
460
+ #
461
+ # Instantiate a #VersionSelector
462
+ def versionSelectorPrepare(opts, optsParser)
463
+ opts[:version_selector] = VersionSelector.new(opts, optsParser)
464
+ end
465
+ module_function :versionSelectorPrepare
466
+
467
+ # Post-Process #VersionSelector options by calling finalize()
468
+ def versionSelectorFinal(opts, env)
469
+ raise("Internal error") if opts[:version_selector] == nil
470
+ flags, opts[:infos], opts[:infos_extra], envOpts = opts[:version_selector].finalize(opts, env)
471
+ opts[:envOpts] = opts[:envOpts].concat(envOpts)
472
+ opts.merge!(flags)
473
+ end
474
+ module_function :versionSelectorFinal
475
+
476
+ # Remove an env from its full name (label and name)
477
+ #
478
+ # BEWARE: No confirmation !
479
+ def deleteEnv(name)
480
+ # Delete an existing environment completely !!!
481
+ label, name = strToLabelName(name)
482
+ dirpath = getDirPathFromLabel(label)
483
+ runCmd("chmod -R +w #{dirpath + "/" + name}", !VERBOSE)
484
+ runCmd("rm -Rf #{dirpath + "/" + name}", !VERBOSE)
485
+ end
486
+ module_function :deleteEnv
487
+
488
+ # Return a header to display environment lists
489
+ def listHeader()
490
+ maxLen = getEnvNames().inject(0){|x, y| x > y.length ? x : y.length}
491
+ return "Name".ljust(maxLen + 2) + "Type".center(20) + "Machine".center(15) +
492
+ "Expiration".center(15)
493
+ end
494
+ module_function :listHeader
495
+
496
+ # Return an array of all the parent env Classes of an envClass (including itself)
497
+ #
498
+ # if no_recurse is set, only return the envClass provided
499
+ def familyTreeListClass(objClass, no_recurse = false)
500
+ if no_recurse == true
501
+ return [ objClass ]
502
+ end
503
+
504
+ classList=[ ]
505
+ tmpList=[ objClass ]
506
+ hasBaseClass = false
507
+
508
+ while tmpList.length != 0
509
+ obj = tmpList.shift()
510
+
511
+
512
+ # Delete object first so that if it exits, we will retain the version
513
+ # that is the highest in the dep tree so all the analysis dependency
514
+ # should be done in the right order
515
+ classList.delete(obj)
516
+
517
+ classList.push(obj)
518
+ hasBaseClass = true if obj == BasicEnv
519
+
520
+ getParents(obj).each(){|parent|
521
+ tmpList.push(parent)
522
+ }
523
+ end
524
+
525
+ classList.push(BasicEnv) if hasBaseClass == false
526
+ return classList
527
+ end
528
+ module_function :familyTreeListClass
529
+
530
+ # Return an array of all the parent env Classes of an env (including the env class itself)
531
+ #
532
+ # Calls #familyTreeListClass
533
+ def familyTreeList(obj, no_recurse = false)
534
+ return familyTreeListClass(obj.class, no_recurse)
535
+ end
536
+ module_function :familyTreeList
537
+
538
+ # Calls a code block on each parent env Class of an env Class (including itself)
539
+ #
540
+ # If reverse is true, call from ancestors to children
541
+ def familyTreeApplyClass(objClass, reverse = false, no_recurse = false, &f)
542
+ classList = familyTreeListClass(objClass, no_recurse)
543
+
544
+ if reverse == false then
545
+ classList.each(){|objClass|
546
+ yield objClass
547
+ }
548
+ else
549
+ while ! classList.empty? do
550
+ objClass = classList.pop()
551
+ yield objClass
552
+ end
553
+ end
554
+
555
+ end
556
+ module_function :familyTreeApplyClass
557
+
558
+
559
+ # Calls a code block on each parent env Class of an env (including the env class itself)
560
+ #
561
+ # If reverse is true, call from ancestors to children
562
+ #
563
+ # Calls #familyTreeApplyClass
564
+ def familyTreeApply(obj, reverse = false, no_recurse=false, &f)
565
+ familyTreeApplyClass(obj.class, reverse, no_recurse){|_class| yield _class }
566
+ end
567
+ module_function :familyTreeApply
568
+
569
+ # Returns an array of all the env Classes that share the same repository as objClass
570
+ def exploreSiblings(objClass)
571
+ envClass = envToClass(objClass)
572
+ repo = getGitRepo(objClass)
573
+ return [ envClass ] if repo == ""
574
+
575
+ begin
576
+ return listEnvs().map{|e| getGitRepo(e) == repo ? e : nil}.compact()
577
+ rescue
578
+ return [ envClass ]
579
+ end
580
+ end
581
+ module_function :exploreSiblings
582
+
583
+ # Look in entries for string that starts with str
584
+ #
585
+ # Returns:
586
+ # - the first match
587
+ # - a list of all matches
588
+ def matchPrefix(entries, str)
589
+ full_name = []
590
+ entries.each(){|ent|
591
+ next if ent !~ /^#{str}/
592
+ full_name << ent
593
+ }
594
+ return full_name[0], full_name
595
+ end
596
+ module_function :matchPrefix
597
+
598
+ # Look in entries for string that contains with str
599
+ #
600
+ # Returns:
601
+ # - the first match
602
+ # - a list of all matches
603
+ def matchExp(entries, str)
604
+ full_name = []
605
+ entries.each(){|ent|
606
+ next if ent !~ /#{str}/
607
+ full_name << ent
608
+ }
609
+ return full_name[0], full_name
610
+ end
611
+ module_function :matchExp
612
+
613
+ # Exception when the provided name matches more than one environment
614
+ class EnvNameErrorException < StandardError
615
+ # Constructor
616
+ #
617
+ # - str: string provided on the command line
618
+ # - matches: array of environment names that matches
619
+ def initialize(str, matches)
620
+ if matches.length == 0 then
621
+ super("'#{str}' match no environment")
622
+ else
623
+ super("'#{str}' match multiple environments: #{matches.join(", ")}")
624
+ end
625
+ end
626
+ end
627
+
628
+ # Exception when no environment name has been provided
629
+ class EnvNoNameErrorException < StandardError
630
+ # Default constructor
631
+ def initialize()
632
+ super("No environment name provided")
633
+ end
634
+ end
635
+
636
+ # Exception when no environment name has been provided
637
+ class EnvNoTypeErrorException < StandardError
638
+ # Default constructor
639
+ def initialize()
640
+ super("No environment type provided")
641
+ end
642
+ end
643
+
644
+ # Exception when no environment name has been provided
645
+ class EnvTypeErrorException < StandardError
646
+ # Constructor
647
+ #
648
+ # - str: string provided on the command line
649
+ def initialize(str)
650
+ super("Environment type '#{str}' is invalid")
651
+ end
652
+ end
653
+
654
+ # Environment name expansion
655
+ #
656
+ # Return the name of an existing environment if 'str' matches at most 1
657
+ # existing environment
658
+ def nameToEnvName(str)
659
+ raise EnvNoNameErrorException if str.to_s == ""
660
+
661
+ return str if isEnv?(str)
662
+
663
+ envs = getEnvs().map(){|x| x.name}
664
+ completeName, matches = matchPrefix(envs, str)
665
+ if matches.length == 0 then
666
+ completeName, matches = matchExp(envs, str)
667
+ end
668
+
669
+ if matches.length != 1 then
670
+ exp = EnvNameErrorException.new(str, matches)
671
+ raise exp
672
+ end
673
+ puts "INFO: Env name '#{str}' matches environment '#{completeName}'"
674
+ return completeName
675
+ end
676
+ module_function :nameToEnvName
677
+
678
+ # Serialize an object to be returns to a calling RPC process through logs
679
+ #
680
+ # Returns a string of the serialized object
681
+ def serialize(str)
682
+ return ":B64_OBJ:" + Base64.encode64(str.to_yaml()).gsub("\n", '') + ":/B64_OBJ:"
683
+ end
684
+ module_function :serialize
685
+
686
+ #Regexp to extract B64 Objects encoded in RPC result
687
+ B64_OBJ_REGXP = /:B64_OBJ:([A-Za-z0-9+\/=]*):\/B64_OBJ:/
688
+
689
+ # Returns an array with all the objects encoded in Base64 within the provided string
690
+ def deserialize(str)
691
+ return str.scan(B64_OBJ_REGXP).map(){|x|
692
+ YAMLLoad(Base64.decode64(x[0].gsub(B64_OBJ_REGXP, '\1')))
693
+ }
694
+ end
695
+ module_function :deserialize
696
+
697
+ # Run a remote Wenv action 'action' with option_str as options.
698
+ #
699
+ # host_str format is [user@]host[:/path/to/wenv]
700
+ #
701
+ # Returns an (array of returned RPC objects, logs without RPC)
702
+ def remoteRun(host_str, action, option_str)
703
+ args=host_str.split(":")
704
+ host=args[0]
705
+ path=""
706
+ path=args[1] + "/" if args.length == 2
707
+ ret = runCmd("ssh -t -t -o StrictHostKeyChecking=no "+
708
+ "#{host} #{path}wenv #{action} #{option_str}", !VERBOSE)
709
+ return deserialize(ret), ret.gsub(B64_OBJ_REGXP, "")
710
+ end
711
+ module_function :remoteRun
712
+
713
+ # Convert a string from CLI to an env Class
714
+ #
715
+ # String is normalement (lower first char) and converted to a label then matched against
716
+ # ENV_TYPE of each env class
717
+ def stringToEnvClass(type)
718
+ normalized_typename = type.to_s.slice(0,1).downcase + type.to_s.slice(1..-1)
719
+ raise EnvTypeErrorException.new(type) if ! isValidType?(type)
720
+
721
+ # Create a new environment or raise an exception if parameters are invalid
722
+ env = nil
723
+ envClass = symbolToClass(normalized_typename)
724
+ raise("Ooops. Failed to generate envClass. Contact support !") if envClass == nil
725
+ return envClass
726
+ end
727
+ module_function :stringToEnvClass
728
+
729
+ # Return a list of all the packages (including internal, temporary, extras)
730
+ # listed in an env Class
731
+ def listAllPackages(objClass)
732
+ getPackages(objClass).values.inject([]){|p, x|
733
+ p + x.values.inject([]){|q, c|
734
+ q+c.map(){|d| d.to_s}
735
+ }
736
+ }
737
+ end
738
+ module_function :listAllPackages
739
+
740
+ # Return a list of all the packages (including internal, temporary, extras)
741
+ # listed in an env Class and its siblings
742
+ def listAllPackagesWithSiblings(objClass)
743
+ return exploreSiblings(objClass).inject([]) { |r, sibling |
744
+ r + listAllPackages(sibling)
745
+ }.uniq
746
+ end
747
+ module_function :listAllPackagesWithSiblings
748
+ end
749
+