software_smithy 1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/README.rdoc +114 -0
  2. data/bin/smithy +586 -0
  3. data/etc/completion/smithy-completion.bash +266 -0
  4. data/etc/completion/zsh/_smithy +130 -0
  5. data/etc/smithyrc +36 -0
  6. data/etc/templates/build/.owners +1 -0
  7. data/etc/templates/build/build-notes +0 -0
  8. data/etc/templates/build/dependencies +0 -0
  9. data/etc/templates/build/rebuild +13 -0
  10. data/etc/templates/build/relink +2 -0
  11. data/etc/templates/build/remodule.erb +21 -0
  12. data/etc/templates/build/retest +6 -0
  13. data/etc/templates/build/status +0 -0
  14. data/etc/templates/modulefile.erb +30 -0
  15. data/etc/templates/package/.check4newver +2 -0
  16. data/etc/templates/package/.exceptions +3 -0
  17. data/etc/templates/package/description +18 -0
  18. data/etc/templates/package/description.markdown +17 -0
  19. data/etc/templates/package/support +1 -0
  20. data/etc/templates/package/versions +3 -0
  21. data/etc/templates/web/all.html.erb +19 -0
  22. data/etc/templates/web/alphabetical.html.erb +12 -0
  23. data/etc/templates/web/category.html.erb +74 -0
  24. data/etc/templates/web/machine_version_table.html.erb +35 -0
  25. data/etc/templates/web/package.html.erb +53 -0
  26. data/etc/templates/web/version_list.html.erb +7 -0
  27. data/etc/templates/web/version_table.html.erb +24 -0
  28. data/lib/smithy/config.rb +167 -0
  29. data/lib/smithy/description.rb +276 -0
  30. data/lib/smithy/file_operations.rb +234 -0
  31. data/lib/smithy/format.rb +134 -0
  32. data/lib/smithy/helpers.rb +159 -0
  33. data/lib/smithy/module_file.rb +224 -0
  34. data/lib/smithy/package.rb +647 -0
  35. data/lib/smithy.rb +45 -0
  36. data/lib/smithy_version.rb +40 -0
  37. data/man/man1/smithy.1 +262 -0
  38. data/smithy.rdoc +281 -0
  39. metadata +230 -0
@@ -0,0 +1,234 @@
1
+ # Smithy is freely available under the terms of the BSD license given below. {{{
2
+ #
3
+ # Copyright (c) 2012. UT-BATTELLE, LLC. All rights reserved.
4
+ #
5
+ # Produced by the National Center for Computational Sciences at Oak Ridge
6
+ # National Laboratory. Smithy is a based on SWTools, more information on SWTools
7
+ # can be found at: http://www.olcf.ornl.gov/center-projects/swtools/
8
+ #
9
+ # This product includes software produced by UT-Battelle, LLC under Contract No.
10
+ # DE-AC05-00OR22725 with the Department of Energy.
11
+ #
12
+ # Redistribution and use in source and binary forms, with or without
13
+ # modification, are permitted provided that the following conditions are met:
14
+ #
15
+ # - Redistributions of source code must retain the above copyright notice, this
16
+ # list of conditions and the following disclaimer.
17
+ #
18
+ # - Redistributions in binary form must reproduce the above copyright notice, this
19
+ # list of conditions and the following disclaimer in the documentation and/or
20
+ # other materials provided with the distribution.
21
+ #
22
+ # - Neither the name of the UT-BATTELLE nor the names of its contributors may
23
+ # be used to endorse or promote products derived from this software without
24
+ # specific prior written permission.
25
+ #
26
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
30
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
34
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
+ # }}}
37
+
38
+ module Smithy
39
+ FILE_NOTICE_COLUMNS = 12
40
+ def notice_create(file)
41
+ puts "create ".rjust(12).color(:green).bright + file
42
+ end
43
+ def notice_exist(file)
44
+ puts "exists ".rjust(12).color(:blue).bright + file
45
+ end
46
+ def notice_link(file1, file2)
47
+ puts "link ".rjust(12).bright + file1 + " -> " + file2
48
+ end
49
+ def notice_identical(file)
50
+ puts "identical ".rjust(12).color(:blue).bright + file
51
+ end
52
+ def notice_conflict(file)
53
+ puts "conflict ".rjust(12).color(:red).bright + file
54
+ end
55
+ def notice_force(file)
56
+ puts "force ".rjust(12).color(:yellow).bright + file
57
+ end
58
+ def notice_skip(file)
59
+ puts "skip ".rjust(12).bright + file
60
+ end
61
+
62
+ class FileOperations
63
+
64
+ class << self
65
+
66
+ def make_executable(f, options = {})
67
+ unless options[:noop]
68
+ p = File.stat(f).mode | 0111
69
+ FileUtils.chmod p, f, options
70
+ end
71
+ end
72
+
73
+ def set_group(f, new_group, options = {})
74
+ method = :chown
75
+ if options.has_key? :recursive
76
+ options.reject!{|k,v| k.eql?(:recursive)}
77
+ method = :chown_R
78
+ end
79
+
80
+ current_group = Etc.getgrgid(File.stat(f).gid).name rescue nil
81
+ return if current_group.eql?(new_group) && method == :chown
82
+
83
+ begin
84
+ FileUtils.send method, nil, new_group, f, options
85
+ rescue
86
+ raise "Could not set group \"#{new_group}\" on \"#{f}\""
87
+ end
88
+ end
89
+
90
+ def make_group_writable(f, options = {})
91
+ f = f.path if f.class == File
92
+ # FileUtils.chmod_R doesn't work well for combinations of files
93
+ # with different bitmasks, it sets everything the same
94
+ if options.has_key? :recursive
95
+ command = "chmod -R g+w #{f}"
96
+ else
97
+ command = "chmod g+w #{f}"
98
+ unless options[:noop]
99
+ # Check to see if it's already group writeable
100
+ # convert the integer to a string in base 8
101
+ mode = File.stat(f).mode.to_s(8)
102
+ # check the group bit, convert back to integer
103
+ group_bit = mode[mode.size-2].to_i
104
+ return if group_bit == 6 || group_bit == 7
105
+ end
106
+ end
107
+
108
+ puts command if options[:verbose]
109
+ `#{command}` unless options[:noop]
110
+ end
111
+
112
+ def make_directory(d, options = {})
113
+ if File.directory?(d)
114
+ notice_exist d
115
+ else
116
+ FileUtils.mkdir_p d, options
117
+ notice_create d
118
+ end
119
+ end
120
+
121
+ def make_symlink(old, new, options = {})
122
+ if File.symlink?(new)
123
+ notice_exist new
124
+ else
125
+ FileUtils.rm_f(new, options)
126
+ FileUtils.ln_sf(old, new, options)
127
+ notice_link old, new
128
+ end
129
+ end
130
+
131
+ def install_file(source, dest, options = {})
132
+ current_time = Time.now.to_i
133
+ duplicate_dest = dest+"_copy_"+current_time.to_s
134
+ installed = false
135
+
136
+ force = options.try(:[],:force)
137
+ force = Smithy::Config.global.try(:[], :"force")
138
+ options.reject!{|k,v| k==:force}
139
+
140
+ if File.exists?(dest) && !force
141
+ if FileUtils.identical?(source, dest)
142
+ notice_identical dest
143
+ installed = true
144
+ else
145
+ notice_conflict dest
146
+ overwrite = nil
147
+ while overwrite.nil? do
148
+ prompt = Readline.readline(" "*FILE_NOTICE_COLUMNS+"Overwrite? (enter \"h\" for help) [ynsdh] ")
149
+ case prompt.downcase
150
+ when "y"
151
+ overwrite = true
152
+ when "n"
153
+ overwrite = false
154
+ when "s"
155
+ overwrite = false
156
+ duplicate = true
157
+ when "d"
158
+ puts `diff -uw #{dest} #{source}`
159
+ when "h"
160
+ indent = " "*FILE_NOTICE_COLUMNS
161
+ puts indent+"y - yes, overwrite"
162
+ puts indent+"n - no, do not overwrite"
163
+ puts indent+"s - save to a separate file"
164
+ puts indent+"d - diff, show the differences between the old and the new"
165
+ puts indent+"h - help, show this help}"
166
+ #when "q"
167
+ #raise "Abort new package"
168
+ #else
169
+ #overwrite = true
170
+ end
171
+ end
172
+
173
+ if overwrite
174
+ notice_force dest
175
+ FileUtils.install source, dest, options
176
+ installed = true
177
+ else
178
+ if duplicate
179
+ FileUtils.install source, duplicate_dest, options
180
+ notice_create duplicate_dest
181
+ else
182
+ notice_skip dest
183
+ end
184
+ end
185
+ end
186
+ else
187
+ FileUtils.install source, dest, options
188
+ notice_create dest
189
+ installed = true
190
+ end
191
+
192
+ return installed
193
+ end
194
+
195
+ def install_from_string(content, dest, options = {})
196
+ if options[:noop]
197
+ updated_file = File.join(ENV["HOME"]+"/.smithy_#{File.basename(dest)}_#{Time.now.to_i}")
198
+ else
199
+ updated_file = File.join(File.dirname(dest), ".#{File.basename(dest)}_#{Time.now.to_i}")
200
+ end
201
+
202
+ File.open(updated_file , "w+") do |f|
203
+ f.write(content)
204
+ end
205
+
206
+ FileOperations.install_file updated_file, dest, options
207
+ FileUtils.rm_f(updated_file) # Always remove
208
+ end
209
+
210
+ def render_erb(args = {})
211
+ options = {:noop => false, :verbose => false}
212
+ options.merge!(args[:options])
213
+ erb_filename = args[:erb]
214
+ dest = args[:destination]
215
+
216
+ if options[:noop]
217
+ rendered_file = ENV["HOME"]+"/.#{File.basename(dest)}_#{Time.now.to_i}"
218
+ else
219
+ rendered_file = "#{File.dirname(dest)}/.#{File.basename(dest)}_#{Time.now.to_i}"
220
+ end
221
+
222
+ erb = ERB.new(File.read(erb_filename), nil, "<>")
223
+ File.open(rendered_file, "w+") do |f|
224
+ f.write erb.result(args[:binding])
225
+ end
226
+
227
+ FileOperations.install_file(rendered_file, dest, options)
228
+ FileUtils.rm_f(rendered_file) # Always remove
229
+ end
230
+
231
+ end
232
+
233
+ end
234
+ end
@@ -0,0 +1,134 @@
1
+ # Smithy is freely available under the terms of the BSD license given below. {{{
2
+ #
3
+ # Copyright (c) 2012. UT-BATTELLE, LLC. All rights reserved.
4
+ #
5
+ # Produced by the National Center for Computational Sciences at Oak Ridge
6
+ # National Laboratory. Smithy is a based on SWTools, more information on SWTools
7
+ # can be found at: http://www.olcf.ornl.gov/center-projects/swtools/
8
+ #
9
+ # This product includes software produced by UT-Battelle, LLC under Contract No.
10
+ # DE-AC05-00OR22725 with the Department of Energy.
11
+ #
12
+ # Redistribution and use in source and binary forms, with or without
13
+ # modification, are permitted provided that the following conditions are met:
14
+ #
15
+ # - Redistributions of source code must retain the above copyright notice, this
16
+ # list of conditions and the following disclaimer.
17
+ #
18
+ # - Redistributions in binary form must reproduce the above copyright notice, this
19
+ # list of conditions and the following disclaimer in the documentation and/or
20
+ # other materials provided with the distribution.
21
+ #
22
+ # - Neither the name of the UT-BATTELLE nor the names of its contributors may
23
+ # be used to endorse or promote products derived from this software without
24
+ # specific prior written permission.
25
+ #
26
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
30
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
34
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
+ # }}}
37
+
38
+ module Smithy
39
+ module Format
40
+ def self.print_column_list(items)
41
+ max_size = 0
42
+ items.each { |m| max_size = m.size if m.size > max_size }
43
+ width = `tput cols`.to_i
44
+ columns = (width/(max_size+3.0)).ceil
45
+ items_per_column = (items.size/columns.to_f).ceil
46
+
47
+ items_copy = items.dup
48
+ s = []
49
+ columns.times do
50
+ s << items_copy.slice!(0, items_per_column)
51
+ end
52
+ while s.last.size < items_per_column do
53
+ s.last << ""
54
+ end
55
+ table = Terminal::Table.new :rows => s.transpose
56
+ puts table.to_s
57
+ end
58
+
59
+ def self.software_row(s)
60
+ row = []
61
+ row << s
62
+ source = s+'/rebuild'
63
+ if File.exist?(source)
64
+ f = File.stat(source)
65
+ else
66
+ f = File.stat(s)
67
+ end
68
+ row << f.mtime.strftime("%Y-%m-%d %H:%M:%S")
69
+ begin
70
+ user = Etc.getpwuid(f.uid)
71
+ row << user.try(:name)
72
+ row << user.try(:gecos)
73
+ rescue
74
+ row << 'unknown'
75
+ row << 'unknown'
76
+ end
77
+ end
78
+
79
+ class Table
80
+ def before
81
+ @@table = Terminal::Table.new :headings => %w(Build LastModified Username Name)
82
+ end
83
+ def format(software, root)
84
+ software.each do |s|
85
+ @@table << Smithy::Format.software_row(s)
86
+ end
87
+ end
88
+ def after
89
+ puts @@table.to_s
90
+ end
91
+ end
92
+
93
+ class CSV
94
+ def before
95
+ end
96
+ def format(software, root)
97
+ software.each do |s|
98
+ puts Smithy::Format.software_row(s).join(',')
99
+ end
100
+ end
101
+ def after
102
+ end
103
+ end
104
+
105
+ class Doku
106
+ def before
107
+ puts "^ Build ^ Last Modified ^ Username ^ Name ^"
108
+ end
109
+ def format(software, root)
110
+ software.each do |s|
111
+ puts "| " + Smithy::Format.software_row(s).join(' | ') + " |"
112
+ end
113
+ end
114
+ def after
115
+ end
116
+ end
117
+
118
+ class Path
119
+ def before ; end
120
+ def format(software, root)
121
+ puts software
122
+ end
123
+ def after ; end
124
+ end
125
+
126
+ class Name
127
+ def before ; end
128
+ def format(software, root)
129
+ puts software.collect{|s| s.gsub(/#{root}\//, '')}
130
+ end
131
+ def after ; end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,159 @@
1
+ # Smithy is freely available under the terms of the BSD license given below. {{{
2
+ #
3
+ # Copyright (c) 2012. UT-BATTELLE, LLC. All rights reserved.
4
+ #
5
+ # Produced by the National Center for Computational Sciences at Oak Ridge
6
+ # National Laboratory. Smithy is a based on SWTools, more information on SWTools
7
+ # can be found at: http://www.olcf.ornl.gov/center-projects/swtools/
8
+ #
9
+ # This product includes software produced by UT-Battelle, LLC under Contract No.
10
+ # DE-AC05-00OR22725 with the Department of Energy.
11
+ #
12
+ # Redistribution and use in source and binary forms, with or without
13
+ # modification, are permitted provided that the following conditions are met:
14
+ #
15
+ # - Redistributions of source code must retain the above copyright notice, this
16
+ # list of conditions and the following disclaimer.
17
+ #
18
+ # - Redistributions in binary form must reproduce the above copyright notice, this
19
+ # list of conditions and the following disclaimer in the documentation and/or
20
+ # other materials provided with the distribution.
21
+ #
22
+ # - Neither the name of the UT-BATTELLE nor the names of its contributors may
23
+ # be used to endorse or promote products derived from this software without
24
+ # specific prior written permission.
25
+ #
26
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
30
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
34
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
+ # }}}
37
+
38
+ # try and blank? methods borrowed from rails
39
+ # See: https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/object/try.rb
40
+ class Object
41
+ def try(method, *args, &block)
42
+ send(method, *args, &block)
43
+ end
44
+ remove_method :try
45
+ alias_method :try, :__send__
46
+
47
+ def blank?
48
+ respond_to?(:empty?) ? empty? : !self
49
+ end
50
+ end
51
+
52
+ class NilClass #:nodoc:
53
+ def try(*args)
54
+ nil
55
+ end
56
+
57
+ def blank?
58
+ true
59
+ end
60
+ end
61
+
62
+ module Smithy
63
+ def notice(message)
64
+ STDOUT.puts "==> ".color(:blue).bright+message.bright if STDOUT.tty?
65
+ end
66
+
67
+ def notice_warn(message)
68
+ STDOUT.puts ("==> "+message).color(:yellow) if STDOUT.tty?
69
+ end
70
+
71
+ def notice_info(message)
72
+ STDOUT.puts (message).color(:blue) if STDOUT.tty?
73
+ end
74
+
75
+ def notice_command(command, comment, width=40)
76
+ STDOUT.puts command.bright.ljust(width)+comment.color(:blue) if STDOUT.tty?
77
+ end
78
+
79
+ def notice_success(message)
80
+ if STDOUT.tty?
81
+ STDOUT.puts ("==> "+message).color(:green)
82
+ else
83
+ STDOUT.puts message
84
+ end
85
+ end
86
+
87
+ def notice_fail(message)
88
+ if STDOUT.tty?
89
+ STDOUT.puts ("==> "+message).color(:red)
90
+ else
91
+ STDOUT.puts message
92
+ end
93
+ end
94
+
95
+ def process_ouput(stdout, stderr, suppress_stdout = false, log_file = nil)
96
+ unless stdout.empty?
97
+ puts stdout unless suppress_stdout
98
+ log_file.puts stdout unless log_file.nil?
99
+ stdout.replace("")
100
+ end
101
+ unless stderr.empty?
102
+ puts stderr unless suppress_stdout
103
+ log_file.puts stderr unless log_file.nil?
104
+ stderr.replace("")
105
+ end
106
+ end
107
+
108
+ def launch_editor(args = {})
109
+ editor = args[:editor] || ENV['EDITOR']
110
+ raise """Please specify which editor to launch using the
111
+ $EDITOR environment variable or the --editor option.""" if editor.blank?
112
+
113
+ arg_list = [ editor ]
114
+ arg_list << "-O" if args[:split] && editor =~ /vim/
115
+
116
+ if args[:split]
117
+ args[:files].each{|f| arg_list << f}
118
+ else
119
+ arg_list << args[:files].first
120
+ end
121
+
122
+ status = Kernel::system(*arg_list)
123
+ end
124
+
125
+ def modulehelp(name)
126
+ raise "$MODULEPATH is not set" unless ENV.has_key?('MODULEPATH')
127
+ sout = ""
128
+ #serr = ""
129
+ status = Open4::popen4("script -q -c '#{ENV['MODULESHOME']}/bin/modulecmd sh help #{name}' /dev/null") do |pid, stdin, stdout, stderr|
130
+ sout += stdout.read.strip
131
+ #serr += stderr.read.strip
132
+ end
133
+ #if status.exitstatus.eql?(0)
134
+ sout.gsub!(/\r/, '')
135
+ #serr.gsub!(/\r/, '')
136
+ return sout
137
+ #list = ""
138
+ # status = Open4::popen4(ENV['MODULESHOME']+"/bin/modulecmd ruby avail -t") do |pid, stdin, stdout, stderr|
139
+ # list = stderr.read.strip
140
+ # end
141
+ # if status.exitstatus.eql?(0)
142
+ # m = {}
143
+ # key = nil
144
+ # list.split(/^(.*:)$/).each do |line|
145
+ # next if line.empty?
146
+ # if key.nil?
147
+ # if line =~ /^(.*):$/
148
+ # key = $1
149
+ # end
150
+ # else
151
+ # m[key] = line.split("\n")
152
+ # m[key].reject!{|l| l.empty?}
153
+ # key = nil
154
+ # end
155
+ # end
156
+ # end
157
+ end
158
+
159
+ end