miga-base 0.6.3.0 → 0.6.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b225951f374bcd267560e5bd8234fb88bcd6b0c11b0561fb4b3b479af39c4b3
4
- data.tar.gz: 9b32d40ea94ceb526fe0ba732c77fce978b0cba5decffd4e1c0d701594670dbd
3
+ metadata.gz: 9b94d26cedfe4ef7f4fd537dd668777c9ee3820eeb670a106e744250cdc72566
4
+ data.tar.gz: 37cfd446014fe396ef6ce15d5289e11118095349d400aeefe16f84985f77c27d
5
5
  SHA512:
6
- metadata.gz: b7fe9b2cbb09b6612b762c7c9202b4b27ece7a0b6f4dd23eecee9bddc835c130f15a63772011106a1f0f1425e5445fa1541a8ebc81661ef341dcacec3ae22193
7
- data.tar.gz: 501fa797aa6726ac5cdc6c043a3073d03a7ba3ed81d63ebac9ef989a76aa1947806c9052ab50c089567001ad1b1b92ad04cc05ea4ca33691de36c4dcb2e34b52
6
+ metadata.gz: 44e9dbe946ab889bb8bef0423544cec4d44894f9617ae28bf9ca33094ceaae16a662816110af42fc8a8941834bdf47f623eb6ec42afb3f0da405bb1267503d30
7
+ data.tar.gz: 30f712d1f2d9c540d571f66cd5b8b5d21e70540f85ec2b126f11949ea2029d935d5344594817c543d81ce26917c6e5d837798b185000d079c8c700a2ac6f13d8
@@ -118,7 +118,7 @@ module MiGA::Cli::Action::Init::DaemonHelper
118
118
  v
119
119
  end
120
120
 
121
- def configure_qsub_msub_daemon
121
+ def configure_qsub_msub_daemon(v)
122
122
  queue = cli.ask_user('What queue should I use?', nil, nil, true)
123
123
  v[:latency] = cli.ask_user('How long should I sleep? (in secs)', '150').to_i
124
124
  v[:maxjobs] = cli.ask_user('How many jobs can I launch at once?', '300').to_i
@@ -132,6 +132,7 @@ module MiGA::Cli::Action::Wf
132
132
  # Add datasets
133
133
  call_cli([
134
134
  'add',
135
+ '--ignore-dups',
135
136
  '-P', cli[:outdir],
136
137
  '-t', cli[:dataset_type],
137
138
  '-i', stage,
@@ -0,0 +1,70 @@
1
+
2
+ ##
3
+ # Helper module including specific functions to handle objects that
4
+ # have results.
5
+ module MiGA::Common::WithResult
6
+ ##
7
+ # Result directories as a Hash
8
+ def result_dirs
9
+ self.class.RESULT_DIRS
10
+ end
11
+
12
+ ##
13
+ # Look for the result with symbol key +task+ and register it in the object.
14
+ # If +save+ is false, it doesn't register the result, but it still returns a
15
+ # result if it already exists.
16
+ #
17
+ # The +opts+ hash controls result creation (if necessary).
18
+ # Supported values include:
19
+ # - +is_clean+: A Boolean indicating if the input files are clean
20
+ # - +force+: A Boolean indicating if the result must be re-indexed,
21
+ # ignored unless +save = true+
22
+ #
23
+ # Returns MiGA::Result or nil
24
+ def add_result(task, save = true, opts = {})
25
+ task = task.to_sym
26
+ return nil if result_dirs[task].nil?
27
+ base = File.join(
28
+ project.path, "data/#{result_dirs[task]}/#{result_base}"
29
+ )
30
+ json = "#{base}.json"
31
+ return MiGA::Result.load(json) unless save
32
+
33
+ MiGA::Result.create(json, opts[:force]) do
34
+ r = send("add_result_#{task}", base, opts) if File.exist?("#{base}.done")
35
+ unless r.nil?
36
+ r.save
37
+ pull_hook(:on_result_ready, r.key)
38
+ end
39
+ end
40
+ end
41
+
42
+ ##
43
+ # Get the result MiGA::Result in this object identified by the symbol +task+
44
+ def result(task)
45
+ task = task.to_sym
46
+ return nil if result_dirs[task].nil?
47
+ MiGA::Result.load(
48
+ "#{project.path}/data/#{result_dirs[task]}/#{result_base}.json"
49
+ )
50
+ end
51
+
52
+ ##
53
+ # Get all the results (Array of MiGA::Result) in this object
54
+ def results
55
+ result_dirs.keys.map { |k| result k }.compact
56
+ end
57
+
58
+ ##
59
+ # For each result execute the 2-ary block: key symbol and MiGA::Result
60
+ def each_result
61
+ results.each { |res| yield(res.key, res) }
62
+ end
63
+
64
+ ##
65
+ # Get a result as MiGA::Result for the object with key +task+.
66
+ # This is equivalent to +add_result(task, false)+.
67
+ def get_result(task)
68
+ add_result(task, false)
69
+ end
70
+ end
@@ -198,7 +198,7 @@ class MiGA::Daemon < MiGA::MiGA
198
198
  @jobs_running.select! do |job|
199
199
  ongoing = case job[:job].to_s
200
200
  when 'd'
201
- !job[:ds].next_preprocessing(false).nil?
201
+ !job[:ds].nil? && !job[:ds].next_preprocessing(false).nil?
202
202
  when 'p'
203
203
  !project.next_task(nil, false).nil?
204
204
  else
@@ -244,6 +244,8 @@ class MiGA::Daemon < MiGA::MiGA
244
244
  say 'MiGA:%s launched' % project.name
245
245
  say '-----------------------------------'
246
246
  load_status
247
+ say 'Configuration options:'
248
+ say @runopts.to_s
247
249
  @loop_i = 0
248
250
  end
249
251
  @loop_i += 1
@@ -143,18 +143,6 @@ class MiGA::Dataset < MiGA::MiGA
143
143
  metadata[:inactive].nil? or !metadata[:inactive]
144
144
  end
145
145
 
146
- ##
147
- # Should I ignore +task+ for this dataset?
148
- def ignore_task?(task)
149
- return true unless is_active?
150
- return !metadata["run_#{task}"] unless metadata["run_#{task}"].nil?
151
- return true if task == :taxonomy and project.metadata[:ref_project].nil?
152
- pattern = [true, false]
153
- ( [@@_EXCLUDE_NOREF_TASKS_H[task], is_ref? ] == pattern or
154
- [@@_ONLY_MULTI_TASKS_H[task], is_multi? ] == pattern or
155
- [@@_ONLY_NONMULTI_TASKS_H[task], is_nonmulti?] == pattern )
156
- end
157
-
158
146
  ##
159
147
  # Returns an Array of +how_many+ duples (Arrays) sorted by AAI:
160
148
  # - +0+: A String with the name(s) of the reference dataset.
@@ -172,5 +160,5 @@ class MiGA::Dataset < MiGA::MiGA
172
160
  'GROUP BY seq2 ORDER BY aai DESC LIMIT ?', [name, how_many])
173
161
  end
174
162
 
175
- end # class MiGA::Dataset
163
+ end
176
164
 
@@ -17,7 +17,6 @@ require 'miga/common/hooks'
17
17
  # - clear_run_counts()
18
18
  # - run_cmd(cmd)
19
19
  # Internal hooks:
20
- # - _pull_preprocessing_ready_hooks()
21
20
  # - _pull_result_hooks()
22
21
  module MiGA::Dataset::Hooks
23
22
 
@@ -26,10 +25,7 @@ module MiGA::Dataset::Hooks
26
25
  def default_hooks
27
26
  {
28
27
  on_preprocessing_ready: [[:clear_run_counts]],
29
- on_result_ready: [
30
- [:_pull_result_hooks],
31
- [:_pull_preprocessing_ready_hooks]
32
- ]
28
+ on_result_ready: [[:_pull_result_hooks]]
33
29
  }
34
30
  end
35
31
 
@@ -57,17 +53,12 @@ module MiGA::Dataset::Hooks
57
53
  )
58
54
  end
59
55
 
60
- ##
61
- # Pull :dataset_ready hook if preprocessing is complete
62
- def hook__pull_preprocessing_ready_hooks(_hook_args, _event_args)
63
- pull_hook(:on_preprocessing_ready) if done_preprocessing?
64
- end
65
-
66
56
  ##
67
57
  # Dataset Action :pull_result_hooks([], [res])
68
58
  # Pull the hook specific to the type of result
69
59
  def hook__pull_result_hooks(_hook_args, event_args)
70
60
  pull_hook(:"on_result_ready_#{event_args.first}", *event_args)
61
+ pull_hook(:on_preprocessing_ready) if done_preprocessing?
71
62
  end
72
63
 
73
64
  end
@@ -1,68 +1,53 @@
1
-
2
1
  require 'sqlite3'
3
2
  require 'miga/result'
4
3
  require 'miga/dataset/base'
4
+ require 'miga/common/with_result'
5
5
 
6
6
  ##
7
7
  # Helper module including specific functions to add dataset results
8
8
  module MiGA::Dataset::Result
9
9
  include MiGA::Dataset::Base
10
+ include MiGA::Common::WithResult
10
11
 
11
12
  ##
12
- # Get the result MiGA::Result in this dataset identified by the symbol +k+
13
- def result(k)
14
- return nil if @@RESULT_DIRS[k.to_sym].nil?
15
- MiGA::Result.load(
16
- "#{project.path}/data/#{@@RESULT_DIRS[k.to_sym]}/#{name}.json"
17
- )
13
+ # Return the basename for results
14
+ def result_base
15
+ name
18
16
  end
19
17
 
20
18
  ##
21
- # Get all the results (Array of MiGA::Result) in this dataset
22
- def results
23
- @@RESULT_DIRS.keys.map { |k| result k }.compact
19
+ # Should I ignore +task+ for this dataset?
20
+ def ignore_task?(task)
21
+ why_ignore(task) != :execute
24
22
  end
25
23
 
26
24
  ##
27
- # For each result executes the 2-ary block: key symbol and MiGA::Result
28
- def each_result
29
- @@RESULT_DIRS.each_key do |k|
30
- yield(k, result(k)) unless result(k).nil?
31
- end
32
- end
33
-
34
- ##
35
- # Look for the result with symbol key +result_type+ and register it in the
36
- # dataset. If +save+ is false, it doesn't register the result, but it still
37
- # returns a result if the expected files are complete. The +opts+ hash
38
- # controls result creation (if necessary). Supported values include:
39
- # - +is_clean+: A Boolean indicating if the input files are clean
40
- # - +force+: A Boolean indicating if the result must be re-indexed.
41
- # If true, it implies +save = true+
42
- # Returns MiGA::Result or nil.
43
- def add_result(result_type, save = true, opts = {})
44
- dir = @@RESULT_DIRS[result_type]
45
- return nil if dir.nil?
46
- base = File.expand_path("data/#{dir}/#{name}", project.path)
47
- if opts[:force]
48
- FileUtils.rm("#{base}.json") if File.exist?("#{base}.json")
25
+ # Return a code explaining why a task is ignored.
26
+ # The values are symbols:
27
+ # - empty: the dataset has no data
28
+ # - inactive: the dataset is inactive
29
+ # - force: forced to ignore by metadata
30
+ # - project: incompatible project
31
+ # - noref: incompatible dataset, only for reference
32
+ # - multi: incompatible dataset, only for multi
33
+ # - nonmulti: incompatible dataset, only for nonmulti
34
+ # - execute: do not ignore, execute the task
35
+ def why_ignore(task)
36
+ if !is_active?
37
+ :inactive
38
+ elsif !metadata["run_#{task}"].nil?
39
+ metadata["run_#{task}"] ? :execute : :force
40
+ elsif task == :taxonomy && project.metadata[:ref_project].nil?
41
+ :project
42
+ elsif @@_EXCLUDE_NOREF_TASKS_H[task] && !is_ref?
43
+ :noref
44
+ elsif @@_ONLY_MULTI_TASKS_H[task] && !is_multi?
45
+ :multi
46
+ elsif @@_ONLY_NONMULTI_TASKS_H[task] && !is_nonmulti?
47
+ :nonmulti
49
48
  else
50
- r_pre = MiGA::Result.load("#{base}.json")
51
- return r_pre if (r_pre.nil? && !save) || !r_pre.nil?
49
+ :execute
52
50
  end
53
- fun = "add_result_#{result_type}"
54
- r = send(fun, base, opts) if File.exist?("#{base}.done")
55
- return if r.nil?
56
- r.save
57
- pull_hook(:on_result_ready, result_type)
58
- r
59
- end
60
-
61
- ##
62
- # Gets a result as MiGA::Result for the datasets with +result_type+. This is
63
- # equivalent to +add_result(result_type, false)+.
64
- def get_result(result_type)
65
- add_result(result_type, false)
66
51
  end
67
52
 
68
53
  ##
@@ -76,24 +61,22 @@ module MiGA::Dataset::Result
76
61
  end
77
62
 
78
63
  ##
79
- # Returns the key symbol of the next task that needs to be executed. Passes
80
- # +save+ to #add_result.
64
+ # Returns the key symbol of the next task that needs to be executed or nil.
65
+ # Passes +save+ to #add_result.
81
66
  def next_preprocessing(save = false)
82
- after_first = false
83
- first = first_preprocessing(save)
84
- return nil if first.nil?
85
- @@PREPROCESSING_TASKS.each do |t|
86
- next if ignore_task? t
87
- if after_first && add_result(t, save).nil?
67
+ first = first_preprocessing(save) or return nil
68
+ @@PREPROCESSING_TASKS[@@PREPROCESSING_TASKS.index(first) .. -1].find do |t|
69
+ if ignore_task? t
70
+ false
71
+ elsif add_result(t, save).nil?
88
72
  if (metadata["_try_#{t}"] || 0) > (project.metadata[:max_try] || 10)
89
73
  inactivate!
90
- return nil
74
+ false
75
+ else
76
+ true
91
77
  end
92
- return t
93
78
  end
94
- after_first = (after_first || (t == first))
95
79
  end
96
- nil
97
80
  end
98
81
 
99
82
  ##
@@ -133,14 +116,7 @@ module MiGA::Dataset::Result
133
116
  ##
134
117
  # Returns the status of +task+. The status values are symbols:
135
118
  # - -: the task is upstream from the initial input
136
- # - ignore_empty: the dataset has no data
137
- # - ignore_inactive: the dataset is inactive
138
- # - ignore_force: forced to ignore by metadata
139
- # - ignore_project: incompatible project
140
- # - ignore_noref: incompatible dataset, only for reference
141
- # - ignore_multi: incompatible dataset, only for multi
142
- # - ignore_nonmulti: incompatible dataset, only for nonmulti
143
- # - ignore: incompatible dataset, unknown reason
119
+ # - ignore_*: the task is to be ignored, see codes in #why_ignore
144
120
  # - complete: a task with registered results
145
121
  # - pending: a task queued to be performed
146
122
  def result_status(task)
@@ -152,21 +128,7 @@ module MiGA::Dataset::Result
152
128
  @@PREPROCESSING_TASKS.index(first_preprocessing)
153
129
  :-
154
130
  elsif ignore_task?(task)
155
- if !is_active?
156
- :ignore_inactive
157
- elsif metadata["run_#{task}"]
158
- :ignore_force
159
- elsif task == :taxonomy && project.metadata[:ref_project].nil?
160
- :ignore_project
161
- elsif @@_EXCLUDE_NOREF_TASKS_H[task] && !is_ref?
162
- :ignore_noref
163
- elsif @@_ONLY_MULTI_TASKS_H[task] && !is_multi?
164
- :ignore_multi
165
- elsif @@_ONLY_NONMULTI_TASKS_H[task] && !is_nonmulti?
166
- :ignore_nonmulti
167
- else
168
- :ignore
169
- end
131
+ :"ignore_#{why_ignore task}"
170
132
  else
171
133
  :pending
172
134
  end
@@ -16,7 +16,6 @@ require 'miga/common/hooks'
16
16
  # - run_lambda(lambda, args...)
17
17
  # - run_cmd(cmd)
18
18
  # Internal hooks:
19
- # - _pull_processing_ready_hooks()
20
19
  # - _pull_result_hooks()
21
20
  module MiGA::Project::Hooks
22
21
 
@@ -24,10 +23,7 @@ module MiGA::Project::Hooks
24
23
 
25
24
  def default_hooks
26
25
  {
27
- on_result_ready: [
28
- [:_pull_result_hooks],
29
- [:_pull_processing_ready_hooks]
30
- ]
26
+ on_result_ready: [[:_pull_result_hooks]]
31
27
  }
32
28
  end
33
29
 
@@ -44,17 +40,12 @@ module MiGA::Project::Hooks
44
40
  )
45
41
  end
46
42
 
47
- ##
48
- # Pull :dataset_ready hook if preprocessing is complete
49
- def hook__pull_processing_ready_hooks(_hook_args, _event_args)
50
- pull_hook(:on_processing_ready) if next_task(nil, false).nil?
51
- end
52
-
53
43
  ##
54
44
  # Dataset Action :pull_result_hooks([], [res])
55
45
  # Pull the hook specific to the type of result
56
46
  def hook__pull_result_hooks(_hook_args, event_args)
57
47
  pull_hook(:"on_result_ready_#{event_args.first}", *event_args)
48
+ pull_hook(:on_processing_ready) if next_task(nil, false).nil?
58
49
  end
59
50
 
60
51
  end
@@ -3,69 +3,47 @@
3
3
 
4
4
  require 'miga/result'
5
5
  require 'miga/project/base'
6
+ require 'miga/common/with_result'
6
7
 
7
8
  ##
8
9
  # Helper module including specific functions to add project results.
9
10
  module MiGA::Project::Result
10
-
11
11
  include MiGA::Project::Base
12
+ include MiGA::Common::WithResult
12
13
 
13
14
  ##
14
- # Get result identified by Symbol +name+, returns MiGA::Result.
15
- def result(name)
16
- dir = @@RESULT_DIRS[name.to_sym]
17
- return nil if dir.nil?
18
- MiGA::Result.load("#{path}/data/#{dir}/miga-project.json")
15
+ # Return the basename for results
16
+ def result_base
17
+ 'miga-project'
19
18
  end
20
19
 
21
20
  ##
22
- # Get all results, an Array of MiGA::Result.
23
- def results
24
- @@RESULT_DIRS.keys.map{ |k| result(k) }.reject{ |r| r.nil? }
25
- end
26
-
27
- ##
28
- # For each result executes the 2-ary +blk+ block: key symbol and MiGA::Result.
29
- def each_result(&blk)
30
- @@RESULT_DIRS.keys.each do |k|
31
- blk.call(k, result(k)) unless result(k).nil?
32
- end
21
+ # Return itself, to simplify modules
22
+ def project
23
+ self
33
24
  end
34
25
 
35
26
  ##
36
- # Add the result identified by Symbol +name+, and return MiGA::Result. Save
37
- # the result if +save+. The +opts+ hash controls result creation (if
38
- # necessary).
39
- # Supported values include:
40
- # - +force+: A Boolean indicating if the result must be re-indexed. If true,
41
- # it implies save=true.
42
- def add_result(name, save = true, opts = {})
43
- return nil if @@RESULT_DIRS[name].nil?
44
- base = "#{path}/data/#{@@RESULT_DIRS[name]}/miga-project"
45
- if opts[:force]
46
- FileUtils.rm("#{base}.json") if File.exist?("#{base}.json")
47
- else
48
- r_pre = MiGA::Result.load("#{base}.json")
49
- return r_pre if (r_pre.nil? && !save) || !r_pre.nil?
50
- end
51
- r = result_files_exist?(base, ".done") ?
52
- send("add_result_#{name}", base) : nil
53
- unless r.nil?
54
- r.save
55
- pull_hook(:on_result_ready, name)
56
- end
57
- r
27
+ # Is this +task+ to be bypassed?
28
+ def ignore_task?(task)
29
+ metadata["run_#{task}"] == false ||
30
+ (!is_clade? && @@INCLADE_TASKS.include?(task) &&
31
+ metadata["run_#{task}"] != true)
58
32
  end
59
33
 
60
34
  ##
61
35
  # Get the next distances task, saving intermediate results if +save+. Returns
62
36
  # a Symbol.
63
- def next_distances(save = true) ; next_task(@@DISTANCE_TASKS, save) ; end
37
+ def next_distances(save = true)
38
+ next_task(@@DISTANCE_TASKS, save)
39
+ end
64
40
 
65
41
  ##
66
42
  # Get the next inclade task, saving intermediate results if +save+. Returns a
67
43
  # Symbol.
68
- def next_inclade(save = true) ; next_task(@@INCLADE_TASKS, save) ; end
44
+ def next_inclade(save = true)
45
+ next_task(@@INCLADE_TASKS, save)
46
+ end
69
47
 
70
48
  ##
71
49
  # Get the next task from +tasks+, saving intermediate results if +save+.
@@ -74,101 +52,104 @@ module MiGA::Project::Result
74
52
  def next_task(tasks = nil, save = true)
75
53
  tasks ||= @@DISTANCE_TASKS + @@INCLADE_TASKS
76
54
  tasks.find do |t|
77
- if metadata["run_#{t}"] == false or
78
- (!is_clade? and @@INCLADE_TASKS.include?(t) and
79
- metadata["run_#{t}"] != true)
80
- false
81
- else
82
- add_result(t, save).nil?
83
- end
55
+ ignore_task?(t) ? false : add_result(t, save).nil?
84
56
  end
85
57
  end
86
58
 
87
-
88
59
  private
89
60
 
90
- ##
91
- # Internal alias for all add_result_*_distances.
92
- def add_result_distances(base)
93
- return nil unless result_files_exist?(base, %w[.Rdata .log .txt])
94
- r = MiGA::Result.new("#{base}.json")
95
- r.add_file(:rdata, 'miga-project.Rdata')
96
- r.add_file(:matrix, 'miga-project.txt')
97
- r.add_file(:log, 'miga-project.log')
98
- r.add_file(:hist, 'miga-project.hist')
99
- r
100
- end
61
+ ##
62
+ # Add result of any type +:*_distances+ at +base+ (no +_opts+ supported).
63
+ def add_result_distances(base, _opts)
64
+ return nil unless result_files_exist?(base, %w[.Rdata .log .txt])
65
+ r = MiGA::Result.new("#{base}.json")
66
+ r.add_file(:rdata, 'miga-project.Rdata')
67
+ r.add_file(:matrix, 'miga-project.txt')
68
+ r.add_file(:log, 'miga-project.log')
69
+ r.add_file(:hist, 'miga-project.hist')
70
+ r
71
+ end
101
72
 
102
- def add_result_clade_finding(base)
103
- if result_files_exist?(base, %w[.empty])
104
- r = MiGA::Result.new("#{base}.json")
105
- r.add_file(:empty, 'miga-project.empty')
106
- return r
107
- end
108
- return nil unless result_files_exist?(base, %w[.proposed-clades])
109
- return nil unless is_clade? or result_files_exist?(base,
110
- %w[.pdf .classif .medoids .class.tsv .class.nwk])
111
- r = add_result_iter_clades(base)
112
- r.add_file(:aai_tree, 'miga-project.aai.nwk')
113
- r.add_file(:proposal, 'miga-project.proposed-clades')
114
- r.add_file(:clades_aai90, 'miga-project.aai90-clades')
115
- r.add_file(:clades_ani95, 'miga-project.ani95-clades')
116
- r.add_file(:clades_gsp, 'miga-project.gsp-clades')
117
- r.add_file(:medoids_gsp, 'miga-project.gsp-medoids')
118
- r
73
+ ##
74
+ # Add result type +:clade_finding+ at +base+ (no +_opts+ supported).
75
+ def add_result_clade_finding(base, _opts)
76
+ if result_files_exist?(base, %w[.empty])
77
+ r = MiGA::Result.new("#{base}.json")
78
+ r.add_file(:empty, 'miga-project.empty')
79
+ return r
119
80
  end
120
-
121
- def add_result_subclades(base)
122
- if result_files_exist?(base, %w[.empty])
123
- r = MiGA::Result.new("#{base}.json")
124
- r.add_file(:empty, 'miga-project.empty')
125
- return r
126
- end
127
- return nil unless result_files_exist?(base,
81
+ return nil unless result_files_exist?(base, %w[.proposed-clades])
82
+ return nil unless is_clade? or result_files_exist?(base,
128
83
  %w[.pdf .classif .medoids .class.tsv .class.nwk])
129
- r = add_result_iter_clades(base)
130
- r.add_file(:ani_tree, 'miga-project.ani.nwk')
131
- r
132
- end
84
+ r = add_result_iter_clades(base)
85
+ r.add_file(:aai_tree, 'miga-project.aai.nwk')
86
+ r.add_file(:proposal, 'miga-project.proposed-clades')
87
+ r.add_file(:clades_aai90, 'miga-project.aai90-clades')
88
+ r.add_file(:clades_ani95, 'miga-project.ani95-clades')
89
+ r.add_file(:clades_gsp, 'miga-project.gsp-clades')
90
+ r.add_file(:medoids_gsp, 'miga-project.gsp-medoids')
91
+ r
92
+ end
133
93
 
134
- def add_result_iter_clades(base)
94
+ ##
95
+ # Add result type +:subclades+ at +base+ (no +_opts+ supported).
96
+ def add_result_subclades(base, _opts)
97
+ if result_files_exist?(base, %w[.empty])
135
98
  r = MiGA::Result.new("#{base}.json")
136
- r.add_file(:report, 'miga-project.pdf')
137
- r.add_file(:class_table, 'miga-project.class.tsv')
138
- r.add_file(:class_tree, 'miga-project.class.nwk')
139
- r.add_file(:classif, 'miga-project.classif')
140
- r.add_file(:medoids, 'miga-project.medoids')
141
- r
99
+ r.add_file(:empty, 'miga-project.empty')
100
+ return r
142
101
  end
102
+ return nil unless result_files_exist?(base,
103
+ %w[.pdf .classif .medoids .class.tsv .class.nwk])
104
+ r = add_result_iter_clades(base)
105
+ r.add_file(:ani_tree, 'miga-project.ani.nwk')
106
+ r
107
+ end
143
108
 
144
- def add_result_ogs(base)
145
- if result_files_exist?(base, %w[.empty])
146
- r = MiGA::Result.new("#{base}.json")
147
- r.add_file(:empty, 'miga-project.empty')
148
- return r
149
- end
150
- return nil unless result_files_exist?(base, %w[.ogs .stats])
151
- r = MiGA::Result.new("#{base}.json")
152
- r.add_file(:ogs, 'miga-project.ogs')
153
- r.add_file(:abc, 'miga-project.abc')
154
- r.add_file(:stats, 'miga-project.stats')
155
- r.add_file(:core_pan, 'miga-project.core-pan.tsv')
156
- r.add_file(:core_pan_plot, 'miga-project.core-pan.pdf')
157
- r
158
- end
109
+ ##
110
+ # Helper function for clade iterations.
111
+ def add_result_iter_clades(base)
112
+ r = MiGA::Result.new("#{base}.json")
113
+ r.add_file(:report, 'miga-project.pdf')
114
+ r.add_file(:class_table, 'miga-project.class.tsv')
115
+ r.add_file(:class_tree, 'miga-project.class.nwk')
116
+ r.add_file(:classif, 'miga-project.classif')
117
+ r.add_file(:medoids, 'miga-project.medoids')
118
+ r
119
+ end
159
120
 
160
- def add_result_project_stats(base)
161
- return nil unless
162
- result_files_exist?(base, %w[.taxonomy.json .metadata.db])
121
+ ##
122
+ # Add result type +:ogs+ at +base+ (no +_opts+ supported).
123
+ def add_result_ogs(base, _opts)
124
+ if result_files_exist?(base, %w[.empty])
163
125
  r = MiGA::Result.new("#{base}.json")
164
- r.add_file(:taxonomy_index, 'miga-project.taxonomy.json')
165
- r.add_file(:metadata_index, 'miga-project.metadata.db')
166
- r
126
+ r.add_file(:empty, 'miga-project.empty')
127
+ return r
167
128
  end
129
+ return nil unless result_files_exist?(base, %w[.ogs .stats])
130
+ r = MiGA::Result.new("#{base}.json")
131
+ r.add_file(:ogs, 'miga-project.ogs')
132
+ r.add_file(:abc, 'miga-project.abc')
133
+ r.add_file(:stats, 'miga-project.stats')
134
+ r.add_file(:core_pan, 'miga-project.core-pan.tsv')
135
+ r.add_file(:core_pan_plot, 'miga-project.core-pan.pdf')
136
+ r
137
+ end
138
+
139
+ ##
140
+ # Add result type +:project_stats+ at +base+ (no +_opts+ supported).
141
+ def add_result_project_stats(base, _opts)
142
+ return nil unless
143
+ result_files_exist?(base, %w[.taxonomy.json .metadata.db])
144
+ r = MiGA::Result.new("#{base}.json")
145
+ r.add_file(:taxonomy_index, 'miga-project.taxonomy.json')
146
+ r.add_file(:metadata_index, 'miga-project.metadata.db')
147
+ r
148
+ end
168
149
 
169
- alias add_result_haai_distances add_result_distances
170
- alias add_result_aai_distances add_result_distances
171
- alias add_result_ani_distances add_result_distances
172
- alias add_result_ssu_distances add_result_distances
150
+ alias add_result_haai_distances add_result_distances
151
+ alias add_result_aai_distances add_result_distances
152
+ alias add_result_ani_distances add_result_distances
153
+ alias add_result_ssu_distances add_result_distances
173
154
 
174
155
  end
@@ -1,6 +1,7 @@
1
1
  # @package MiGA
2
2
  # @license Artistic-2.0
3
3
 
4
+ require 'miga/taxonomy'
4
5
  require 'miga/remote_dataset/download'
5
6
 
6
7
  ##
@@ -203,7 +204,7 @@ class MiGA::RemoteDataset < MiGA::MiGA
203
204
  when ''
204
205
  metadata[:is_type] = false
205
206
  metadata[:is_ref_type] = false
206
- when 'assembly from reference material'
207
+ when 'assembly from reference material', 'assembly designated as reftype'
207
208
  metadata[:is_type] = false
208
209
  metadata[:is_ref_type] = true
209
210
  metadata[:type_rel] = from_type
@@ -14,19 +14,28 @@ class MiGA::Result < MiGA::MiGA
14
14
  include MiGA::Result::Stats
15
15
 
16
16
  # Class-level
17
+ class << self
18
+ ##
19
+ # Check if the result described by the JSON in +path+ already exists
20
+ def exist?(path)
21
+ File.exist? path
22
+ end
17
23
 
18
- ##
19
- # Check if the result described by the JSON in +path+ already exists.
20
- def self.exist?(path)
21
- File.exist? path
22
- end
24
+ ##
25
+ # Load the result described by the JSON in +path+.
26
+ # Returns MiGA::Result if it already exists, nil otherwise.
27
+ def load(path)
28
+ return nil unless MiGA::Result.exist? path
29
+ MiGA::Result.new(path)
30
+ end
23
31
 
24
- ##
25
- # Load the result described by the JSON in +path+. Returns MiGA::Result if it
26
- # already exists, nil otherwise.
27
- def self.load(path)
28
- return nil unless MiGA::Result.exist? path
29
- MiGA::Result.new(path)
32
+ def create(path, force = false, &blk)
33
+ FileUtils.rm(path) if force && File.exist?(path)
34
+ r_pre = self.load(path)
35
+ return r_pre unless r_pre.nil?
36
+ yield
37
+ self.load(path)
38
+ end
30
39
  end
31
40
 
32
41
  # Instance-level
@@ -18,9 +18,13 @@ module MiGA::Result::Source
18
18
  ##
19
19
  # Detect the result key assigned to this result
20
20
  def key
21
- @key ||= MiGA::Result.RESULT_DIRS.find do |k, v|
22
- "data/#{v}" == relative_dir
23
- end.first
21
+ @key ||= if relative_dir == 'data/90.stats' && file_path(:metadata_index)
22
+ :project_stats
23
+ else
24
+ MiGA::Result.RESULT_DIRS.find do |k, v|
25
+ "data/#{v}" == relative_dir
26
+ end.first
27
+ end
24
28
  end
25
29
 
26
30
  ##
@@ -1,4 +1,5 @@
1
1
 
2
+ require 'zlib'
2
3
  require 'miga/result/base'
3
4
 
4
5
  ##
@@ -75,6 +76,16 @@ module MiGA::Result::Stats
75
76
  stats[:coding_density] =
76
77
  [300.0 * s[:tot] / asm[:stats][:total_length][0], '%']
77
78
  end
79
+ if file_path(:gff3) && file_path(:gff3) =~ /\.gz/
80
+ Zlib::GzipReader.open(file_path(:gff3)) do |fh|
81
+ fh.each do |ln|
82
+ if ln =~ /^# Model Data:.*;transl_table=(\d+);/
83
+ stats[:codon_table] = $1
84
+ break
85
+ end
86
+ end
87
+ end
88
+ end
78
89
  stats
79
90
  end
80
91
 
@@ -31,6 +31,7 @@ module MiGA::TaxDist
31
31
  # correspond to the p-values of +test+ (one of +:intax+ or +:novel+)
32
32
  # with options +opts+. See +aai_path+ for supported options.
33
33
  def aai_pvalues(aai, test, opts = {})
34
+ y = {}
34
35
  Zlib::GzipReader.open(aai_path(test, opts)) do |fh|
35
36
  keys = nil
36
37
  fh.each_line do |ln|
@@ -46,11 +47,13 @@ module MiGA::TaxDist
46
47
  rank = i.zero? ? :root : MiGA::Taxonomy.KNOWN_RANKS[i]
47
48
  vals[rank] = v.to_f
48
49
  end
49
- return vals
50
+ y = vals
51
+ break
50
52
  end
51
53
  end
54
+ fh.rewind # to avoid warnings caused by the break above
52
55
  end
53
- {}
56
+ y
54
57
  end
55
58
 
56
59
  ##
@@ -10,7 +10,7 @@ module MiGA
10
10
  # - Float representing the major.minor version.
11
11
  # - Integer representing gem releases of the current version.
12
12
  # - Integer representing minor changes that require new version number.
13
- VERSION = [0.6, 3, 0]
13
+ VERSION = [0.6, 3, 1]
14
14
 
15
15
  ##
16
16
  # Nickname for the current major.minor version.
@@ -18,7 +18,7 @@ module MiGA
18
18
 
19
19
  ##
20
20
  # Date of the current gem release.
21
- VERSION_DATE = Date.new(2020, 3, 27)
21
+ VERSION_DATE = Date.new(2020, 4, 11)
22
22
 
23
23
  ##
24
24
  # Reference of MiGA.
@@ -36,7 +36,7 @@ case "$TYPE" in
36
36
  | perl -pe 's/[^A-Z]//ig' | wc -c | awk '{print $1}')
37
37
  echo "# codon table $ct total length: $C_LEN aa" \
38
38
  >> "${DATASET}.ct.t"
39
- if [[ $C_LEN > $(($P_LEN * 11 / 10)) ]] ; then
39
+ if [[ $C_LEN -gt $(($P_LEN * 11 / 10)) ]] ; then
40
40
  for x in faa fna gff3 ; do
41
41
  mv "${DATASET}.$x.$ct" "${DATASET}.$x"
42
42
  done
@@ -115,7 +115,7 @@ class DaemonTest < Test::Unit::TestCase
115
115
  assert(l[0] =~ /-{20}\n/)
116
116
  assert(l[1] =~ /MiGA:#{p.name} launched/)
117
117
  assert(l[2] =~ /-{20}\n/)
118
- assert(l[3] =~ /Probing running jobs\n/)
118
+ assert(l[5] =~ /Probing running jobs\n/)
119
119
  end
120
120
  ensure
121
121
  begin
@@ -2,7 +2,6 @@ require 'test_helper'
2
2
  require 'miga/project'
3
3
 
4
4
  class ProjectTest < Test::Unit::TestCase
5
-
6
5
  def setup
7
6
  $tmp = Dir.mktmpdir
8
7
  ENV['MIGA_HOME'] = $tmp
@@ -16,6 +15,17 @@ class ProjectTest < Test::Unit::TestCase
16
15
  ENV['MIGA_HOME'] = nil
17
16
  end
18
17
 
18
+ def create_result_files(project, res, exts)
19
+ d = MiGA::Project.RESULT_DIRS[res]
20
+ (['.done'] + exts).each do |x|
21
+ assert_nil(
22
+ project.add_result(res),
23
+ "Premature registration of result #{res} at extension #{x}"
24
+ )
25
+ FileUtils.touch(File.join(project.path, "data/#{d}/miga-project#{x}"))
26
+ end
27
+ end
28
+
19
29
  def test_class_load
20
30
  assert_nil(MiGA::Project.load($tmp + '/O_o'))
21
31
  assert_equal(MiGA::Project, MiGA::Project.load($p1.path).class)
@@ -47,7 +57,8 @@ class ProjectTest < Test::Unit::TestCase
47
57
  assert_equal(MiGA::Dataset, d.class)
48
58
  assert_equal([d], p.datasets)
49
59
  assert_equal(['d1'], p.dataset_names)
50
- p.each_dataset{ |ds| assert_equal(d, ds) }
60
+ p.each_dataset { |ds| assert_equal(d, ds) }
61
+ p.each_dataset { |n, ds| assert_equal(n, ds.name) }
51
62
  dr = p.unlink_dataset('d1')
52
63
  assert_equal(d, dr)
53
64
  assert_equal([], p.datasets)
@@ -71,12 +82,10 @@ class ProjectTest < Test::Unit::TestCase
71
82
  assert_equal(1, p2.datasets.size)
72
83
  assert_equal(MiGA::Dataset, p2.dataset('d1').class)
73
84
  assert_equal(1, p2.dataset('d1').results.size)
74
- assert(File.exist?(
75
- File.expand_path("data/01.raw_reads/#{d1.name}.1.fastq", p2.path)
76
- ))
77
- assert(File.exist?(
78
- File.expand_path("metadata/#{d1.name}.json", p2.path)
79
- ))
85
+ assert(
86
+ File.exist?(File.join(p2.path, "data/01.raw_reads/#{d1.name}.1.fastq"))
87
+ )
88
+ assert(File.exist?(File.join(p2.path, "metadata/#{d1.name}.json")))
80
89
  end
81
90
 
82
91
  def test_add_result
@@ -85,7 +94,7 @@ class ProjectTest < Test::Unit::TestCase
85
94
  %w[.Rdata .log .txt .done].each do |x|
86
95
  assert_nil(p1.add_result(:haai_distances))
87
96
  FileUtils.touch(
88
- File.expand_path("data/09.distances/01.haai/miga-project#{x}",p1.path)
97
+ File.join(p1.path, "data/09.distances/01.haai/miga-project#{x}")
89
98
  )
90
99
  end
91
100
  assert_equal(MiGA::Result, p1.add_result(:haai_distances).class)
@@ -93,12 +102,12 @@ class ProjectTest < Test::Unit::TestCase
93
102
 
94
103
  def test_result
95
104
  p1 = $p1
96
- assert_nil(p1.result :n00b)
97
- assert_nil(p1.result :project_stats)
105
+ assert_nil(p1.result(:n00b))
106
+ assert_nil(p1.result(:project_stats))
98
107
  File.open(
99
108
  File.expand_path('data/90.stats/miga-project.json', p1.path), 'w'
100
109
  ) { |fh| fh.puts '{}' }
101
- assert_not_nil(p1.result :project_stats)
110
+ assert_not_nil(p1.result(:project_stats))
102
111
  assert_equal(1, p1.results.size)
103
112
  end
104
113
 
@@ -109,64 +118,48 @@ class ProjectTest < Test::Unit::TestCase
109
118
  assert(!p1.done_preprocessing?)
110
119
  FileUtils.touch(File.expand_path("data/90.stats/#{d1.name}.done", p1.path))
111
120
  assert(p1.done_preprocessing?)
121
+ assert_nil(p1.next_inclade)
122
+ p1.metadata[:type] = :clade
123
+ assert_equal(:subclades, p1.next_inclade)
112
124
 
113
- # Project stats
114
- assert_equal(:project_stats, p1.next_distances)
115
- d = MiGA::Project.RESULT_DIRS[:project_stats]
116
- %w[.done .taxonomy.json .metadata.db].each do |x|
117
- assert_nil(
118
- p1.add_result(:project_stats),
119
- "Premature registration of result project_stats at extension #{x}."
120
- )
121
- FileUtils.touch(File.expand_path("data/#{d}/miga-project#{x}", p1.path))
122
- end
123
- assert_equal(MiGA::Result, p1.add_result(:project_stats).class,
124
- 'Imposible to add project_stats result.')
125
-
126
- # Distances
127
- [:haai_distances, :aai_distances, :ani_distances].each do |r|
128
- assert_equal(r, p1.next_distances)
129
- assert_equal(Symbol, p1.next_distances.class)
130
- d = MiGA::Project.RESULT_DIRS[r]
131
- %w[.done .Rdata .log .txt].each do |x|
132
- assert_nil(
133
- p1.add_result(r),
134
- "Premature registration of result #{r} at extension #{x}."
135
- )
136
- FileUtils.touch(File.expand_path("data/#{d}/miga-project#{x}", p1.path))
137
- end
138
- assert_equal(MiGA::Result, p1.add_result(r).class,
139
- "Imposible to add #{r} result.")
125
+ # Project tasks
126
+ expected_files = {
127
+ project_stats: %w[.taxonomy.json .metadata.db],
128
+ haai_distances: %w[.Rdata .log .txt],
129
+ aai_distances: %w[.Rdata .log .txt],
130
+ ani_distances: %w[.Rdata .log .txt],
131
+ clade_finding: %w[.pdf .classif .medoids
132
+ .class.tsv .class.nwk .proposed-clades],
133
+ subclades: %w[.pdf .classif .medoids .class.tsv .class.nwk],
134
+ ogs: %w[.ogs .stats]
135
+ }
136
+ expected_files.each do |r, exts|
137
+ assert_equal(r, p1.next_task)
138
+ create_result_files(p1, r, exts)
139
+ assert_not_nil(p1.add_result(r), "Imposible to add #{r} result")
140
140
  end
141
- assert_equal(:clade_finding, p1.next_distances)
141
+ assert_nil(p1.next_task)
142
+ p1.each_result { |k, r| assert_equal(k, r.key) }
143
+ end
142
144
 
143
- # Clades
144
- assert_nil(p1.next_inclade)
145
+ def test_empty_results
146
+ p1 = $p1
145
147
  p1.metadata[:type] = :clade
146
- res = [
147
- [:clade_finding,
148
- %w[.pdf .classif .medoids .class.tsv .class.nwk .proposed-clades]],
149
- [:subclades, %w[.pdf .classif .medoids .class.tsv .class.nwk]],
150
- [:ogs, %w[.ogs .stats]]
151
- ]
152
- res.each do |rr|
153
- (r, xs) = rr
154
- d = MiGA::Project.RESULT_DIRS[r]
155
- assert_equal(Symbol, p1.next_inclade.class)
156
- ([".done"] + xs).each do |x|
157
- assert_nil(
158
- p1.add_result(r),
159
- "Premature registration of result #{r} at extension #{x}."
160
- )
161
- FileUtils.touch(File.expand_path("data/#{d}/miga-project#{x}", p1.path))
162
- end
163
- assert_equal(
164
- MiGA::Result,
165
- p1.add_result(r).class,
166
- "Impossible to add #{r} result."
167
- )
148
+ %i[clade_finding subclades ogs].each do |r|
149
+ assert_nil(p1.add_result(r), "Unexpected result exists: #{r}")
150
+ create_result_files(p1, r, %w[.empty])
151
+ assert_not_nil(p1.add_result(r), "Cannot register emtpy task: #{r}")
168
152
  end
169
- assert_nil(p1.next_inclade)
170
153
  end
171
154
 
155
+ def test_force_result
156
+ p1 = $p1
157
+ create_result_files(p1, :ogs, %w[.empty])
158
+ date1 = p1.add_result(:ogs)[:created]
159
+ sleep(1)
160
+ date2 = p1.add_result(:ogs, true, force: false)[:created]
161
+ assert_equal(date1, date2)
162
+ date3 = p1.add_result(:ogs, true, force: true)[:created]
163
+ assert_not_equal(date1, date3)
164
+ end
172
165
  end
@@ -30,10 +30,10 @@ class RemoteDatasetTest < Test::Unit::TestCase
30
30
 
31
31
  def test_rest
32
32
  hiv2 = 'M30502.1'
33
- {embl: :ebi, nuccore: :ncbi}.each do |db, universe|
33
+ { embl: :ebi, nuccore: :ncbi }.each do |db, universe|
34
34
  rd = MiGA::RemoteDataset.new(hiv2, db, universe)
35
35
  assert_equal([hiv2], rd.ids)
36
- omit_if(!$remote_tests, 'Remote access is error-prone.')
36
+ omit_if(!$remote_tests, 'Remote access is error-prone')
37
37
  tx = rd.get_ncbi_taxonomy
38
38
  msg = "Failed on #{universe}:#{db}"
39
39
  assert_equal(MiGA::Taxonomy, tx.class, msg)
@@ -57,7 +57,7 @@ class RemoteDatasetTest < Test::Unit::TestCase
57
57
  n = 'Cjac_L14'
58
58
  rd = MiGA::RemoteDataset.new(cjac, :assembly_gz, :web)
59
59
  assert_equal([cjac], rd.ids)
60
- omit_if(!$remote_tests, 'Remote access is error-prone.')
60
+ omit_if(!$remote_tests, 'Remote access is error-prone')
61
61
  p = $p1
62
62
  assert_nil(p.dataset(n))
63
63
  rd.save_to(p, n)
@@ -66,9 +66,54 @@ class RemoteDatasetTest < Test::Unit::TestCase
66
66
  assert_equal(MiGA::Result, p.dataset(n).result(:assembly).class)
67
67
  end
68
68
 
69
+ def test_asm_acc2id
70
+ omit_if(!$remote_tests, 'Remote access is error-prone')
71
+ assert_nil(MiGA::RemoteDataset.ncbi_asm_acc2id('NotAnAccession'))
72
+ id = MiGA::RemoteDataset.ncbi_asm_acc2id('GCA_004684205.1')
73
+ assert_equal('2514661', id)
74
+ assert_equal(id, MiGA::RemoteDataset.ncbi_asm_acc2id(id))
75
+ end
76
+
77
+ def test_update_metadata
78
+ omit_if(!$remote_tests, 'Remote access is error-prone')
79
+ hiv1 = 'GCF_000856385.1'
80
+ d1 = MiGA::Dataset.new($p1, 'd1')
81
+ assert_nil(d1.metadata[:ncbi_assembly])
82
+ rd = MiGA::RemoteDataset.new(hiv1, :assembly, :ncbi)
83
+ rd.update_metadata(d1, passthrough: 123, metadata_only: true)
84
+ assert_equal(123, d1.metadata[:passthrough])
85
+ assert_equal(hiv1, d1.metadata[:ncbi_assembly])
86
+ assert_equal('Lentivirus', d1.metadata[:tax][:g])
87
+ end
88
+
89
+ def test_type_status_asm
90
+ omit_if(!$remote_tests, 'Remote access is error-prone')
91
+ rd = MiGA::RemoteDataset.new('GCF_000018105.1', :assembly, :ncbi)
92
+ assert(rd.get_metadata[:is_type])
93
+ end
94
+
95
+ def test_nontype_status_asm
96
+ omit_if(!$remote_tests, 'Remote access is error-prone')
97
+ rd = MiGA::RemoteDataset.new('GCA_004684205.1', :assembly, :ncbi)
98
+ assert(!rd.get_metadata[:is_type])
99
+ end
100
+
101
+ def test_type_status_nuccore
102
+ omit_if(!$remote_tests, 'Remote access is error-prone')
103
+ rd = MiGA::RemoteDataset.new('NC_019748.1', :nuccore, :ncbi)
104
+ assert(rd.get_metadata[:is_type])
105
+ end
106
+
107
+ def test_ref_type_status
108
+ omit_if(!$remote_tests, 'Remote access is error-prone')
109
+ rd = MiGA::RemoteDataset.new('GCA_002849345', :assembly, :ncbi)
110
+ assert(!rd.get_metadata[:is_type])
111
+ assert(rd.get_metadata[:is_ref_type])
112
+ end
113
+
69
114
  # This test is too expensive (too much time to run it!)
70
115
  #def test_net_timeout
71
- # omit_if(!$remote_tests, "Remote access is error-prone.")
116
+ # omit_if(!$remote_tests, "Remote access is error-prone")
72
117
  # bad = "ftp://example.com/miga"
73
118
  # rd = MiGA::RemoteDataset.new(bad, :assembly, :web)
74
119
  # assert_raise(Net::ReadTimeout) { rd.save_to($p1, "bad") }
@@ -26,7 +26,6 @@ class TaxDistTest < Test::Unit::TestCase
26
26
  assert_lt(close_intax[:s], 0.05)
27
27
 
28
28
  distant_novel = MiGA::TaxDist.aai_pvalues(35.0, :novel, engine: :diamond)
29
- $stderr.puts distant_novel
30
29
  assert_gt(distant_novel[:root], 0.05)
31
30
  assert_lt(distant_novel[:g], 0.05)
32
31
  assert_nil(distant_novel[:ns])
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: miga-base
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3.0
4
+ version: 0.6.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luis M. Rodriguez-R
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-27 00:00:00.000000000 Z
11
+ date: 2020-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: daemons
@@ -157,6 +157,7 @@ files:
157
157
  - lib/miga/common/format.rb
158
158
  - lib/miga/common/hooks.rb
159
159
  - lib/miga/common/path.rb
160
+ - lib/miga/common/with_result.rb
160
161
  - lib/miga/daemon.rb
161
162
  - lib/miga/daemon/base.rb
162
163
  - lib/miga/dataset.rb