jkr 0.1.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5cc3028f9f18f51c7dae2c3c382bfa44763c0df2
4
- data.tar.gz: 538c2f84ff9a128ef584be7d5f37d9e9c9263731
3
+ metadata.gz: c2aa3b45798602f7adfa2ef39671bbd0c67248ad
4
+ data.tar.gz: 9033b8152c9b54663ba76df543cb11546bdb5f39
5
5
  SHA512:
6
- metadata.gz: 8ccfb21a505843e30005c5a402fcbf6da1cab077a25f8781d7e3b3ee5df3761567bbfccbcf4abd07585e9f06466b0587db63c3d55994160de3f6ed34cbcc49ff
7
- data.tar.gz: 55ec247337556c9fd37c6d446934f3962b34e932615acb478ad9018ae36c0fd365e7c04a1dc34bc4e9e7ee3b7326cc002751e2fe4ddd37fad8390e72849c0ede
6
+ metadata.gz: 9dc067dcb1007050e2317a34a2c6afa23a1dd82caa66b06fdef2e58b8d2779fab496780f39efedfbbd338cd41d7408faf3569273cb608eefa4cf3772c2f45128
7
+ data.tar.gz: 37d50d20c882cde08ed6527131f5d3ed4c2e690c60c7f05052727bb5244877449aa36ad45310e0e12a0e19f9c61696309f70891a06b7c892b3839cdf2f68962e
data/.gitignore CHANGED
@@ -11,3 +11,4 @@
11
11
  /bin/rake2thor
12
12
  /bin/thor
13
13
  /pkg/*.gem
14
+ /Gemfile.lock
@@ -76,7 +76,10 @@ _jkr() {
76
76
 
77
77
  __jkr_subcmds() {
78
78
  _values 'Jkr command' \
79
+ 'init[Init a Jkr environment]' \
79
80
  'execute[Execute a plan]' \
81
+ 'resume[Resume in-progress execution]' \
80
82
  'list[List jkr plans]' \
81
- 'analyze[Analyze a result]'
83
+ 'analyze[Analyze a result]' \
84
+ 'query[Query interesting result]'
82
85
  }
@@ -43,13 +43,7 @@ module Jkr
43
43
 
44
44
  desc "list", "List executable plans"
45
45
  def list()
46
- begin
47
- @jkr_env = Jkr::Env.new(options[:directory])
48
- rescue Errno::ENOENT
49
- puts(red("[ERROR] jkr dir not found at #{@options[:directory]}"))
50
- puts(red(" Maybe you are in a wrong directory."))
51
- exit(false)
52
- end
46
+ @jkr_env = create_env()
53
47
 
54
48
  plans = Dir.glob("#{@jkr_env.jkr_plan_dir}/*.plan").map do |plan_file_path|
55
49
  plan = Jkr::Plan.create_by_name(@jkr_env, File.basename(plan_file_path, ".plan"))
@@ -74,7 +68,7 @@ module Jkr
74
68
 
75
69
  desc "execute <plan> [<plan> ...]", "Execute plans"
76
70
  def execute(*plan_names)
77
- @jkr_env = Jkr::Env.new(options[:directory])
71
+ @jkr_env = create_env()
78
72
 
79
73
  if options[:debug]
80
74
  delete_files_on_error = false
@@ -89,21 +83,84 @@ module Jkr
89
83
  end
90
84
  end
91
85
 
92
- desc "analyze <result> [<result> ...]", "Run analysis script for executed results"
86
+ desc "resume [<result> ...]", "Resume in-progress execution"
87
+ def resume(*result_ids)
88
+ @jkr_env = create_env()
89
+ cur_result_id = Jkr::Env.find_result(Dir.pwd)
90
+ if cur_result_id
91
+ result_ids.push(cur_result_id)
92
+ end
93
+
94
+ result_ids.each do |rid|
95
+ plan = Plan.create_by_result_id(@jkr_env, rid)
96
+ Jkr::Trial.resume(@jkr_env, plan)
97
+ end
98
+ end
99
+
100
+ desc "analyze [<result> ...]", "Run analysis script for executed results"
93
101
  def analyze(*result_ids)
94
- @jkr_env = Jkr::Env.new(options[:directory])
102
+ @jkr_env = create_env()
103
+
104
+ # check if current dir is a result dir
105
+ cur_result_id = Jkr::Env.find_result(Dir.pwd)
106
+ if cur_result_id
107
+ result_ids.push(cur_result_id)
108
+ end
95
109
 
96
110
  result_ids.each do |arg|
97
111
  Jkr::Analysis.analyze(@jkr_env, arg)
98
112
  end
99
113
  end
100
114
 
115
+ desc "query <result>", "Query interesting result"
116
+ def query(result_id = nil)
117
+ @jkr_env = create_env()
118
+
119
+ if result_id == nil
120
+ # check if current dir is a result dir
121
+ cur_result_id = Jkr::Env.find_result(Dir.pwd)
122
+ if cur_result_id
123
+ result_id = cur_result_id
124
+ else
125
+ raise ArgumentError.new("Result ID must be specified.")
126
+ end
127
+ end
128
+
129
+ result_dir = Dir.glob(sprintf("#{@jkr_env.jkr_result_dir}/%05d*", result_id.to_i)).first
130
+
131
+ Dir.glob("#{result_dir}/[0-9][0-9][0-9][0-9][0-9]/metastore.msh").sort.each do |m|
132
+ metastore = Marshal.load(File.open(m))
133
+ params = Marshal.load(File.open(File.expand_path("../params.msh", m)))
134
+
135
+ disp = metastore[:vars].map do |var|
136
+ "#{var}: #{params[var].inspect}"
137
+ end.join(", ")
138
+
139
+ puts "#{File.basename(File.dirname(m))} | #{disp}"
140
+ end
141
+ end
142
+
101
143
  no_commands do
102
144
  def find_plan_file(plan_name)
103
145
  @jkr_env.plans.find do |plan_file_path|
104
146
  File.basename(plan_file_path) == plan_name + ".plan"
105
147
  end
106
148
  end
149
+
150
+ def create_env()
151
+ begin
152
+ if options[:directory]
153
+ return Jkr::Env.new(options[:directory])
154
+ else
155
+ return Jkr::Env.new(Jkr::Env.find(Dir.pwd))
156
+ end
157
+ rescue Errno::ENOENT
158
+ $stderr.puts(red("[ERROR] jkr dir not found at #{@options[:directory]}"))
159
+ $stderr.puts(red(" Maybe you are in a wrong directory."))
160
+ exit(false)
161
+ end
162
+
163
+ end
107
164
  end
108
165
  end
109
166
 
@@ -21,7 +21,7 @@ module Jkr
21
21
  @jkr_result_dir = File.join(@jkr_dir, RESULT_DIR)
22
22
  @jkr_script_dir = File.join(@jkr_dir, SCRIPT_DIR)
23
23
 
24
- unless Dir.exists?(@jkr_dir)
24
+ unless Dir.exists?(@env_dir)
25
25
  raise Errno::ENOENT.new(@jkr_dir)
26
26
  end
27
27
 
@@ -34,5 +34,64 @@ module Jkr
34
34
  end
35
35
  end
36
36
  end
37
+
38
+ def self.valid_env_dir?(dir)
39
+ jkr_dir = File.expand_path("jkr", dir)
40
+ plan_dir = File.expand_path("plan", jkr_dir)
41
+ script_dir = File.expand_path("script", jkr_dir)
42
+ result_dir = File.expand_path("result", jkr_dir)
43
+
44
+ [jkr_dir, result_dir, plan_dir, script_dir].each do |dir_|
45
+ unless Dir.exists?(dir_)
46
+ return false
47
+ end
48
+ end
49
+
50
+ true
51
+ end
52
+
53
+ # Find Jkr env dir if 'dir' is under an valid Jkr environemnt directory.
54
+ def self.find(dir)
55
+ dir = File.expand_path("./", dir)
56
+ while true
57
+ if valid_env_dir?(dir)
58
+ return dir
59
+ end
60
+
61
+ parent_dir = File.expand_path("../", dir)
62
+ if parent_dir == dir
63
+ break
64
+ else
65
+ dir = parent_dir
66
+ end
67
+ end
68
+
69
+ nil
70
+ end
71
+
72
+ # Find an executed Jkr result if 'dir' is under the result dir, and return result id.
73
+ # return nil otherwise.
74
+ def self.find_result(dir)
75
+ dir = File.expand_path("./", dir)
76
+ while true
77
+ parent_dir = File.expand_path("../", dir)
78
+ gp_dir = File.expand_path("../../", dir) # grand parent
79
+ ggp_dir = File.expand_path("../../../", dir) # grand grand parent
80
+
81
+ if ggp_dir == gp_dir
82
+ return nil
83
+ end
84
+
85
+ if valid_env_dir?(ggp_dir)
86
+ if File.basename(gp_dir) == "jkr" &&
87
+ File.basename(parent_dir) == "result" &&
88
+ File.basename(dir) =~ /^[0-9]+/
89
+ return File.basename(dir).to_i
90
+ end
91
+ end
92
+
93
+ dir = File.expand_path("../", dir)
94
+ end
95
+ end
37
96
  end
38
97
  end
@@ -93,12 +93,22 @@ module Jkr
93
93
  plan.file_path = finder.find_by_result_id(ret_id)
94
94
 
95
95
  plan.plan_search_path = [File.expand_path("../plan", plan.file_path)]
96
- plan.script_search_path = [File.expand_path("../script", plan.file_path)]
96
+ plan.script_search_path = [File.expand_path("../script", plan.file_path),
97
+ plan.jkr_env.jkr_script_dir]
97
98
 
98
99
  unless plan.file_path
99
100
  raise ArgumentError.new("Not valid result ID: #{ret_id}")
100
101
  end
101
102
 
103
+ resultset_num = sprintf "%05d", ret_id
104
+ dirs = Dir.glob(File.join(plan.jkr_env.jkr_result_dir, resultset_num)+"*")
105
+ if dirs.size == 0
106
+ raise RuntimeError.new("Resultset not found: #{ret_id}")
107
+ elsif dirs.size > 1
108
+ raise RuntimeError.new("Cannot identify result set directory")
109
+ end
110
+ plan.resultset_dir = dirs.first
111
+
102
112
  PlanLoader.load_plan(plan)
103
113
 
104
114
  plan
@@ -185,7 +195,7 @@ module Jkr
185
195
  @plan
186
196
  end
187
197
 
188
- def use_script(name)
198
+ def use_script(name, use = true)
189
199
  # find script file
190
200
  if name.is_a? Symbol
191
201
  name = name.to_s + ".rb"
@@ -206,12 +216,18 @@ module Jkr
206
216
 
207
217
  if path
208
218
  load path
209
- @plan.used_scripts.push(path)
219
+ if use
220
+ @plan.used_scripts.push(path)
221
+ end
210
222
  else
211
223
  raise RuntimeError.new("Cannot use script: #{name}")
212
224
  end
213
225
  end
214
226
 
227
+ def load_script(name)
228
+ use_script(name, false)
229
+ end
230
+
215
231
  def extend(base_plan_name)
216
232
  base_plan = Plan.create_by_name(self.plan.jkr_env, base_plan_name.to_s,
217
233
  :plan_search_path => @plan.plan_search_path,
@@ -374,7 +390,7 @@ module Jkr
374
390
  {'message'=>message})
375
391
  end
376
392
 
377
- def sh(*args)
393
+ def sh_(*args)
378
394
  puts "sh: #{args.join(' ')}"
379
395
  return system(*args)
380
396
  end
@@ -387,8 +403,12 @@ module Jkr
387
403
  true
388
404
  end
389
405
 
406
+ # for backward compatibility
390
407
  alias :system_ :sh!
391
408
 
409
+ # raise Error on failure by default
410
+ alias :sh :sh!
411
+
392
412
  def su_sh(*args)
393
413
  puts "su_sh: #{args.join(' ')}"
394
414
  su_cmd = File.expand_path("../su_cmd", __FILE__)
@@ -6,6 +6,8 @@ require 'jkr/utils'
6
6
  module Jkr
7
7
  class Trial
8
8
  attr_reader :params
9
+ attr_reader :result_dir
10
+
9
11
  def self.make_trials(resultset_dir, plan)
10
12
  var_combs = [{}]
11
13
  plan.vars.each do |key, vals|
@@ -25,8 +27,7 @@ module Jkr
25
27
  params_list = params_list * plan.routine_nr_run
26
28
 
27
29
  params_list.map do |params|
28
- result_dir = Utils.reserve_next_dir(resultset_dir)
29
- Trial.new(result_dir, plan, params)
30
+ Trial.new(resultset_dir, plan, params)
30
31
  end
31
32
  end
32
33
 
@@ -40,7 +41,7 @@ module Jkr
40
41
 
41
42
  def self.run(env, plan, delete_files_on_error = true)
42
43
  plan_suffix = File.basename(plan.file_path, ".plan")
43
- plan_suffix += "_#{plan.short_desc}" if plan.short_desc
44
+ plan_suffix += "_#{plan.short_desc}" if plan.short_desc && plan.short_desc.size > 0
44
45
  resultset_dir = Utils.reserve_next_dir(env.jkr_result_dir, plan_suffix)
45
46
  plan.resultset_dir = resultset_dir
46
47
  FileUtils.mkdir_p(File.join(resultset_dir, "plan"))
@@ -73,28 +74,71 @@ module Jkr
73
74
  params = plan.params.merge(plan.vars)
74
75
  plan.freeze
75
76
 
77
+ save_info(plan, :start_time => Time.now)
78
+
76
79
  # show estimated execution time if available
77
80
  if plan.exec_time_estimate
78
81
  puts("")
79
82
  puts("== estimated execution time: #{pretty_time(plan.exec_time_estimate.call(plan))} ==")
80
83
  puts("")
81
84
  end
82
-
83
- plan.do_prep()
84
- trials.each do |trial|
85
- trial.run
86
- end
87
- plan.do_cleanup()
88
85
  rescue Exception => err
89
86
  if delete_files_on_error
90
87
  FileUtils.rm_rf(resultset_dir)
91
88
  end
92
89
  raise err
93
90
  end
91
+
92
+ resume(env, plan)
93
+ end
94
+
95
+ def self.resume(env, plan)
96
+ trials = self.make_trials(plan.resultset_dir, plan)
97
+
98
+ save_info(plan, :last_resume_time => Time.now)
99
+
100
+ plan.do_prep()
101
+ trials.each do |trial|
102
+ begin
103
+ trial.run
104
+ rescue Exception => err
105
+ failed_dir = File.expand_path("../_failed_" + File.basename(trial.result_dir),
106
+ trial.result_dir)
107
+ i = 1
108
+ while Dir.exists?(failed_dir)
109
+ failed_dir = File.expand_path("../_failed_" + File.basename(trial.result_dir) + "_#{i}",
110
+ trial.result_dir)
111
+ i += 1
112
+ end
113
+ FileUtils.mv(trial.result_dir, failed_dir)
114
+ save_info(plan, :last_failure_time => Time.now)
115
+
116
+ raise err
117
+ end
118
+ end
119
+ plan.do_cleanup()
120
+
121
+ save_info(plan, :finish_time => Time.now)
122
+ end
123
+
124
+ def self.save_info(plan, data = {})
125
+ info_path = File.expand_path("INFO", plan.resultset_dir)
126
+ unless File.exists?(info_path)
127
+ File.open(info_path, "w") do |f|
128
+ f.puts(JSON.pretty_generate({}))
129
+ end
130
+ end
131
+
132
+ info_data = JSON.load(File.open(info_path))
133
+ info_data = info_data.merge(data)
134
+
135
+ File.open(info_path, "w") do |f|
136
+ f.puts(JSON.pretty_generate(info_data))
137
+ end
94
138
  end
95
139
 
96
- def initialize(result_dir, plan, params)
97
- @result_dir = result_dir
140
+ def initialize(resultset_dir, plan, params)
141
+ @resultset_dir = resultset_dir
98
142
  @plan = plan
99
143
  @params = params
100
144
  end
@@ -102,27 +146,50 @@ module Jkr
102
146
 
103
147
  def run()
104
148
  plan = @plan
105
- File.open("#{@result_dir}/params.json", "w") do |f|
106
- f.puts(@params.to_json)
149
+
150
+ # check duplicate execution
151
+ Dir.glob("#{@resultset_dir}/*").select do |path|
152
+ File.basename(path) =~ /^[0-9]{5}$/
153
+ end.each do |result_dir|
154
+ params = Marshal.load(File.open("#{result_dir}/params.msh"))
155
+
156
+ if params == @params
157
+ # already executed trial. skip.
158
+ return false
159
+ end
107
160
  end
108
161
 
109
- # reset plan.metastore
110
- plan.metastore.clear
162
+ # make result dir for this trial
163
+ @result_dir = Utils.reserve_next_dir(@resultset_dir)
164
+
165
+ Dir.chdir(@result_dir) do
166
+ # save params
167
+ File.open("#{@result_dir}/params.msh", "w") do |f|
168
+ Marshal.dump(@params, f)
169
+ end
170
+ File.open("#{@result_dir}/params.json", "w") do |f|
171
+ f.puts(JSON.pretty_generate(@params))
172
+ end
111
173
 
112
- # define utility functions for plan.routine object
113
- Jkr::TrialUtils.define_routine_utils(@result_dir, @plan, @params)
174
+ # reset plan.metastore
175
+ plan.metastore.clear
114
176
 
115
- @plan.metastore[:trial_start_time] = Time.now
116
- @plan.do_routine(@plan, @params)
117
- @plan.metastore[:trial_end_time] = Time.now
177
+ # define utility functions for plan.routine object
178
+ Jkr::TrialUtils.define_routine_utils(@result_dir, @plan, @params)
118
179
 
119
- Jkr::TrialUtils.undef_routine_utils(@plan)
180
+ @plan.metastore[:vars] = @plan.vars.keys
181
+ @plan.metastore[:trial_start_time] = Time.now
182
+ @plan.do_routine(@plan, @params)
183
+ @plan.metastore[:trial_end_time] = Time.now
120
184
 
121
- # save plan.metastore
122
- Marshal.dump(@plan.metastore,
123
- File.open("#{@result_dir}/metastore.msh", "w"))
124
- File.open("#{@result_dir}/metastore.json", "w") do |f|
125
- f.puts(@plan.metastore.to_json)
185
+ Jkr::TrialUtils.undef_routine_utils(@plan)
186
+
187
+ # save plan.metastore
188
+ Marshal.dump(@plan.metastore,
189
+ File.open("#{@result_dir}/metastore.msh", "w"))
190
+ File.open("#{@result_dir}/metastore.json", "w") do |f|
191
+ f.puts(JSON.pretty_generate(@plan.metastore))
192
+ end
126
193
  end
127
194
  end
128
195
  end
@@ -1,3 +1,3 @@
1
1
  module Jkr
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jkr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuto Hayamizu
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-10-08 00:00:00.000000000 Z
11
+ date: 2016-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -133,7 +133,6 @@ files:
133
133
  - ".gitignore"
134
134
  - ".rspec"
135
135
  - Gemfile
136
- - Gemfile.lock
137
136
  - Guardfile
138
137
  - History.txt
139
138
  - LICENSE.txt
@@ -1,81 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- jkr (0.1.0)
5
- term-ansicolor
6
- thor
7
-
8
- GEM
9
- remote: https://rubygems.org/
10
- specs:
11
- coderay (1.1.1)
12
- diff-lcs (1.2.5)
13
- ffi (1.9.14)
14
- formatador (0.2.5)
15
- guard (2.14.0)
16
- formatador (>= 0.2.4)
17
- listen (>= 2.7, < 4.0)
18
- lumberjack (~> 1.0)
19
- nenv (~> 0.1)
20
- notiffany (~> 0.0)
21
- pry (>= 0.9.12)
22
- shellany (~> 0.0)
23
- thor (>= 0.18.1)
24
- guard-compat (1.2.1)
25
- guard-rspec (4.7.3)
26
- guard (~> 2.1)
27
- guard-compat (~> 1.1)
28
- rspec (>= 2.99.0, < 4.0)
29
- listen (3.1.5)
30
- rb-fsevent (~> 0.9, >= 0.9.4)
31
- rb-inotify (~> 0.9, >= 0.9.7)
32
- ruby_dep (~> 1.2)
33
- lumberjack (1.0.10)
34
- method_source (0.8.2)
35
- nenv (0.3.0)
36
- notiffany (0.1.1)
37
- nenv (~> 0.1)
38
- shellany (~> 0.0)
39
- pry (0.10.4)
40
- coderay (~> 1.1.0)
41
- method_source (~> 0.8.1)
42
- slop (~> 3.4)
43
- rake (11.2.2)
44
- rb-fsevent (0.9.7)
45
- rb-inotify (0.9.7)
46
- ffi (>= 0.5.0)
47
- rspec (3.5.0)
48
- rspec-core (~> 3.5.0)
49
- rspec-expectations (~> 3.5.0)
50
- rspec-mocks (~> 3.5.0)
51
- rspec-core (3.5.2)
52
- rspec-support (~> 3.5.0)
53
- rspec-expectations (3.5.0)
54
- diff-lcs (>= 1.2.0, < 2.0)
55
- rspec-support (~> 3.5.0)
56
- rspec-mocks (3.5.0)
57
- diff-lcs (>= 1.2.0, < 2.0)
58
- rspec-support (~> 3.5.0)
59
- rspec-support (3.5.0)
60
- ruby_dep (1.4.0)
61
- shellany (0.0.1)
62
- slop (3.6.0)
63
- term-ansicolor (1.3.2)
64
- tins (~> 1.0)
65
- thor (0.19.1)
66
- tins (1.12.0)
67
-
68
- PLATFORMS
69
- ruby
70
-
71
- DEPENDENCIES
72
- bundler
73
- guard
74
- guard-rspec
75
- jkr!
76
- pry
77
- rake
78
- rspec
79
-
80
- BUNDLED WITH
81
- 1.11.2