software_smithy 1.1

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.
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