rumodule 0.0.3

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.
data/bin/rumodule ADDED
@@ -0,0 +1,1069 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'como'
4
+ include Como
5
+ require_relative '../lib/version'
6
+
7
+
8
+ Spec.command( 'rumodule', 'Tero Isannainen', '2014', [
9
+ [ :exclusive, 'doc', '-d', "Documentation." ],
10
+ [ :opt_single, 'shell', '-s', "Shell." ],
11
+ [ :single, 'command', '-c', "Command." ],
12
+ [ :opt_multi, 'module', '-m', "Modules to load." ],
13
+ ], {
14
+ :header => "\n rumodule - Shell env module manager, v#{RumoduleMod.version}\n\n"
15
+ } )
16
+
17
+
18
+ # Define option combinations.
19
+ Spec.checkRule do
20
+ one(
21
+ 'doc',
22
+ incr( 'command', 'module' ))
23
+ end
24
+
25
+
26
+ # Documentation for Rumodule.
27
+ if Opt['doc'].given
28
+
29
+ puts %q{
30
+ = Content
31
+
32
+ * Introduction
33
+ * Command Line Usage
34
+ * Rumodule File Commands
35
+ * Shell Function
36
+ * Environment Setup
37
+ * Summary
38
+
39
+
40
+ = Introduction
41
+
42
+ Rumodule is used to manage shell environment variables by
43
+ adding/removing modules. By adding a module using Rumodule, for
44
+ example the PATH environment variable can be setup so that the
45
+ executable is found.
46
+
47
+ Modules exist per tool or per tool version. Rumodule makes it easy
48
+ to maintain and provide tool setups between multiple users.
49
+
50
+ The commands are called User Commands. Modules are called Rumodule
51
+ files and they include Rumodule File Commands.
52
+
53
+ Rumodule refers to modules through RUMODULE environment
54
+ variable. RUMODULE includes a list of directories where Rumodule
55
+ Files reside.
56
+
57
+ Rumodule command is not convenient to be used directly. The user
58
+ should setup a shell function which is used to utilize Rumodule.
59
+ Recommended name is "rumo". See: Shell Function.
60
+
61
+ Supported shells: zsh, sh, bash, fish
62
+
63
+
64
+ = Command Line Usage
65
+
66
+ == Overview
67
+
68
+ The most common User Commands are: "add" and "rm". "add" adds
69
+ modules content to the shell environment and "rm" removes the same
70
+ content (or its effects).
71
+
72
+ Execution examples:
73
+ rumo add my_module
74
+ rumo rm my_module
75
+
76
+ Other common commands are "list" and "avail". "list" displays a list
77
+ of loaded modules and "avail" lists all modules found, defined by
78
+ the RUMODULE env variable.
79
+
80
+
81
+ == List of User Commands
82
+
83
+ * add: add (load) one or many modules
84
+ * sadd: add (load) one or many system modules
85
+ * rm: remove (unload) one or many modules
86
+ * srm: remove (unload) one or many system modules
87
+ * list: list loaded modules
88
+ * slist: list loaded system modules
89
+ * which: display module that would be selected from module directory
90
+ * display: display module content
91
+ * avail: list all available modules
92
+ * savail: list all available modules (including system modules)
93
+ * help: display rumodule commands or module help if module given
94
+
95
+
96
+
97
+ = Rumodule File Commands
98
+
99
+ == Overview
100
+
101
+ The Rumodule files include commands to setup a tool for
102
+ usage. Rumodule files are normal Ruby files, except a set of
103
+ Rumodule commands are available in the top namespace. The Rumodule
104
+ File Commands are semantically defined for the "add" command. For
105
+ "rm" they have the opposite meaning.
106
+
107
+ The most common commands are "setenv", "append_path", and
108
+ "prepend_path".
109
+
110
+ "append_path" adds an entry to the end of existing env variable (or
111
+ new is created). "prepend_path" adds an entry to the beginning of
112
+ existing env variable. New var is created if it doesn't exist.
113
+
114
+ New env variable is created with "setenv" command. Existing env
115
+ var can be removed with "unsetenv" command.
116
+
117
+ Rumodule example:
118
+ help( "This module is used for tool" )
119
+ tool_path = ENV['TOOL_PATH']
120
+ append_path( 'PATH', "#{tool_path}/bin" )
121
+ add( "tool_setup" )
122
+
123
+
124
+ == List of Rumodule File Commands
125
+
126
+ [ setenv( var, value ) ]
127
+ Set env var "var" to "value".
128
+
129
+ [ unsetenv( var ) ]
130
+ Unset env var "var".
131
+
132
+ [ append_path( var, value ) ]
133
+ Append "value" to env var "var".
134
+
135
+ [ prepend_path( var, value ) ]
136
+ Prepend "value" to env var "var".
137
+
138
+ [ remove_path( var, value ) ]
139
+ Remove "value" from env var "var".
140
+
141
+ [ pushenv( var, value ) ]
142
+ Set env var "var" to "value" and save the old value of "var" for
143
+ future. When module is removed, the old value is returned.
144
+
145
+ [ prereq( mod ) ]
146
+ Check that module "mod" is loaded, or abort. It is recommended to
147
+ check for other modules before performing any other operation
148
+ within the module command. Otherwise the Shell Function should
149
+ check for "rumodule" return codes, and prevent shell env changes
150
+ when aborting.
151
+
152
+ [ conflict( mod ) ]
153
+ Check that module "mod" is not loaded, or abort. See "prereq"
154
+ usage recommendations.
155
+
156
+ [ is_loaded( mod ) ]
157
+ Check if module "mod" is loaded.
158
+
159
+ [ add( mod ) ]
160
+ Add a module "mod" from Rumodule file.
161
+
162
+
163
+
164
+ = Shell Function
165
+
166
+ == Overview
167
+
168
+ Rumodule user must setup a shell function to use Rumodule
169
+ easily. Recommended name for the function is "rumo". The purpose of
170
+ the function is to map user arguments to "rumodule" command and pass
171
+ "rumodule" output to shell for evaluation. This enables the user
172
+ command to change the shell environment variable contents.
173
+
174
+ NOTE: If you are using a Ruby version which takes a long time to
175
+ load into memory, please consider referencing directly into suitable
176
+ Ruby version in "rumo".
177
+
178
+
179
+ == Shell Function examples
180
+
181
+ Setup "rumo" command for sh, zsh, or bash shells:
182
+ rumo () {
183
+ cmd=$1
184
+ shift
185
+ if test $# -gt 0; then
186
+ eval `rumodule -s zsh -c $cmd -m $*`
187
+ else
188
+ eval `rumodule -c $cmd`
189
+ fi
190
+ }
191
+
192
+ Setup "rumo" command for fish shell:
193
+ function rumo
194
+ if test (count $argv) -gt 1
195
+ set cmd (rumodule -s fish -c $argv[1] -m $argv[2..-1])
196
+ else
197
+ set cmd (rumodule -s fish -c $argv[1])
198
+ end
199
+ eval $cmd
200
+ end
201
+
202
+
203
+ = Environment Setup
204
+
205
+ Rumodule requires the RUMODULE env var to be set to the root
206
+ directory or directories where the Rumodule Files reside.
207
+
208
+ Lets assume the "$HOME/usr/share/rumodule" directory is used to
209
+ store the modules.
210
+
211
+ The directory content could be the following:
212
+ tool1
213
+ tool2
214
+ tool3/1.2.3
215
+ /1.2.6
216
+ tool4
217
+ system-
218
+
219
+ "tool1,2,4" are module files and "tool3" is a subdirectory including
220
+ module files "1.2.3" and "1.2.6". "system-" is a system module file,
221
+ which is visible only with "savail" command. System module files are
222
+ used to separate between compulsory module files vs user selectable.
223
+
224
+ "tool3" has two versions and it could be referred for example with:
225
+ rumo add tool3
226
+ rumo add tool3/1.2.6
227
+
228
+ If version is left out, Rumodule uses one of the version. The
229
+ selection is performed by first sorting the directory entries and
230
+ then selecting the last.
231
+
232
+ Usually the user should specify the actual version requested when
233
+ adding the module and when removing the directory is enough.
234
+
235
+ Rumodule files can be hidden from the system by using the "." prefix
236
+ to filename (as for "ls" shell utility").
237
+
238
+
239
+ = Summary
240
+
241
+ These steps are required to take Rumodule into use:
242
+
243
+ * Create Rumodule Files to dir.
244
+ * Set RUMODULE env var to dir.
245
+ * Setup rumo Shell Function.
246
+
247
+ }
248
+
249
+ # ' Fix ruby-mode coloring
250
+
251
+ exit( false )
252
+ end
253
+
254
+
255
+ # Check for working environment:
256
+ if ENV['RUMODULE'] == nil
257
+ STDERR.puts " User must define \"RUMODULE\" environment variable...\n See: rumodule -d"
258
+ exit( false )
259
+ end
260
+
261
+
262
+ # "home"-method.
263
+ module RumoduleMod
264
+
265
+ # Return home path.
266
+ def home
267
+ ENV['HOME']
268
+ end
269
+
270
+ end
271
+
272
+ include RumoduleMod
273
+
274
+
275
+ class RumoduleCommon
276
+
277
+ include RumoduleMod
278
+
279
+ # Shell constant.
280
+ if Opt['shell'].given
281
+ SHELL = Opt['shell'].value
282
+ else
283
+ SHELL = 'zsh'
284
+ end
285
+
286
+ end
287
+
288
+
289
+
290
+ # Environment variable that has been read from "unix" env.
291
+ class EnvVar < RumoduleCommon
292
+
293
+ # Variable name.
294
+ attr_reader :name
295
+
296
+ # Dirty flag indicates that the env has to be updated.
297
+ attr_reader :dirty
298
+
299
+ # EnvVar value.
300
+ attr_reader :value
301
+
302
+
303
+ # Check for "unix" var existance.
304
+ #
305
+ # @param name [String] Env var name to check.
306
+ # @return [String] Value or nil.
307
+ def EnvVar.exist?( name )
308
+ ENV[name]
309
+ end
310
+
311
+
312
+ # Initialize name, dirty and unset. If unset is true, then "unset"
313
+ # command is output to shell.
314
+ #
315
+ # @param name [String] Env var name.
316
+ # @param value [String] Value for Env var.
317
+ def initialize( name, value = nil )
318
+ @name = name
319
+ @dirty = false
320
+ @unset = false
321
+ if value
322
+ @value = value
323
+ else
324
+ @value = ENV[name].split(':')
325
+ end
326
+ end
327
+
328
+
329
+ # Set variable to a value.
330
+ #
331
+ # @param value [String] Value for Env var.
332
+ def set( value )
333
+ @dirty = true
334
+ @unset = false
335
+ @value = [ value ]
336
+ end
337
+
338
+
339
+ # Unset variable from env.
340
+ def unset
341
+ @dirty = true
342
+ @unset = true
343
+ @value = []
344
+ end
345
+
346
+
347
+ # Place new value infront of the path.
348
+ #
349
+ # @param value [String] Value for Env var.
350
+ def prepend_path( value )
351
+ @dirty = true
352
+ @unset = false
353
+ @value.unshift( value )
354
+ end
355
+
356
+
357
+ # Place new value at end of the path.
358
+ #
359
+ # @param value [String] Value for Env var.
360
+ def append_path( value )
361
+ @dirty = true
362
+ @unset = false
363
+ @value.push( value )
364
+ end
365
+
366
+
367
+ # Remove value from the path.
368
+ #
369
+ # @param value [String] Value to remove from Env var.
370
+ def remove_path( value )
371
+ @dirty = true
372
+ @unset = false
373
+ @value.delete( value )
374
+ end
375
+
376
+
377
+ # Remove value at index.
378
+ #
379
+ # @param idx [Integer] Value index used to remove from Env var.
380
+ def delete_index( idx )
381
+ @dirty = true
382
+ @unset = false
383
+ @value.delete_at( idx )
384
+ end
385
+
386
+
387
+ # Entries in Env var.
388
+ #
389
+ # @return [Integer] Length.
390
+ def length
391
+ @value.length
392
+ end
393
+
394
+
395
+ # Format EnvVar for shell. Output depends on whether the EnvVar
396
+ # has been "unset" or not.
397
+ #
398
+ # @return [String] Shell's eval command arguments.
399
+ def export
400
+ if @unset
401
+ case SHELL
402
+ when 'zsh', 'sh', 'bash'; "unset #{name}"
403
+ when 'fish'; "set -e #{name}"
404
+ else raise "Unknown shell: \"#{SHELL}\""
405
+ end
406
+ else
407
+ case SHELL
408
+ when 'zsh', 'sh', 'bash'; "export #{name}=#{@value.join(':')}"
409
+ # when 'fish'; "export #{name} #{@value.join(' ')}"
410
+ when 'fish'; "set -gx #{name} #{@value.join(' ')}"
411
+ else raise "Unknown shell: \"#{SHELL}\""
412
+ end
413
+ end
414
+ end
415
+
416
+ end
417
+
418
+
419
+ # Utility routines for Rumodule internal functions.
420
+ module Utility
421
+
422
+ # List of loaded modules.
423
+ LOADED = 'RUMODULE_LOADED'
424
+
425
+ # List of loaded system modules.
426
+ SYSLOADED = 'RUMODULE_SYSLOADED'
427
+
428
+ # List of loaded submodules.
429
+ SUBLOADED = 'RUMODULE_SUBLOADED'
430
+
431
+ # List of directories including modules.
432
+ MODULEDIRS = ENV['RUMODULE'] ? ENV['RUMODULE'].split(':') : []
433
+
434
+ # Stack to store pushed env vars.
435
+ RUMODULE_PUSH = 'RUMODULE_PUSH'
436
+
437
+
438
+
439
+ # List of loaded modules.
440
+ #
441
+ # @return [Array<String>] Loaded modules.
442
+ def loaded
443
+ getenvar( LOADED, true ).value
444
+ end
445
+
446
+
447
+ # List of loaded system modules.
448
+ #
449
+ # @return [Array<String>] Loaded modules.
450
+ def sys_loaded
451
+ getenvar( SYSLOADED, true ).value
452
+ end
453
+
454
+
455
+ # List of loaded modules (normal + system).
456
+ #
457
+ # @return [Array<String>] Loaded modules.
458
+ def all_loaded
459
+ getenvar( LOADED, true ).value +
460
+ getenvar( SYSLOADED, true ).value +
461
+ getenvar( SUBLOADED, true ).value
462
+ end
463
+
464
+
465
+ # Report usage info.
466
+ def usage( msg )
467
+ STDERR.puts( msg )
468
+ abort
469
+ end
470
+
471
+
472
+ # Report error.
473
+ def error( msg )
474
+ STDERR.puts( "rumodule error: #{msg}" )
475
+ abort
476
+ end
477
+
478
+
479
+ # Report warning.
480
+ def warning( msg )
481
+ STDERR.puts( "rumodule warning: #{msg}" )
482
+ abort
483
+ end
484
+
485
+
486
+ # Exit program without shell output.
487
+ def abort
488
+ STDERR.flush
489
+ exit( false )
490
+ end
491
+
492
+
493
+ # Return module file. If argument is dir, then check for directory
494
+ # content for modules.
495
+ #
496
+ # Alternatively 'm' can be abspath to module.
497
+ #
498
+ # @param m [String] Module name hint.
499
+ # @return [String] Path to module.
500
+ def findModule( m )
501
+
502
+ if m[0] == '/'
503
+
504
+ # Abspath
505
+ m
506
+
507
+ else
508
+
509
+ # Search for module.
510
+
511
+ pwd = Dir.pwd
512
+
513
+ ret = nil
514
+
515
+ MODULEDIRS.each do |mdir|
516
+
517
+ Dir.chdir mdir
518
+
519
+ if File.directory?( m )
520
+ ret = Dir[ "#{m}/*" ].sort[-1]
521
+ elsif File.exist?( m )
522
+ ret = m
523
+ end
524
+
525
+ if ret
526
+ ret = mdir + "/" + ret
527
+ break
528
+ end
529
+
530
+ end
531
+
532
+ Dir.chdir( pwd )
533
+
534
+ ret
535
+ end
536
+ end
537
+
538
+
539
+ # Load module content.
540
+ #
541
+ # @param m [String] Module name hint.
542
+ def loadModule( m )
543
+ path = findModule( m )
544
+ if path && File.exist?( path )
545
+ instance_eval( IO::read( path ), path )
546
+ path
547
+ else
548
+ error "Unknown module: \"#{m}\"!"
549
+ end
550
+ end
551
+
552
+
553
+ # Register module as loaded.
554
+ #
555
+ # @param m [String] Module path.
556
+ def registerModule( m, list = :normal )
557
+ case list
558
+ when :normal; getenvar( LOADED, true ).append_path( m )
559
+ when :system; getenvar( SYSLOADED, true ).append_path( m )
560
+ when :sub; getenvar( SUBLOADED, true ).append_path( m )
561
+ end
562
+ end
563
+
564
+
565
+ # UnRegister module as loaded.
566
+ #
567
+ # @param m [String] Module path.
568
+ def unregisterModule( m, list = :normal )
569
+
570
+ case list
571
+ when :normal; loaded = getenvar( LOADED )
572
+ when :system; loaded = getenvar( SYSLOADED )
573
+ when :sub; loaded = getenvar( SUBLOADED )
574
+ end
575
+
576
+ # loaded = getenvar( LOADED )
577
+ index = loaded.value.index( m )
578
+
579
+ if index
580
+
581
+ # Accurate match.
582
+ loaded.delete_index( index )
583
+
584
+ else
585
+
586
+ # Regexp match.
587
+ loaded.length.times do |i|
588
+ if Regexp.new( "#{m}/" ).match( loaded.value[i] )
589
+ loaded.delete_index( i )
590
+ return
591
+ end
592
+ end
593
+
594
+ end
595
+
596
+ end
597
+
598
+
599
+ # Rumodule help.
600
+ def commonHelp
601
+ usage %Q{
602
+ Available Commands and Args:
603
+ - add modulefile+
604
+ - sadd modulefile+
605
+ - rm modulefile+
606
+ - list
607
+ - slist
608
+ - which modulefile
609
+ - display modulefile
610
+ - avail
611
+ - savail
612
+ - help modulefile
613
+
614
+ }
615
+ end
616
+
617
+
618
+ # Empty help for modules. Help gets defined in CmdHelp when help
619
+ # is requested by user.
620
+ def help( str )
621
+ true
622
+ end
623
+
624
+ end
625
+
626
+
627
+ # Prefined Rumodule commands.
628
+ class Rumodule < RumoduleCommon
629
+
630
+ include Utility
631
+
632
+
633
+ # Map rumodule cmd to internal class method.
634
+ #
635
+ # @param cmd [String] Rumodule user command.
636
+ # @param mods [Array] List of modules.
637
+ def Rumodule.run( cmd, mods )
638
+
639
+ # Internal class name.
640
+ cmdClass = "Cmd#{cmd.capitalize}"
641
+
642
+ if Module.const_defined?( cmdClass )
643
+
644
+ # Create instance of the class.
645
+ obj = Object::const_get( cmdClass ).new
646
+
647
+ # Execute rumodule method.
648
+ obj.action( mods )
649
+
650
+ else
651
+
652
+ error "Unknown command: \"#{cmd}\"!"
653
+ end
654
+ end
655
+
656
+
657
+ # List of output command lines to shell. Must be separeted
658
+ # with semicolon and newline.
659
+ @@outputlist = []
660
+
661
+
662
+ # Cache variables from env to Hash. All updated values are visible
663
+ # to subsequent commands.
664
+ @@varcache = {}
665
+
666
+
667
+ # Fetch env varible from env. Conditionally create the env var.
668
+ #
669
+ # @param var [String] Env var name.
670
+ # @param create [Boolean] Create if not existing.
671
+ # @return [String] Env var value.
672
+ def getenvar( var, create = false )
673
+
674
+ if @@varcache[ var ]
675
+ # In cache.
676
+ @@varcache[ var ]
677
+ else
678
+
679
+ # Not in cache.
680
+ if ENV[ var ]
681
+
682
+ # In env.
683
+ v = EnvVar.new( var )
684
+ @@varcache[ var ] = v
685
+
686
+ elsif create
687
+
688
+ # Create as new.
689
+ v = EnvVar.new( var, [] )
690
+ @@varcache[ var ] = v
691
+
692
+ else
693
+ nil
694
+ end
695
+ end
696
+ end
697
+
698
+
699
+ # Is module(s) loaded?
700
+ #
701
+ # @param mod [String] Module name.
702
+ # @return [Boolean] True if loaded.
703
+ def _is_loaded( mod )
704
+ mod = [ mod ] if mod.class != Array
705
+
706
+ mod.each do |i|
707
+ if all_loaded.index( i )
708
+ return true
709
+ end
710
+ end
711
+
712
+ false
713
+ end
714
+
715
+
716
+ # Place str to output buffer (shell output).
717
+ #
718
+ # @param str [String] String for output.
719
+ def _output( str )
720
+ @@outputlist.push str
721
+ end
722
+
723
+
724
+ # Flush all pending shell output.
725
+ def Rumodule.flush
726
+
727
+ # Check for changed env varibles and perform update.
728
+ @@varcache.values.each do |v|
729
+ if v.dirty
730
+ @@outputlist.push v.export
731
+ end
732
+ end
733
+
734
+ # Output updates.
735
+ if @@outputlist.length > 0
736
+ puts @@outputlist.join( ";\n" )
737
+ end
738
+ end
739
+
740
+ end
741
+
742
+
743
+
744
+ # Help command.
745
+ class CmdHelp < Rumodule
746
+
747
+ def action( mod = nil )
748
+
749
+ if mod
750
+
751
+ begin
752
+
753
+ # Override dummy help method.
754
+ self.class.send( :define_method, :help, lambda { |str|
755
+ usage( str )
756
+ } )
757
+
758
+ loadModule( mod )
759
+
760
+ rescue
761
+
762
+ STDERR.puts "No help provided!"
763
+
764
+ end
765
+
766
+
767
+ else
768
+
769
+ commonHelp
770
+
771
+ end
772
+ end
773
+
774
+ end
775
+
776
+
777
+ # Display command.
778
+ class CmdDisplay < Rumodule
779
+
780
+ def action( mod )
781
+ mod = findModule( mod )
782
+ usage File.readlines( mod )
783
+ end
784
+
785
+ end
786
+
787
+
788
+ # Which command.
789
+ class CmdWhich < Rumodule
790
+
791
+ def action( mod )
792
+ usage findModule( mod )
793
+ end
794
+
795
+ end
796
+
797
+
798
+ # List command.
799
+ class CmdList < Rumodule
800
+
801
+ def action( mod = nil )
802
+ usage loaded
803
+ end
804
+
805
+ end
806
+
807
+
808
+ # List command.
809
+ class CmdSlist < Rumodule
810
+
811
+ def action( mod = nil )
812
+ usage sys_loaded
813
+ end
814
+
815
+ end
816
+
817
+
818
+ # Add command.
819
+ class CmdAdd < Rumodule
820
+
821
+ # Add modules if not loaded yet.
822
+ def action( mods, list = :normal )
823
+ mods.each do |mod|
824
+ mod_path = findModule( mod )
825
+ if mod_path == nil
826
+ error "Unknown module: \"#{mod}\"..."
827
+ elsif !_is_loaded( mod_path )
828
+ loaded_mod = loadModule( mod_path )
829
+ registerModule( loaded_mod, list )
830
+ else
831
+ warning( "Module is already loaded: \"#{mod_path}\"..." )
832
+ end
833
+ end
834
+ end
835
+
836
+
837
+ # ------------------------------------------------------------
838
+ # Module file commands:
839
+
840
+
841
+ def setenv( var, value )
842
+ getenvar( var, true ).set( value )
843
+ end
844
+
845
+
846
+ def unsetenv( var, value = nil )
847
+ if v = getenvar( var )
848
+ v.unset
849
+ end
850
+ end
851
+
852
+
853
+ def append_path( var, value )
854
+ getenvar( var, true ).append_path( value )
855
+ end
856
+
857
+
858
+ def prepend_path( var, value )
859
+ getenvar( var, true ).prepend_path( value )
860
+ end
861
+
862
+
863
+ def remove_path( var, value )
864
+ getenvar( var, true ).remove_path( value )
865
+ end
866
+
867
+
868
+ def pushenv( var, value )
869
+ # Store old value if it exists.
870
+ bup = "#{RUMODULE_PUSH}_#{var}"
871
+ if EnvVar.exist?( var )
872
+ getenvar( bup, true ).prepend_path( ENV[var] )
873
+ end
874
+ getenvar( var, true ).set( value )
875
+ end
876
+
877
+
878
+ def prereq( mod )
879
+ unless is_loaded( mod )
880
+ usage "Prerequisite module not loaded: #{mod}"
881
+ end
882
+ end
883
+
884
+
885
+ def conflict( mod )
886
+ if is_loaded( mod )
887
+ usage "Conflicting module loaded: #{mod}"
888
+ end
889
+ end
890
+
891
+
892
+ def is_loaded( mod )
893
+ _is_loaded( findModule( mod ) )
894
+ end
895
+
896
+
897
+ def add( mod )
898
+ action( [ mod ], :sub )
899
+ end
900
+
901
+ end
902
+
903
+
904
+ # System add command.
905
+ class CmdSadd < CmdAdd
906
+
907
+ # Add modules if not loaded yet.
908
+ def action( mods, list = :system )
909
+ mods.each do |mod|
910
+ mod_path = findModule( mod )
911
+ if mod_path == nil
912
+ error "Unknown module: \"#{mod}\"..."
913
+ elsif !_is_loaded( mod_path )
914
+ loaded_mod = loadModule( mod_path )
915
+ registerModule( loaded_mod, list )
916
+ end
917
+ end
918
+ end
919
+ end
920
+
921
+
922
+ # Rm command.
923
+ class CmdRm < Rumodule
924
+
925
+ def action( mods, list = :normal )
926
+ mods.each do |mod|
927
+ mod_path = findModule( mod )
928
+ if _is_loaded( mod_path )
929
+ loaded_mod = loadModule( mod_path )
930
+ unregisterModule( loaded_mod, list )
931
+ end
932
+ end
933
+ end
934
+
935
+
936
+ # ------------------------------------------------------------
937
+ # Module file commands:
938
+
939
+ def setenv( var, value )
940
+ if v = getenvar( var )
941
+ v.unset
942
+ end
943
+ end
944
+
945
+ def unsetenv( var, value = nil )
946
+ if value
947
+ getenvar( var, true ).set( value )
948
+ end
949
+ end
950
+
951
+ def append_path( var, value )
952
+ getenvar( var ).remove_path( value )
953
+ end
954
+
955
+ def prepend_path( var, value )
956
+ getenvar( var ).remove_path( value )
957
+ end
958
+
959
+ def remove_path( var, value )
960
+ getenvar( var, true ).prepend_path( value )
961
+ end
962
+
963
+ def pushenv( var, value )
964
+
965
+ # Store old value if it exists.
966
+ bup = "#{RUMODULE_PUSH}_#{var}"
967
+
968
+ if EnvVar.exist?( bup )
969
+ v = getenvar( bup )
970
+ getenvar( var, true ).set( v.value[0] )
971
+ v.value.shift
972
+ end
973
+ end
974
+
975
+ def prereq( mod )
976
+ true
977
+ end
978
+
979
+ def conflict( mod )
980
+ true
981
+ end
982
+
983
+ def is_loaded( mod )
984
+ true
985
+ end
986
+
987
+ def add( mod )
988
+ action( [ mod ], :sub )
989
+ end
990
+
991
+ end
992
+
993
+
994
+ # Rm system command.
995
+ class CmdSrm < CmdRm
996
+
997
+ def action( mods, list = :system )
998
+ mods.each do |mod|
999
+ mod_path = findModule( mod )
1000
+ if _is_loaded( mod_path )
1001
+ loaded_mod = loadModule( mod_path )
1002
+ unregisterModule( loaded_mod, list )
1003
+ end
1004
+ end
1005
+ end
1006
+ end
1007
+
1008
+
1009
+
1010
+ # Get command line options.
1011
+
1012
+ cmd = Opt['command'].value
1013
+
1014
+ mod = mods = nil
1015
+ if Opt['module'].given
1016
+ mod = Opt['module'].value[0]
1017
+ mods = Opt['module'].value
1018
+ end
1019
+
1020
+
1021
+ # Select the command.
1022
+
1023
+ case cmd
1024
+
1025
+ when 'help'
1026
+ Rumodule.run( cmd, mod )
1027
+
1028
+ when 'avail'
1029
+ Utility::MODULEDIRS.each do |mdir|
1030
+ STDERR.puts( Dir["#{mdir}/**/*"].select do |i| i[-1] != "-" end )
1031
+ end
1032
+
1033
+ when 'savail'
1034
+ Utility::MODULEDIRS.each do |mdir|
1035
+ STDERR.puts( Dir["#{mdir}/**/*"] )
1036
+ end
1037
+
1038
+ when 'display'
1039
+ Rumodule.run( cmd, mod )
1040
+
1041
+ when 'which'
1042
+ Rumodule.run( cmd, mod )
1043
+
1044
+ when 'list'
1045
+ Rumodule.run( cmd, mod )
1046
+
1047
+ when 'slist'
1048
+ Rumodule.run( cmd, mod )
1049
+
1050
+ when 'add'
1051
+ Rumodule.run( cmd, mods )
1052
+
1053
+ when 'sadd'
1054
+ Rumodule.run( cmd, mods )
1055
+
1056
+ when 'rm'
1057
+ Rumodule.run( cmd, mods )
1058
+
1059
+ when 'srm'
1060
+ Rumodule.run( cmd, mods )
1061
+
1062
+ else
1063
+ error "Unknown command: \"#{cmd}\"!"
1064
+
1065
+ end
1066
+
1067
+
1068
+ # Flush command updates.
1069
+ Rumodule.flush