oar-scripting 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
File without changes
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ # Author:: Pascal Morillon (<pascal.morillon@irisa.fr>)
3
+ # Date:: Wed Feb 29 15:14:47 +0100 2012
4
+ #
5
+
6
+ $: << File.join(File.dirname(__FILE__), "..", "lib")
7
+
8
+ require 'rubygems'
9
+ require 'oar/scripting/application/graph.rb'
10
+
11
+ OAR::Scripting::Application::Graph.new.run
12
+
@@ -0,0 +1,64 @@
1
+ # Author:: Pascal Morillon (<pascal.morillon@irisa.fr>)
2
+ # Date:: Wed Feb 22 17:36:57 +0100 2012
3
+ #
4
+
5
+ require 'oar/scripting/constants'
6
+ require 'oar/scripting/script'
7
+ require 'oar/scripting/config'
8
+ require 'logger'
9
+ require 'backports'
10
+
11
+ module OAR
12
+ module Scripting
13
+
14
+ def sh(cmd, options = {})
15
+ options = options.symbolize_keys
16
+ options[:stderr] ||= true
17
+ cmd += options[:stderr] == false ? " 2>/dev/null" : " 2>&1"
18
+ result = ""
19
+ Script.logger.info "[command] " + cmd
20
+ IO.popen(cmd) do |io|
21
+ result = io.read.strip
22
+ Script.logger.debug "[result]\n" + result
23
+ end
24
+ $? != 0 ? Script.logger.debug("[command_failure]") : Script.logger.debug("[command_success]")
25
+ result if options[:return]
26
+ end # def:: sh(cmd)
27
+
28
+ def step(name, *args, &block)
29
+ step = Hash.new
30
+ raise(ArgumentError, "Step name must be a symbol") unless name.kind_of?(Symbol)
31
+ if Script.disabled_steps.include? name
32
+ Script.logger.info "[disable_step]#{name}"
33
+ return
34
+ end
35
+ step = args.first unless args.first.nil?
36
+ step[:name] = name
37
+ step[:order] ||= OAR::Scripting::Config[:default_step_order]
38
+ step[:continue] ||= true
39
+ step[:proc] = block
40
+ pre_step = Script.steps.select { |a| a[:name] == name }
41
+ unless pre_step.empty?
42
+ if step[:overwrite]
43
+ Script.logger.info "[step_overwrites] replace #{pre_step.first.inspect} by #{step.inspect}"
44
+ Script.steps.delete pre_step.first
45
+ Script.steps << step
46
+ else
47
+ Script.logger.info "[step_already_defined] skip #{step.inspect}"
48
+ end
49
+ else
50
+ Script.steps << step
51
+ end
52
+ end # def:: step(name)
53
+
54
+ def job
55
+ Script.job
56
+ end # def:: job
57
+
58
+ def oarstat
59
+ Script.oarstat
60
+ end # def:: oarstat
61
+
62
+ end # module:: Scripting
63
+ end # module:: OAR
64
+
@@ -0,0 +1,47 @@
1
+ # Author:: Pascal Morillon (<pascal.morillon@irisa.fr>)
2
+ # Date:: Wed Feb 29 15:07:38 +0100 2012
3
+ #
4
+
5
+ require 'mixlib/cli'
6
+ require 'oar/scripting/constants'
7
+ require 'oar/scripting/config'
8
+
9
+ class OAR::Scripting::Application
10
+ include Mixlib::CLI
11
+
12
+ def initialize
13
+ super
14
+
15
+ trap("TERM") do
16
+ OAR::Scripting::Application.fatal!("SIGTERM received, stopping", 1)
17
+ end
18
+
19
+ trap("INT") do
20
+ OAR::Scripting::Application.fatal!("SIGINT received, stopping", 2)
21
+ end
22
+ end # Definition:: initialize
23
+
24
+ def run
25
+ # use parse_options from Mixlib
26
+ parse_options
27
+
28
+ # Run application
29
+ run_application
30
+ end # Definition:: run
31
+
32
+ def run_application
33
+ raise "#{self.to_s}: you must override run_application"
34
+ end # Definition:: run_application
35
+
36
+ class << self
37
+ def fatal!(msg, err = -1)
38
+ STDERR.puts("FATAL: #{msg}")
39
+ Process.exit err
40
+ end # Definition:: fatal!(msg, err = -1)
41
+
42
+ def exit!(msg, err = -1)
43
+ Process.exit err
44
+ end # Definition:: exit!(msg, err = -1)
45
+ end
46
+
47
+ end # class:: OAR::Scripting::Application
@@ -0,0 +1,191 @@
1
+ # Author:: Pascal Morillon (<pascal.morillon@irisa.fr>)
2
+ # Date:: Wed Feb 29 15:09:48 +0100 2012
3
+ #
4
+
5
+ require 'oar/scripting/application'
6
+ require 'fileutils'
7
+ require 'rubyvis'
8
+ require 'json'
9
+
10
+ class OAR::Scripting::Application::Graph < OAR::Scripting::Application
11
+
12
+ include OAR::Scripting
13
+
14
+ CMD_NAME = "oar-scripting-graph"
15
+
16
+ option :help,
17
+ :short => "-h",
18
+ :long => "--help",
19
+ :description => "Show this message",
20
+ :on => :tail,
21
+ :boolean => true,
22
+ :show_options => true,
23
+ :exit => 0
24
+
25
+ option :version,
26
+ :short => "-v",
27
+ :long => "--version",
28
+ :description => "Show oar-scripting version",
29
+ :boolean => true,
30
+ :proc => lambda {|v| puts "#{CMD_NAME}: #{OAR::Scripting::VERSION}"},
31
+ :exit => 0
32
+
33
+ option :output,
34
+ :short => "-o PATH",
35
+ :long => "--output PATH",
36
+ :description => "Output directory",
37
+ :default => Config[:output]
38
+
39
+ def initialize
40
+ super
41
+ end # def:: initialize
42
+
43
+ def run_application
44
+ Config[:timeout] = 120
45
+ raise "Directory does not exist : #{config[:output]}" until File.exist?(config[:output])
46
+ FileUtils.rm_rf File.join(config[:output], "oar-scripting-graph") if File.exist?(File.join(config[:output], "oar-scripting-graph"))
47
+ FileUtils.mkdir File.join(config[:output], "oar-scripting-graph")
48
+ FileUtils.mkdir File.join(config[:output], "oar-scripting-graph", "css")
49
+ FileUtils.mkdir File.join(config[:output], "oar-scripting-graph", "js")
50
+ FileUtils.mkdir File.join(config[:output], "oar-scripting-graph", "images")
51
+ FileUtils.mkdir File.join(config[:output], "oar-scripting-graph", "logs")
52
+ FileUtils.cp(File.join(File.dirname(__FILE__), 'graph', 'sh_emacs.css'),File.join(config[:output], "oar-scripting-graph", "css"))
53
+ FileUtils.cp(File.join(File.dirname(__FILE__), 'graph', 'sh_main.min.js'),File.join(config[:output], "oar-scripting-graph", "js"))
54
+ FileUtils.cp(File.join(File.dirname(__FILE__), 'graph', 'sh_ruby.min.js'),File.join(config[:output], "oar-scripting-graph", "js"))
55
+
56
+ html_path = File.join(config[:output], "oar-scripting-graph")
57
+
58
+ dataset = {}
59
+
60
+ %w{prologue epilogue}.each do |script|
61
+ dataset[script.to_sym] = {}
62
+ Dir["/var/log/oar/*-#{script}-*.log"].each do |file|
63
+ log = File.read(file).scan(/^.*\[stats\].*$/).first
64
+ log.nil? ? next : json = log.gsub(/^.*\[stats\](.*)$/, '\1')
65
+ stats = JSON.parse json
66
+ p stats
67
+ dataset[script.to_sym][:global] ||= []
68
+ dataset[script.to_sym][:global] << OpenStruct.new( {"x" => stats["job"]["resources_count"], "y" => stats["job"]["host_count"], "z" => stats["duration"]} )
69
+ dataset[script.to_sym][:steps_list] ||= []
70
+ stats["steps"].each do |step|
71
+ dataset[script.to_sym][:steps_list] << step["name"] if !dataset[script.to_sym][:steps_list].include?(step["name"])
72
+ dataset[script.to_sym][:steps] ||= {}
73
+ dataset[script.to_sym][:steps][step["name"].to_sym] ||= []
74
+ dataset[script.to_sym][:steps][step["name"].to_sym] << OpenStruct.new( {"x" => stats["job"]["resources_count"], "y" => stats["job"]["host_count"], "z" => step["duration"]} )
75
+ end
76
+ end
77
+ end
78
+
79
+ dataset.each do |script,datas|
80
+ graph_gen("#{script.to_s.capitalize} duration (all steps)", File.join(html_path, "images", "#{script.to_s}_all.svg"), dataset[script][:global])
81
+ dataset[script][:steps_list].each do |step|
82
+ graph_gen("#{script.to_s.capitalize} duration (#{step})", File.join(html_path, "images", "#{script.to_s}_#{step}.svg"), dataset[script][:steps][step.to_sym])
83
+ end
84
+ end
85
+
86
+ open(File.join(html_path, "index.html"), "w") do |file|
87
+ file.puts <<-EOH
88
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
89
+ <html>
90
+ <head>
91
+ <title>OAR Scripting graph</title>
92
+ <link rel="stylesheet" title="Default" href="./css/sh_emacs.css">
93
+ <script type="text/javascript" src="./js/sh_main.min.js"></script>
94
+ <script type="text/javascript" src="./js/sh_ruby.min.js"></script>
95
+ </head>
96
+ EOH
97
+ file.puts <<-EOH
98
+ <body onload="sh_highlightDocument('js/', 'sh_ruby.min.js');">
99
+ <h1>OAR Scripting graph</h1>
100
+ <h3>PROLOGUE_EPILOGUE_TIMEOUT=#{Config[:timeout]}</h3>
101
+ <h4>Generated at #{Time.now}</h4>
102
+ EOH
103
+ dataset.each do |script,datas|
104
+ file.puts "<div>"
105
+ file.puts "<pre class=\"sh_ruby\">"
106
+ file.puts File.read("/etc/oar/#{script.to_s}")
107
+ file.puts <<-EOH
108
+ </pre>
109
+ </div>
110
+ <div class='image'>
111
+ <!--[if IE]>
112
+ <embed class='svg' height='600' src='#{File.join("./images", "#{script.to_s}_all.svg")}' width='1100'></embed>
113
+ <![endif]-->
114
+ <object class='svg' data='#{File.join("./images", "#{script.to_s}_all.svg")}' height='600' type='image/svg+xml' width='1100'></object>
115
+ </div>
116
+ EOH
117
+ dataset[script][:steps_list].each do |step|
118
+ file.puts <<-EOH
119
+ <div class='image'>
120
+ <!--[if IE]>
121
+ <embed class='svg' height='600' src='#{File.join("./images", "#{script.to_s}_#{step}.svg")}' width='1100'></embed>
122
+ <![endif]-->
123
+ <object class='svg' data='#{File.join("./images", "#{script.to_s}_#{step}.svg")}' height='600' type='image/svg+xml' width='1100'></object>
124
+ </div>
125
+ EOH
126
+ end
127
+ end
128
+ file.puts <<-EOH
129
+ </body>
130
+ </html>
131
+ EOH
132
+ end
133
+ end # def:: run_application
134
+
135
+ def graph_gen(title, file_path, data)
136
+
137
+ x_max = 0
138
+ y_max = 0
139
+ data.each do |entry|
140
+ x_max = entry.x if entry.x > x_max
141
+ y_max = entry.y if entry.y > y_max
142
+ end
143
+
144
+ axis = { :x => { :title => "Recources count", :max => x_max },
145
+ :y => { :title => "Nodes count", :max => y_max } }
146
+
147
+ panel = { :title => title,
148
+ :bottom => 60,
149
+ :left => 60,
150
+ :right => 40,
151
+ :top => 40 }
152
+
153
+ w = 1000
154
+ h = 400
155
+
156
+ timeout = Config[:timeout]
157
+
158
+ x = pv.Scale.linear(0, axis[:x][:max]).range(0, w)
159
+ y = pv.Scale.linear(0, axis[:y][:max]).range(0, h)
160
+
161
+ c = pv.Scale.log(1, timeout).range("green", "brown")
162
+
163
+ # The root panel.
164
+ vis = pv.Panel.new().width(w).height(h).bottom(panel[:bottom]).left(panel[:left]).right(panel[:right]).top(panel[:top])
165
+
166
+ # Main title
167
+ vis.add(pv.Label).left(((w + panel[:left] + panel[:right]) - panel[:title].length) / 2 ).bottom(h).textAngle(0).text(panel[:title]).font( "35" + "px sans-serif")
168
+
169
+ # Axis titles
170
+ vis.add(pv.Label).left(-20).bottom(h/2 - (axis[:y][:title].length / 2)).textAngle(-Math::PI/2).text(axis[:y][:title]).font( "20" + "px sans-serif")
171
+ vis.add(pv.Label).left(w/2 - (axis[:x][:title].length / 2)).bottom(-40).textAngle(0).text(axis[:x][:title]).font( "20" + "px sans-serif")
172
+
173
+ # Y-axis and ticks.
174
+ vis.add(pv.Rule).data(y.ticks()).bottom(y).strokeStyle(lambda {|d| d!=0 ? "#eee" : "#000"}).anchor("left").add(pv.Label).visible(lambda {|d| d > 0 and d < axis[:y][:max]}).text(y.tick_format)
175
+
176
+ # X-axis and ticks.
177
+ vis.add(pv.Rule).data(x.ticks()).left(x).stroke_style(lambda {|d| d!=0 ? "#eee" : "#000"}).anchor("bottom").add(pv.Label).visible(lambda {|d| d > 0 and d < axis[:x][:max]}).text(x.tick_format)
178
+
179
+ #/* The dot plot! */
180
+ vis.add(pv.Panel).data(data).add(pv.Dot).left(lambda {|d| x.scale(d.x)}).bottom(lambda {|d| y.scale(d.y)}).stroke_style(lambda {|d| c.scale(d.z)}).fill_style(lambda {|d| c.scale(d.z).alpha(0.2)}).shape_size(lambda {|d| d.z * 5}).anchor("center").add(pv.Label).visible(lambda {|d| d.z > 30}).textAngle(0).text(lambda {|d| "%0.1f" % d.z});
181
+
182
+ vis.render()
183
+
184
+ open(file_path, "w") do |file|
185
+ file.puts vis.to_svg
186
+ end
187
+
188
+ end # def:: graph_gen(title, file_path)
189
+
190
+
191
+ end # class:: OAR::Scripting::Application::Graph < OAR::Scripting::Application
@@ -0,0 +1,33 @@
1
+ # Author:: Pascal Morillon (<pascal.morillon@irisa.fr>)
2
+ # Date:: Wed Feb 29 15:31:57 +0100 2012
3
+ #
4
+
5
+ class OAR::Scripting::Config
6
+
7
+ @@config = Hash.new
8
+
9
+ @@config[:output] = File.expand_path(ENV["PWD"])
10
+ @@config[:oar_conf_path] = "/etc/oar"
11
+ @@config[:prologue_d_path] = File.join @@config[:oar_conf_path], "prologue.d"
12
+ @@config[:epilogue_d_path] = File.join @@config[:oar_conf_path], "epilogue.d"
13
+ @@config[:default_step_order] = 50
14
+ @@config[:log_path] = "/var/log/oar"
15
+
16
+ def self.[](opt)
17
+ @@config[opt.to_sym]
18
+ end # def:: self.[](opt)
19
+
20
+ def self.[]=(opt, value)
21
+ @@config[opt.to_sym] = value
22
+ end # def:: self.[]=(opt, value)
23
+
24
+ def self.method_missing(method_symbol, *args)
25
+ @@config[method_symbol] = args[0]
26
+ @@config[method_symbol]
27
+ end # def:: self.method_missing(method_symbol), *args)
28
+
29
+ def self.inspect
30
+ @@config
31
+ end # def:: self.inspect
32
+
33
+ end # class:: OAR::Scripting::Config
@@ -0,0 +1,11 @@
1
+ # Author:: Pascal Morillon (<pascal.morillon@irisa.fr>)
2
+ # Date:: Wed Feb 22 17:38:51 +0100 2012
3
+ #
4
+
5
+ module OAR
6
+ module Scripting
7
+ GEM = "oar-scripting"
8
+ VERSION = "1.0.4"
9
+ end # module:: Scripting
10
+ end # module:: OAR
11
+
@@ -0,0 +1,15 @@
1
+ # Author:: Pascal Morillon (<pascal.morillon@irisa.fr>)
2
+ # Date:: Thu Feb 23 16:43:48 +0100 2012
3
+ #
4
+
5
+ require 'oar/scripting/script'
6
+
7
+ class OAR::Scripting::Epilogue < OAR::Scripting::Script
8
+
9
+ def initialize
10
+ @@type = :epilogue
11
+ super
12
+ end # def:: initialize
13
+
14
+ end # class:: OAR::Scripting::Epilogue < OAR::Scripting::Script
15
+
@@ -0,0 +1,15 @@
1
+ # Author:: Pascal Morillon (<pascal.morillon@irisa.fr>)
2
+ # Date:: Thu Feb 23 16:43:39 +0100 2012
3
+ #
4
+
5
+ require 'oar/scripting/script'
6
+
7
+ class OAR::Scripting::Prologue < OAR::Scripting::Script
8
+
9
+ def initialize
10
+ @@type = :prologue
11
+ super
12
+ end # def:: initialize
13
+
14
+ end # class:: OAR::Scripting::Prologue < OAR::Scripting::Script
15
+
@@ -0,0 +1,103 @@
1
+ # Author:: Pascal Morillon (<pascal.morillon@irisa.fr>)
2
+ # Date:: Mon Feb 27 13:42:10 +0100 2012
3
+ #
4
+
5
+ require 'oar/scripting'
6
+ require 'json'
7
+
8
+ class OAR::Scripting::Script
9
+
10
+ def self.init(type)
11
+ @@resources = []
12
+ @@start_at = Time.new
13
+ @@job = getargs
14
+ @@type ||= type
15
+ @@logger ||= Logger.new(File.join(OAR::Scripting::Config[:log_path], "#{@@job[:id]}-#{@@type.to_s}-#{@@job[:user]}.log"))
16
+ @@logger.info "[begin]"
17
+ @@stats = { "job" => @@job, "steps" => [] }
18
+ @@steps = []
19
+ @@disabled_steps = []
20
+ end # def:: initialize
21
+
22
+ def self.load_steps
23
+ dir = OAR::Scripting::Config["#{@@type}_d_path".to_sym]
24
+ if File.exist? dir
25
+ Dir[File.join dir, "*.rb"].each do |file|
26
+ load file
27
+ end
28
+ end
29
+ end # def:: self.load_scripts
30
+
31
+ def self.getargs
32
+ job = { :id => ARGV[0],
33
+ :user => ARGV[1],
34
+ :nodesfile => ARGV[2] }
35
+ begin
36
+ File.open(job[:nodesfile]).each { |line| @@resources << line.chomp }
37
+ rescue
38
+ # let @@resources empty
39
+ end
40
+ job[:resources_count] = @@resources.length
41
+ job[:host_count] = @@resources.uniq.length
42
+ job
43
+ end # def:: getargs
44
+
45
+ def self.logger
46
+ @@logger
47
+ end # def:: logger
48
+
49
+ def self.type
50
+ @@type
51
+ end # def:: type
52
+
53
+ def self.job
54
+ @@job
55
+ end # def:: self.job
56
+
57
+ def self.steps
58
+ @@steps
59
+ end # def:: self.steps
60
+
61
+ def self.oarstat
62
+ @@oarstat ||= JSON.parse(%x[oarstat -f -j @@job[:id] -J])[@@job[:id]]
63
+ end # def:: self.oarstat
64
+
65
+ def self.execute
66
+ @@steps.sort! { |a,b| a[:order] <=> b[:order] }
67
+ @@steps.each do |step|
68
+ @@logger.info "[begin_step]#{step[:name]}"
69
+ start = Time.new
70
+ begin
71
+ step[:proc].call
72
+ rescue Exception => e
73
+ @@logger.debug "[Error] step #{step[:name]} failed (describe in #{step[:file]}"
74
+ @@logger.debug e.message
75
+ @@logger.debug e.backtrace
76
+ raise unless step[:continue]
77
+ end
78
+ @@logger.info "[end_step]#{step[:name]}"
79
+ @@stats["steps"] << { "name" => step[:name].to_s, "duration" => (Time.now - start), "order" => step[:order] }
80
+ end
81
+ @@logger.info "[end]"
82
+ @@stats["duration"] = Time.now - @@start_at
83
+ @@logger.info "[stats]" + @@stats.to_json
84
+ end # def:: execute
85
+
86
+ def self.stats
87
+ @@stats
88
+ end # def:: self.stats
89
+
90
+ def self.disabled_steps
91
+ @@disabled_steps
92
+ end # def:: self.disabled_steps
93
+
94
+ def self.disable_steps(steps)
95
+ steps = [steps] unless steps.class == Array
96
+ @@disabled_steps += steps
97
+ steps2disable = Script.steps.select { |step| steps.include? step[:name] }
98
+ Script.logger.info "[disable_loaded_steps]#{steps2disable.inspect}"
99
+ @@steps -= steps2disable
100
+ end # def:: self.disable_steps(steps)
101
+
102
+ end # class:: OAR::Scripting::Script
103
+
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oar-scripting
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.4
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Pascal Morillon
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mixlib-cli
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.1.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.1.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: rubyvis
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 0.5.1
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 0.5.1
46
+ - !ruby/object:Gem::Dependency
47
+ name: json
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 1.6.5
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.6.5
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - '='
68
+ - !ruby/object:Gem::Version
69
+ version: 0.8.7
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - '='
76
+ - !ruby/object:Gem::Version
77
+ version: 0.8.7
78
+ - !ruby/object:Gem::Dependency
79
+ name: yard
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 0.8.2.1
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 0.8.2.1
94
+ description: OAR helper library for prologue/epilogue scripting
95
+ email: pascal.morillon@irisa.fr
96
+ executables:
97
+ - oar-scripting-graph
98
+ extensions: []
99
+ extra_rdoc_files:
100
+ - README.rdoc
101
+ files:
102
+ - README.rdoc
103
+ - lib/oar/scripting/application/graph.rb
104
+ - lib/oar/scripting/application.rb
105
+ - lib/oar/scripting/config.rb
106
+ - lib/oar/scripting/constants.rb
107
+ - lib/oar/scripting/epilogue.rb
108
+ - lib/oar/scripting/prologue.rb
109
+ - lib/oar/scripting/script.rb
110
+ - lib/oar/scripting.rb
111
+ - bin/oar-scripting-graph
112
+ homepage: https://github.com/pmorillon/oar-scripting
113
+ licenses: []
114
+ post_install_message:
115
+ rdoc_options: []
116
+ require_paths:
117
+ - - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ segments:
125
+ - 0
126
+ hash: -239453471554793347
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ! '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ segments:
134
+ - 0
135
+ hash: -239453471554793347
136
+ requirements: []
137
+ rubyforge_project:
138
+ rubygems_version: 1.8.24
139
+ signing_key:
140
+ specification_version: 3
141
+ summary: OAR helper library for prologue/epilogue scripting
142
+ test_files: []