miga-base 0.7.20.1 → 0.7.23.0

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
  SHA256:
3
- metadata.gz: 76b06be04db6bb162666752f374da5a3adab38e010acf8a07f20fc2e8f97e75b
4
- data.tar.gz: 6c4f9b9118b21b11921b4c0a70ae99f3b1728d5737175ca5b9f23088ff985063
3
+ metadata.gz: 6ed8981c0dfc266aea53be66e06b77eaf277444a094ef460021c2713aef3bf73
4
+ data.tar.gz: d9f0bd3934dd5e3ba27cb58adfd1236a74ba6b003a06cd74b9da96e594a27e99
5
5
  SHA512:
6
- metadata.gz: d90839141adeb99d0551d0228c7b5806b11a971852bf2ca8040f419af79330be47fc7abe7f1bffec35fe935b3857a1631c860d8e6aa877ba74eb1524d24f8153
7
- data.tar.gz: baeee018956a1877065e2e9b5f689e1dc99af71cecc2705f951ab384b05b5760cffd7d85218068bb674541cb766a585add60c5b23a6209c15e2276b369d0f1b0
6
+ metadata.gz: f40242b96f36ce5528e2206aa4f366d047b5969a45d69cff5ac825297563f9adddaee957e562eddae34c96b8a0651fd2fec39a42d2cd278d66ea03ac35afabfc
7
+ data.tar.gz: ab01b09ab020c1bfcf5dd5be7a01c971e83e02066ad35f4b6a9f0c525351c81b5cdb0e80910cf4237b9e59a33c518995a073c1f625f049b6b722802541d11c1f
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  [![Code Climate](https://codeclimate.com/github/bio-miga/miga/badges/gpa.svg)](https://codeclimate.com/github/bio-miga/miga)
2
2
  [![Test Coverage](https://codeclimate.com/github/bio-miga/miga/badges/coverage.svg)](https://codeclimate.com/github/bio-miga/miga/coverage)
3
- [![Build Status](https://travis-ci.org/bio-miga/miga.svg?branch=master)](https://travis-ci.org/bio-miga/miga)
3
+ [![Build Status](https://github.com/bio-miga/miga/workflows/build/badge.svg)](https://github.com/bio-miga/miga/actions?query=workflow:build)
4
4
  [![Gem Version](https://badge.fury.io/rb/miga-base.svg)](https://badge.fury.io/rb/miga-base)
5
5
  [![Inch docs](http://inch-ci.org/github/bio-miga/miga.svg)](http://inch-ci.org/github/bio-miga/miga)
6
6
 
@@ -20,6 +20,6 @@ class MiGA::Cli::Action::AddResult < MiGA::Cli::Action
20
20
  obj = cli.load_project_or_dataset
21
21
  cli.say "Registering result: #{cli[:result]}"
22
22
  r = obj.add_result(cli[:result], true, force: cli[:force])
23
- raise "Cannot add result, incomplete expected files." if r.nil?
23
+ raise 'Cannot add result, incomplete expected files' if r.nil?
24
24
  end
25
25
  end
@@ -2,9 +2,7 @@
2
2
  # @license Artistic-2.0
3
3
 
4
4
  require 'miga/cli/action'
5
- require 'net/ftp'
6
5
  require 'digest/md5'
7
- require 'open-uri'
8
6
 
9
7
  class MiGA::Cli::Action::GetDb < MiGA::Cli::Action
10
8
  def parse_cli
@@ -12,7 +10,7 @@ class MiGA::Cli::Action::GetDb < MiGA::Cli::Action
12
10
  database: :recommended,
13
11
  version: :latest,
14
12
  local: File.expand_path('.miga_db', ENV['MIGA_HOME']),
15
- host: 'ftp://microbial-genomes.org/db',
13
+ host: MiGA::MiGA.known_hosts(:miga_db),
16
14
  pb: true,
17
15
  overwrite: true
18
16
  }
@@ -50,6 +48,14 @@ class MiGA::Cli::Action::GetDb < MiGA::Cli::Action
50
48
  end
51
49
 
52
50
  def perform
51
+ # Quick check when the database is not an alias
52
+ dir = File.join(cli[:local], cli[:database].to_s)
53
+ if !cli[:overwrite] && Dir.exist?(dir)
54
+ cli.puts "Database exists: #{dir}"
55
+ return
56
+ end
57
+
58
+ # Remote manifest
53
59
  @ftp = remote_connection
54
60
  manif = remote_manifest(@ftp)
55
61
  cli.puts "# Host: #{manif[:host]}"
@@ -59,6 +65,8 @@ class MiGA::Cli::Action::GetDb < MiGA::Cli::Action
59
65
  list_versions(db) and return
60
66
  ver = version_requested(db)
61
67
  check_target and return
68
+
69
+ # Download and expand
62
70
  file = download_file(@ftp, ver[:path])
63
71
  check_digest(ver, file)
64
72
  unarchive(file)
@@ -78,27 +86,14 @@ class MiGA::Cli::Action::GetDb < MiGA::Cli::Action
78
86
 
79
87
  def remote_connection
80
88
  cli.say "Connecting to '#{cli[:host]}'"
81
- uri = URI.parse(cli[:host])
82
- raise 'Only FTP hosts are supported' unless uri.scheme == 'ftp'
83
-
84
- ftp = Net::FTP.new(uri.host)
85
- ftp.passive = true
86
- ftp.login
87
- ftp.chdir(uri.path)
88
- ftp
89
+ MiGA::MiGA.remote_connection(cli[:host])
89
90
  end
90
91
 
91
92
  def download_file(ftp, path)
92
93
  cli.say "Downloading '#{path}'"
93
- Dir.mkdir(cli[:local]) unless Dir.exist? cli[:local]
94
94
  file = File.expand_path(path, cli[:local])
95
- filesize = ftp.size(path)
96
- transferred = 0
97
- ftp.getbinaryfile(path, file, 1024) do |data|
98
- if cli[:pb]
99
- transferred += data.size
100
- cli.advance("#{path}:", transferred, filesize)
101
- end
95
+ MiGA::MiGA.download_file_ftp(ftp, path, file) do |n, size|
96
+ cli.advance("#{path}:", n, size) if cli[:pb]
102
97
  end
103
98
  cli.print "\n" if cli[:pb]
104
99
  file
@@ -165,7 +160,7 @@ class MiGA::Cli::Action::GetDb < MiGA::Cli::Action
165
160
  def check_target
166
161
  return false if cli[:overwrite]
167
162
 
168
- file = File.expand_path(cli[:database].to_s, cli[:local])
163
+ file = File.join(cli[:local], cli[:database].to_s)
169
164
  if Dir.exist? file
170
165
  warn "The target directory already exists: #{file}"
171
166
  true
@@ -195,7 +190,7 @@ class MiGA::Cli::Action::GetDb < MiGA::Cli::Action
195
190
 
196
191
  def unarchive(file)
197
192
  cli.say "Unarchiving #{file}"
198
- `cd "#{cli[:local]}" && tar -zxf "#{file}"`
193
+ `cd "#{cli[:local]}" && tar -zxf "#{file}" && rm "#{file}"`
199
194
  end
200
195
 
201
196
  def register_database(manif, db, ver)
@@ -1,18 +1,24 @@
1
- # @package MiGA
2
- # @license Artistic-2.0
1
+ # frozen_string_literal: true
3
2
 
4
3
  require 'miga/cli/action'
5
4
  require 'shellwords'
6
5
 
7
6
  class MiGA::Cli::Action::Init < MiGA::Cli::Action
8
7
  require 'miga/cli/action/init/daemon_helper'
8
+ require 'miga/cli/action/init/files_helper'
9
9
  include MiGA::Cli::Action::Init::DaemonHelper
10
+ include MiGA::Cli::Action::Init::FilesHelper
10
11
 
11
12
  def parse_cli
12
13
  cli.interactive = true
13
- cli.defaults = { mytaxa: nil,
14
- config: File.expand_path('.miga_modules', ENV['HOME']),
15
- ask: false, auto: false, dtype: :bash }
14
+ cli.defaults = {
15
+ mytaxa: nil,
16
+ rdp: nil,
17
+ config: File.join(ENV['MIGA_HOME'], '.miga_modules'),
18
+ ask: false,
19
+ auto: false,
20
+ dtype: :bash
21
+ }
16
22
  cli.parse do |opt|
17
23
  opt.on(
18
24
  '-c', '--config PATH',
@@ -21,9 +27,14 @@ class MiGA::Cli::Action::Init < MiGA::Cli::Action
21
27
  ) { |v| cli[:config] = v }
22
28
  opt.on(
23
29
  '--[no-]mytaxa',
24
- 'Should I try setting up MyTaxa its dependencies?',
30
+ 'Should I try setting up MyTaxa and its dependencies?',
25
31
  'By default: interactive (true if --auto)'
26
32
  ) { |v| cli[:mytaxa] = v }
33
+ opt.on(
34
+ '--[no-]rdp',
35
+ 'Should I try setting up the RDP classifier?',
36
+ 'By default: interactive (true if --auto)'
37
+ ) { |v| cli[:rdp] = v }
27
38
  opt.on(
28
39
  '--daemon-type STRING',
29
40
  'Type of daemon launcher, one of: bash, ssh, qsub, msub, slurm',
@@ -47,13 +58,13 @@ class MiGA::Cli::Action::Init < MiGA::Cli::Action
47
58
  BANNER
48
59
  list_requirements
49
60
  rc_fh = open_rc_file
50
- check_configuration_script rc_fh
51
- paths = check_software_requirements rc_fh
52
- check_additional_files paths
53
- check_r_packages paths
54
- check_ruby_gems paths
61
+ check_configuration_script(rc_fh)
62
+ paths = check_software_requirements(rc_fh)
63
+ check_additional_files(paths)
64
+ check_r_packages(paths)
65
+ check_ruby_gems(paths)
55
66
  configure_daemon
56
- close_rc_file rc_fh
67
+ close_rc_file(rc_fh)
57
68
  cli.puts 'Configuration complete. MiGA is ready to work!'
58
69
  cli.puts ''
59
70
  end
@@ -116,58 +127,18 @@ class MiGA::Cli::Action::Init < MiGA::Cli::Action
116
127
 
117
128
  private
118
129
 
119
- def open_rc_file
120
- rc_path = File.expand_path('.miga_rc', ENV['HOME'])
121
- if File.exist? rc_path
122
- if cli.ask_user(
123
- 'I found a previous configuration. Do you want to continue?',
124
- 'yes', %w(yes no)
125
- ) == 'no'
126
- cli.puts 'OK, see you soon!'
127
- exit(0)
128
- end
129
- end
130
- rc_fh = File.open(rc_path, 'w')
131
- rc_fh.puts <<~BASH
132
- #!/bin/bash
133
- # `miga init` made this on #{Time.now}
134
-
135
- BASH
136
- rc_fh
137
- end
138
-
139
- def check_configuration_script(rc_fh)
140
- unless File.exist? cli[:config]
141
- cli[:config] = cli.ask_user(
142
- 'Is there a script I need to load at startup?',
143
- cli[:config]
144
- )
145
- end
146
- if File.exist? cli[:config]
147
- cli[:config] = File.expand_path(cli[:config])
148
- cli.puts "Found bash configuration script: #{cli[:config]}"
149
- rc_fh.puts "MIGA_STARTUP='#{cli[:config]}'"
150
- rc_fh.puts '. "$MIGA_STARTUP"'
151
- else
152
- cli[:config] = '/dev/null'
153
- end
154
- cli.puts ''
155
- end
156
-
157
130
  def check_software_requirements(rc_fh)
158
131
  cli.puts 'Looking for requirements:'
159
- ask_for_mytaxa
160
- rc_fh.puts 'export MIGA_MYTAXA="no"' unless cli[:mytaxa]
132
+ ask_for_optional(:mytaxa, 'MyTaxa')
133
+ rc_fh.puts "export MIGA_MYTAXA='#{cli[:mytaxa] ? 'yes' : 'no'}'"
134
+ ask_for_optional(:rdp, 'RDP classifier')
135
+ rc_fh.puts "export MIGA_RDP='#{cli[:rdp] ? 'yes' : 'no'}'"
161
136
  paths = {}
162
137
  rc_fh.puts 'MIGA_PATH=""'
163
138
  req_path = File.expand_path('utils/requirements.txt', MiGA.root_path)
164
139
  File.open(req_path, 'r') do |fh|
165
140
  fh.each_line do |ln|
166
- next if $. < 3
167
-
168
- r = ln.chomp.split(/\t+/)
169
- next if r[0] =~ /\(opt\)$/ && !cli[:mytaxa]
170
-
141
+ r = define_software(ln) or next
171
142
  cli.print "Testing #{r[0]}#{" (#{r[3]})" if r[3]}... "
172
143
  path = find_software(r[1])
173
144
  paths[r[1]] = File.expand_path(r[1], path).shellescape
@@ -178,11 +149,20 @@ class MiGA::Cli::Action::Init < MiGA::Cli::Action
178
149
  paths
179
150
  end
180
151
 
181
- def ask_for_mytaxa
182
- if cli[:mytaxa].nil?
183
- cli[:mytaxa] =
152
+ def define_software(ln)
153
+ r = ln.chomp.split(/\t+/)
154
+ return if %w[Software --------].include?(r[0])
155
+ return if r[0] =~ /\(mytaxa\)$/ && !cli[:mytaxa]
156
+ return if r[0] =~ /\(rdp\)$/ && !cli[:rdp]
157
+
158
+ r
159
+ end
160
+
161
+ def ask_for_optional(symbol, name)
162
+ if cli[symbol].nil?
163
+ cli[symbol] =
184
164
  cli.ask_user(
185
- 'Should I include MyTaxa modules?',
165
+ "Should I include #{name} modules?",
186
166
  'yes', %w(yes no)
187
167
  ) == 'yes'
188
168
  end
@@ -209,27 +189,6 @@ class MiGA::Cli::Action::Init < MiGA::Cli::Action
209
189
  path
210
190
  end
211
191
 
212
- def check_additional_files(paths)
213
- if cli[:mytaxa]
214
- cli.puts 'Looking for MyTaxa databases:'
215
- mt = File.dirname paths['MyTaxa']
216
- cli.print 'Looking for scores... '
217
- unless Dir.exist?(File.expand_path('db', mt))
218
- cli.puts "no\nExecute 'python2 #{mt}/utils/download_db.py'"
219
- exit(1)
220
- end
221
- cli.puts 'yes'
222
- cli.print 'Looking for diamond db... '
223
- unless File.exist?(File.expand_path('AllGenomes.faa.dmnd', mt))
224
- cli.puts "no\nDownload " \
225
- "'http://enve-omics.ce.gatech.edu/data/public_mytaxa/" \
226
- "AllGenomes.faa.dmnd' into #{mt}"
227
- exit(1)
228
- end
229
- cli.puts ''
230
- end
231
- end
232
-
233
192
  def check_r_packages(paths)
234
193
  cli.puts 'Looking for R packages:'
235
194
  %w(ape cluster vegan).each do |pkg|
@@ -266,15 +225,4 @@ class MiGA::Cli::Action::Init < MiGA::Cli::Action
266
225
  end
267
226
  cli.puts ''
268
227
  end
269
-
270
- def close_rc_file(rc_fh)
271
- rc_fh.puts <<~FOOT
272
-
273
- MIGA_CONFIG_VERSION='#{MiGA::MiGA.VERSION}'
274
- MIGA_CONFIG_LONGVERSION='#{MiGA::MiGA.LONG_VERSION}'
275
- MIGA_CONFIG_DATE='#{Time.now}'
276
-
277
- FOOT
278
- rc_fh.close
279
- end
280
228
  end
@@ -1,5 +1,4 @@
1
- # @package MiGA
2
- # @license Artistic-2.0
1
+ # frozen_string_literal: true
3
2
 
4
3
  ##
5
4
  # Helper module with daemon configuration functions for MiGA::Cli::Action::Init
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # Helper module with files configuration functions for MiGA::Cli::Action::Init
5
+ module MiGA::Cli::Action::Init::FilesHelper
6
+ def open_rc_file
7
+ rc_path = File.expand_path('.miga_rc', ENV['HOME'])
8
+ if File.exist? rc_path
9
+ if cli.ask_user(
10
+ 'I found a previous configuration. Do you want to continue?',
11
+ 'yes', %w(yes no)
12
+ ) == 'no'
13
+ cli.puts 'OK, see you soon!'
14
+ exit(0)
15
+ end
16
+ end
17
+ rc_fh = File.open(rc_path, 'w')
18
+ rc_fh.puts <<~BASH
19
+ #!/bin/bash
20
+ # `miga init` made this on #{Time.now}
21
+
22
+ BASH
23
+ rc_fh
24
+ end
25
+
26
+ def close_rc_file(rc_fh)
27
+ rc_fh.puts <<~FOOT
28
+
29
+ MIGA_CONFIG_VERSION='#{MiGA::MiGA.VERSION}'
30
+ MIGA_CONFIG_LONGVERSION='#{MiGA::MiGA.LONG_VERSION}'
31
+ MIGA_CONFIG_DATE='#{Time.now}'
32
+
33
+ FOOT
34
+ rc_fh.close
35
+ end
36
+
37
+ def check_configuration_script(rc_fh)
38
+ unless File.exist? cli[:config]
39
+ cli[:config] = cli.ask_user(
40
+ 'Is there a script I need to load at startup?',
41
+ cli[:config]
42
+ )
43
+ end
44
+ if File.exist? cli[:config]
45
+ cli[:config] = File.expand_path(cli[:config])
46
+ cli.puts "Found bash configuration script: #{cli[:config]}"
47
+ rc_fh.puts "MIGA_STARTUP='#{cli[:config]}'"
48
+ rc_fh.puts '. "$MIGA_STARTUP"'
49
+ else
50
+ cli[:config] = '/dev/null'
51
+ end
52
+ cli.puts ''
53
+ end
54
+
55
+ def check_additional_files(paths)
56
+ if cli[:mytaxa]
57
+ check_mytaxa_scores(paths)
58
+ check_mytaxa_database(paths)
59
+ end
60
+ check_rdp_classifier if cli[:rdp]
61
+ check_phyla_lite
62
+ end
63
+
64
+ def check_mytaxa_scores(paths)
65
+ cli.print 'Looking for MyTaxa scores... '
66
+ mt = File.dirname(paths['MyTaxa'])
67
+ unless Dir.exist?(File.join(mt, 'db'))
68
+ cli.puts "no\nExecute 'python2 #{mt}/utils/download_db.py'"
69
+ raise 'Incomplete MyTaxa installation'
70
+ end
71
+ cli.puts 'yes'
72
+ end
73
+
74
+ def check_mytaxa_database(paths)
75
+ cli.print 'Looking for MyTaxa DB... '
76
+ mt = File.dirname(paths['MyTaxa'])
77
+ dmnd_db = 'AllGenomes.faa.dmnd'
78
+ miga_db = File.join(ENV['MIGA_HOME'], '.miga_db')
79
+ home_db = File.join(miga_db, dmnd_db)
80
+ mt_db = File.join(mt, 'AllGenomes.faa.dmnd')
81
+ if File.exist?(home_db)
82
+ cli.puts 'yes'
83
+ elsif File.exist?(mt_db)
84
+ cli.puts 'yes, sym-linking'
85
+ File.symlink(mt_db, home_db)
86
+ else
87
+ cli.puts 'no, downloading'
88
+ MiGA::MiGA.download_file_ftp(:miga_dist, dmnd_db, home_db) do |n, size|
89
+ cli.advance("#{dmnd_db}:", n, size)
90
+ end
91
+ cli.puts
92
+ end
93
+ end
94
+
95
+ def check_rdp_classifier
96
+ cli.print 'Looking for RDP classifier... '
97
+ miga_db = File.join(ENV['MIGA_HOME'], '.miga_db')
98
+ file = 'classifier.jar'
99
+ path = File.join(miga_db, file)
100
+ if File.size?(path)
101
+ cli.puts 'yes'
102
+ else
103
+ cli.puts 'no, downloading'
104
+ arch = 'classifier.tar.gz'
105
+ MiGA::MiGA.download_file_ftp(
106
+ :miga_dist, arch, File.join(miga_db, arch)
107
+ ) { |n, size| cli.advance("#{arch}:", n, size) }
108
+ `cd '#{miga_db}' && tar zxf '#{arch}' && rm '#{arch}'`
109
+ cli.puts
110
+ end
111
+ end
112
+
113
+ def check_phyla_lite
114
+ cli.puts 'Looking for Phyla Lite... '
115
+ cmd = ['get_db', '-n', 'Phyla_Lite', '--no-overwrite']
116
+ MiGA::Cli.new(cmd).launch(true)
117
+ end
118
+ end
@@ -11,16 +11,8 @@ class MiGA::Cli::Action::NextStep < MiGA::Cli::Action
11
11
  end
12
12
 
13
13
  def perform
14
- p = cli.load_project
15
- n = nil
16
- if cli[:dataset].nil?
17
- n = p.next_distances(false)
18
- n ||= p.next_inclade(false)
19
- else
20
- d = cli.load_dataset
21
- n = d.next_preprocessing if d.is_active?
22
- end
23
- n ||= '?'
24
- cli.puts n
14
+ obj = cli.load_project_or_dataset
15
+ n = obj.next_task
16
+ cli.puts(n || '?')
25
17
  end
26
18
  end
data/lib/miga/common.rb CHANGED
@@ -6,6 +6,7 @@ require 'miga/json'
6
6
  require 'miga/common/base'
7
7
  require 'miga/common/path'
8
8
  require 'miga/common/format'
9
+ require 'miga/common/net'
9
10
  require 'stringio'
10
11
 
11
12
  ##
@@ -16,6 +17,7 @@ class MiGA::MiGA
16
17
 
17
18
  extend MiGA::Common::Path
18
19
  extend MiGA::Common::Format
20
+ extend MiGA::Common::Net
19
21
 
20
22
  ENV['MIGA_HOME'] ||= ENV['HOME']
21
23
 
@@ -64,7 +66,7 @@ class MiGA::MiGA
64
66
  adv_n = n - @_advance_time[:n]
65
67
  unless total.nil? || @_advance_time[:last].nil? || adv_n <= 0
66
68
  if adv_n.to_f/n > 0.001
67
- this_time = Time.now - @_advance_time[:last]
69
+ this_time = (Time.now - @_advance_time[:last]).to_f
68
70
  this_avg = this_time / adv_n
69
71
  @_advance_time[:avg] ||= this_avg
70
72
  @_advance_time[:avg] = 0.9 * @_advance_time[:avg] + 0.1 * this_avg
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/ftp'
4
+ require 'open-uri'
5
+ require 'fileutils'
6
+
7
+ Net::FTP.send(:remove_const, 'FTP_PORT') # just to avoid warnings
8
+ Net::FTP.const_set('FTP_PORT', 21)
9
+
10
+ ##
11
+ # General web-access functions shared throughout MiGA.
12
+ module MiGA::Common::Net
13
+ ##
14
+ # Returns the URL of the host +name+ (Symbol)
15
+ def known_hosts(name)
16
+ case name.to_sym
17
+ when :miga_online_ftp
18
+ 'ftp://microbial-genomes.org//' # <- // to simplify chdir in connection
19
+ when :miga_db
20
+ 'ftp://microbial-genomes.org/db'
21
+ when :miga_dist
22
+ 'ftp://microbial-genomes.org/dist'
23
+ else
24
+ raise "Unrecognized server name: #{host}"
25
+ end
26
+ end
27
+
28
+ ##
29
+ # Connect to an FTP +host+ (String) or a known host name (Symbol, see
30
+ # +.known_hosts+)
31
+ def remote_connection(host)
32
+ host = known_hosts(host) if host.is_a?(Symbol)
33
+ uri = URI.parse(host)
34
+ raise 'Only FTP hosts are currently supported' unless uri.scheme == 'ftp'
35
+
36
+ ftp = Net::FTP.new(uri.host)
37
+ ftp.passive = true
38
+ ftp.login
39
+ ftp.chdir(uri.path)
40
+ ftp
41
+ end
42
+
43
+ ##
44
+ # Download a file via FTP using the +connection+ (returned by
45
+ # +.remote_connection+) with remote name +file+ into local +target+.
46
+ #
47
+ # Alternatively, +connection+ can simply be the host (String) or a recognized
48
+ # Symbol (see +.remote_connection+), in which case the function opens the
49
+ # connection automatically
50
+ #
51
+ # Reports progress to the function block with two arguments: the
52
+ # currently transferred size and the total file size
53
+ def download_file_ftp(connection, file, target)
54
+ # Open connection unless passed
55
+ close_conn = false
56
+ if connection.is_a?(String) || connection.is_a?(Symbol)
57
+ connection = remote_connection(connection)
58
+ close_conn = true
59
+ end
60
+
61
+ # Prepare download
62
+ FileUtils.mkdir_p(File.dirname(target))
63
+ filesize = connection.size(file)
64
+ transferred = 0
65
+
66
+ # Get in chunks of 1KiB
67
+ connection.getbinaryfile(file, target, 1024) do |data|
68
+ yield(transferred += data.size, filesize) if block_given?
69
+ end
70
+
71
+ # Close connection if automatically opened
72
+ connection.close if close_conn
73
+ end
74
+ end
@@ -1,6 +1,8 @@
1
1
  ##
2
2
  # Helper module including specific functions to handle objects that
3
- # have results.
3
+ # have results. The class including this module must implement methods
4
+ # +.RESULT_DIRS+, +#ignore_task?+, +#metadata+, +#project+,
5
+ # and +#inactivate!+.
4
6
  module MiGA::Common::WithResult
5
7
  ##
6
8
  # Result directories as a Hash
@@ -68,4 +70,40 @@ module MiGA::Common::WithResult
68
70
  def get_result(task)
69
71
  add_result(task, false)
70
72
  end
73
+
74
+ ##
75
+ # Get the next task from +tasks+, saving intermediate results if +save+.
76
+ # If +tasks+ is +nil+ (default), it uses the entire list of tasks.
77
+ # Returns a Symbol.
78
+ def next_task(tasks = nil, save = false)
79
+ tasks ||= result_dirs.keys
80
+ tasks.find do |t|
81
+ if ignore_task?(t)
82
+ # Do not run if this step is to be ignored
83
+ false
84
+ else
85
+ res = add_result(t, save)
86
+ if res.nil?
87
+ # Run if the step has not been calculated,
88
+ # unless too many attempts were already made
89
+ if (metadata["_try_#{t}"] || 0) > (project.metadata[:max_try] || 10)
90
+ inactivate! "Too many errors in step #{t}"
91
+ false
92
+ else
93
+ true
94
+ end
95
+ else
96
+ # Run if the step is ready but has to be recalculated
97
+ res.recalculate? ? true : false
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ ##
104
+ # Mark all results for recalculation
105
+ def recalculate_tasks(reason = nil)
106
+ each_result { |_k, res| res.recalculate!(reason).save }
107
+ end
108
+
71
109
  end
data/lib/miga/dataset.rb CHANGED
@@ -107,6 +107,7 @@ class MiGA::Dataset < MiGA::MiGA
107
107
  metadata[:warn] = "Inactive: #{reason}" unless reason.nil?
108
108
  metadata[:inactive] = true
109
109
  metadata.save
110
+ project.recalculate_tasks('Reference dataset inactivated') if ref?
110
111
  pull_hook :on_inactivate
111
112
  end
112
113
 
@@ -116,6 +117,7 @@ class MiGA::Dataset < MiGA::MiGA
116
117
  metadata[:inactive] = nil
117
118
  metadata[:warn] = nil if metadata[:warn] && metadata[:warn] =~ /^Inactive: /
118
119
  metadata.save
120
+ project.recalculate_tasks('Reference dataset activated') if ref?
119
121
  pull_hook :on_activate
120
122
  end
121
123
 
@@ -77,19 +77,8 @@ module MiGA::Dataset::Result
77
77
  # Returns the key symbol of the next task that needs to be executed or nil.
78
78
  # Passes +save+ to #add_result.
79
79
  def next_preprocessing(save = false)
80
- first = first_preprocessing(save) or return nil
81
- @@PREPROCESSING_TASKS[@@PREPROCESSING_TASKS.index(first)..-1].find do |t|
82
- if ignore_task? t
83
- false
84
- elsif add_result(t, save).nil?
85
- if (metadata["_try_#{t}"] || 0) > (project.metadata[:max_try] || 10)
86
- inactivate! "Too many errors in step #{t}"
87
- false
88
- else
89
- true
90
- end
91
- end
92
- end
80
+ first_preprocessing(save) if save
81
+ next_task(nil, save)
93
82
  end
94
83
 
95
84
  ##
@@ -301,7 +290,8 @@ module MiGA::Dataset::Result
301
290
  MiGA::Result.new("#{base}.json"), name,
302
291
  longest_ssu_gene: '.ssu.fa',
303
292
  gff: '.ssu.gff',
304
- all_ssu_genes: '.ssu.all.fa'
293
+ all_ssu_genes: '.ssu.all.fa',
294
+ classification: '.rdp.tsv'
305
295
  )
306
296
  opts[:is_clean] ||= false
307
297
  r.clean! if opts[:is_clean]
data/lib/miga/project.rb CHANGED
@@ -97,13 +97,28 @@ class MiGA::Project < MiGA::MiGA
97
97
 
98
98
  ##
99
99
  # Is this a clade project?
100
- def is_clade?
100
+ def clade?
101
101
  type == :clade
102
102
  end
103
103
 
104
+ ##
105
+ # Same as active? For backward compatibility
106
+ alias is_clade? clade?
107
+
104
108
  ##
105
109
  # Is this a project for multi-organism datasets?
106
- def is_multi?
110
+ def multi?
107
111
  @@KNOWN_TYPES[type][:multi]
108
112
  end
113
+
114
+ ##
115
+ # Same as multi? For backward compatibility
116
+ alias is_multi? multi?
117
+
118
+ ##
119
+ # Is this project active? Currently a dummy function, returns
120
+ # always true.
121
+ def active?
122
+ true
123
+ end
109
124
  end
@@ -50,14 +50,11 @@ module MiGA::Project::Base
50
50
  07.annotation/01.function/01.essential
51
51
  07.annotation/01.function/02.ssu
52
52
  07.annotation/02.taxonomy/01.mytaxa
53
- 07.annotation/03.qa 07.annotation/03.qa/01.checkm
54
- 07.annotation/03.qa/02.mytaxa_scan
53
+ 07.annotation/03.qa 07.annotation/03.qa/02.mytaxa_scan
55
54
  08.mapping 08.mapping/01.read-ctg 08.mapping/02.read-gene
56
55
  09.distances 09.distances/01.haai 09.distances/02.aai
57
56
  09.distances/03.ani 09.distances/04.ssu 09.distances/05.taxonomy
58
57
  10.clades 10.clades/01.find 10.clades/02.ani 10.clades/03.ogs
59
- 10.clades/04.phylogeny 10.clades/04.phylogeny/01.essential
60
- 10.clades/04.phylogeny/02.core 10.clades/05.metadata
61
58
  90.stats
62
59
  ]
63
60
 
@@ -48,11 +48,11 @@ module MiGA::Project::Dataset
48
48
  # Add dataset identified by +name+ and return MiGA::Dataset.
49
49
  def add_dataset(name)
50
50
  unless metadata[:datasets].include? name
51
- ds = MiGA::Dataset.new(self, name)
51
+ d = MiGA::Dataset.new(self, name)
52
52
  @metadata[:datasets] << name
53
53
  @dataset_names_hash = nil # Ensure loading even if +do_not_save+ is true
54
54
  save
55
- # TODO redo_project_steps if ds.ref?
55
+ recalculate_tasks('New reference dataset added') if d.ref? && d.active?
56
56
  pull_hook(:on_add_dataset, name)
57
57
  end
58
58
  dataset(name)
@@ -66,6 +66,7 @@ module MiGA::Project::Dataset
66
66
 
67
67
  self.metadata[:datasets].delete(name)
68
68
  save
69
+ recalculate_tasks('Reference dataset unlinked') if d.ref? && d.active?
69
70
  pull_hook(:on_unlink_dataset, name)
70
71
  d
71
72
  end
@@ -23,6 +23,11 @@ module MiGA::Project::Result
23
23
  self
24
24
  end
25
25
 
26
+ ##
27
+ # Do nothing, only to comply with MiGA::Common::WithResult
28
+ def inactivate!(reason = nil)
29
+ end
30
+
26
31
  ##
27
32
  # Is this +task+ to be bypassed?
28
33
  def ignore_task?(task)
@@ -45,17 +50,6 @@ module MiGA::Project::Result
45
50
  next_task(@@INCLADE_TASKS, save)
46
51
  end
47
52
 
48
- ##
49
- # Get the next task from +tasks+, saving intermediate results if +save+.
50
- # If +tasks+ is +nil+ (default), it uses the entire list of tasks.
51
- # Returns a Symbol.
52
- def next_task(tasks = nil, save = true)
53
- tasks ||= @@DISTANCE_TASKS + @@INCLADE_TASKS
54
- tasks.find do |t|
55
- ignore_task?(t) ? false : add_result(t, save).nil?
56
- end
57
- end
58
-
59
53
  private
60
54
 
61
55
  ##
@@ -162,6 +162,8 @@ class MiGA::RemoteDataset < MiGA::MiGA
162
162
  txt.empty? ? sleep(1) : break
163
163
  end
164
164
  doc = MiGA::Json.parse(txt, symbolize: false, contents: true)
165
+ return if doc.nil? || doc['result'].nil? || doc['result'].empty?
166
+
165
167
  @_ncbi_asm_json_doc = doc['result'][ doc['result']['uids'].first ]
166
168
  end
167
169
 
data/lib/miga/result.rb CHANGED
@@ -59,9 +59,25 @@ class MiGA::Result < MiGA::MiGA
59
59
  end
60
60
 
61
61
  ##
62
- # Register the result as cleaned
62
+ # Register the result as cleaned, returns self
63
63
  def clean!
64
64
  self[:clean] = true
65
+ self
66
+ end
67
+
68
+ ##
69
+ # Is the result marked to be recalculated? Returns Boolean
70
+ def recalculate?
71
+ !!self[:recalculate]
72
+ end
73
+
74
+ ##
75
+ # Mark the result to be recalculated, returns self
76
+ def recalculate!(reason = nil)
77
+ self[:recalculate] = true
78
+ self[:recalculate_why] = reason
79
+ self[:recalculate_when] = Time.now.to_s
80
+ self
65
81
  end
66
82
 
67
83
  ##
data/lib/miga/version.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'date'
2
4
 
3
5
  ##
@@ -8,7 +10,7 @@ module MiGA
8
10
  # - Float representing the major.minor version.
9
11
  # - Integer representing gem releases of the current version.
10
12
  # - Integer representing minor changes that require new version number.
11
- VERSION = [0.7, 20, 1]
13
+ VERSION = [0.7, 23, 0].freeze
12
14
 
13
15
  ##
14
16
  # Nickname for the current major.minor version.
@@ -16,7 +18,7 @@ module MiGA
16
18
 
17
19
  ##
18
20
  # Date of the current gem release.
19
- VERSION_DATE = Date.new(2021, 1, 10)
21
+ VERSION_DATE = Date.new(2021, 2, 9)
20
22
 
21
23
  ##
22
24
  # Reference of MiGA.
@@ -19,7 +19,7 @@ rm -f miga-project.txt
19
19
  for i in $DS ; do
20
20
  echo "SELECT CASE WHEN omega!=0 THEN 'AAI' ELSE 'hAAI_AAI' END," \
21
21
  " seq1, seq2, aai, sd, n, omega from aai;" \
22
- | sqlite3 "$i.db" | tr "\\|" "\\t"
22
+ | sqlite3 "$DIR/$i.db" | tr "\\|" "\\t"
23
23
  echo "$i" >> miga-project.log
24
24
  done
25
25
  ) | gzip -9c > miga-project.txt.gz
@@ -18,7 +18,7 @@ rm -f miga-project.txt
18
18
  echo "metric a b value sd n omega" | tr " " "\\t"
19
19
  for i in $DS ; do
20
20
  echo "SELECT 'ANI', seq1, seq2, ani, sd, n, omega from ani ;" \
21
- | sqlite3 "$i.db" | tr "\\|" "\\t"
21
+ | sqlite3 "$DIR/$i.db" | tr "\\|" "\\t"
22
22
  echo "$i" >> miga-project.log
23
23
  done
24
24
  ) | gzip -9c > miga-project.txt.gz
@@ -22,7 +22,7 @@ rm -f miga-project.txt
22
22
  echo "metric a b value sd n omega" | tr " " "\\t"
23
23
  for i in $DS ; do
24
24
  echo "SELECT 'hAAI', seq1, seq2, aai, sd, n, omega from aai ;" \
25
- | sqlite3 "$i.db" | tr "\\|" "\\t"
25
+ | sqlite3 "$DIR/$i.db" | tr "\\|" "\\t"
26
26
  echo "$i" >> miga-project.log
27
27
  done
28
28
  ) | gzip -9c > miga-project.txt.gz
data/scripts/mytaxa.bash CHANGED
@@ -14,15 +14,16 @@ if [[ "$MIGA_MYTAXA" == "no" ]] ; then
14
14
  echo "This system doesn't currently support MyTaxa." \
15
15
  > "$DATASET.nomytaxa.txt"
16
16
  else
17
- MT=$(dirname -- "$(which MyTaxa)")
18
-
19
17
  # Check type of dataset
20
18
  MULTI=$(miga list_datasets -P "$PROJECT" -D "$DATASET" --multi \
21
19
  | wc -l | awk '{print $1}')
22
20
  if [[ "$MULTI" -eq "1" ]] ; then
23
21
  # Check requirements
24
- if [[ ! -e "$MT/AllGenomes.faa.dmnd" ]] ; then
25
- echo "Cannot locate the database: $MT/AllGenomes.faa.dmnd:" \
22
+ MT=$(dirname -- "$(which MyTaxa)")
23
+ DB="$MIGA_HOME/.miga_db/AllGenomes.faa.dmnd"
24
+ [[ -e "$DB" ]] || DB="$MT/AllGenomes.faa.dmnd"
25
+ if [[ ! -e "$DB" ]] ; then
26
+ echo "Cannot locate the database: AllGenomes.faa.dmnd:" \
26
27
  "no such file or directory" >&2
27
28
  exit 1
28
29
  fi
@@ -40,7 +41,7 @@ else
40
41
  # Execute search
41
42
  FAA="../../../06.cds/$DATASET.faa"
42
43
  [[ -s "$FAA" ]] || FAA="${FAA}.gz"
43
- diamond blastp -q "$FAA" -d "$MT/AllGenomes.faa" \
44
+ diamond blastp -q "$FAA" -d "$DB" \
44
45
  -a "$DATASET.daa" -k 5 -p "$CORES" --min-score 60
45
46
  diamond view -a "$DATASET.daa" -o "$DATASET.blast"
46
47
 
@@ -5,7 +5,6 @@ SCRIPT="mytaxa_scan"
5
5
  # shellcheck source=scripts/miga.bash
6
6
  . "$MIGA/scripts/miga.bash" || exit 1
7
7
  DIR="$PROJECT/data/07.annotation/03.qa/02.mytaxa_scan"
8
- [[ -d "$DIR" ]] || mkdir -p "$DIR"
9
8
  cd "$DIR"
10
9
 
11
10
  # Initialize
@@ -14,17 +13,16 @@ if [[ "$MIGA_MYTAXA" == "no" ]] ; then
14
13
  echo "This system doesn't currently support MyTaxa." \
15
14
  > "$DATASET.nomytaxa.txt"
16
15
  else
17
- MT=$(dirname -- "$(which MyTaxa)")
18
- TMPDIR=$(mktemp -d /tmp/MiGA.XXXXXXXXXXXX)
19
- trap "rm -rf '$TMPDIR'; exit" SIGHUP SIGINT SIGTERM
20
-
21
16
  # Check type of dataset
22
17
  NOMULTI=$(miga list_datasets -P "$PROJECT" -D "$DATASET" --no-multi \
23
18
  | wc -l | awk '{print $1}')
24
19
  if [[ "$NOMULTI" -eq "1" ]] ; then
25
20
  # Check requirements
21
+ MT=$(dirname -- "$(which MyTaxa)")
22
+ DB="$MIGA_HOME/.miga_db/AllGenomes.faa.dmnd"
23
+ [[ -e "$DB" ]] || DB="$MT/AllGenomes.faa.dmnd"
26
24
  if [[ ! -e "$MT/AllGenomes.faa.dmnd" ]] ; then
27
- echo "Cannot locate the database: $MT/AllGenomes.faa.dmnd:" \
25
+ echo "Cannot locate the database: AllGenomes.faa.dmnd:" \
28
26
  "no such file or directory" >&2
29
27
  exit 1
30
28
  fi
@@ -39,13 +37,16 @@ else
39
37
  exit 1
40
38
  fi
41
39
 
40
+ TMPDIR=$(mktemp -d /tmp/MiGA.XXXXXXXXXXXX)
41
+ trap "rm -rf '$TMPDIR'; exit" SIGHUP SIGINT SIGTERM
42
+
42
43
  FAA="../../../06.cds/$DATASET.faa"
43
44
  [[ -s "$FAA" ]] || FAA="${FAA}.gz"
44
45
  if [[ ! -s "$DATASET.mytaxa" ]] ; then
45
46
  # Execute search
46
47
  if [[ ! -s "$DATASET.blast" ]] ; then
47
48
  diamond blastp -q "$FAA" -a "$DATASET.daa" -t "$TMPDIR" \
48
- -d "$MT/AllGenomes.faa" -k 5 -p "$CORES" --min-score 60
49
+ -d "$DB" -k 5 -p "$CORES" --min-score 60
49
50
  diamond view -a "$DATASET.daa" -o "$DATASET.blast" -t "$TMPDIR"
50
51
  fi
51
52
 
data/scripts/ssu.bash CHANGED
@@ -16,6 +16,7 @@ if [[ -s $fa ]] ; then
16
16
  # Run barrnap
17
17
  barrnap --quiet --threads "$CORES" "$fa" | grep "^##gff\\|;product=16S " \
18
18
  > "$DATASET.ssu.gff"
19
+
19
20
  # Extract
20
21
  bedtools getfasta -s "-fi" "$fa" -bed "$DATASET.ssu.gff" \
21
22
  -fo "$DATASET.ssu.all.fa"
@@ -24,9 +25,22 @@ if [[ -s $fa ]] ; then
24
25
  FastA.filter.pl "$DATASET.ssu.fa.id" "$DATASET.ssu.all.fa" > "$DATASET.ssu.fa"
25
26
  rm "$DATASET.ssu.fa.id"
26
27
  [[ -e "$fa.fai" ]] && rm "$fa.fai"
28
+
29
+ # RDP classifier
30
+ if [[ "$MIGA_RDP" == "yes" && -s "$DATASET.ssu.all.fa" ]] ; then
31
+ java -jar "$MIGA_HOME/.miga_db/classifier.jar" classify \
32
+ -c 0.8 -f fixrank -g 16srrna -o "$DATASET.rdp.tsv" \
33
+ "$DATASET.ssu.all.fa"
34
+ echo "# Version: $(perl -pe 's/.*://' \
35
+ < "$MIGA_HOME/.miga_db/classifier.version.txt" \
36
+ | grep . | paste - - | perl -pe 's/\t/; /')" \
37
+ >> "$DATASET.rdp.tsv"
38
+ fi
39
+
27
40
  # Gzip
28
- gzip -9 -f "$DATASET.ssu.gff"
29
- gzip -9 -f "$DATASET.ssu.all.fa"
41
+ for x in ssu.gff ssu.all.fa rdp.tsv ; do
42
+ [[ -e "${DATASET}.${x}" ]] && gzip -9 -f "${DATASET}.${x}"
43
+ done
30
44
  fi
31
45
 
32
46
  # Finalize
data/test/hook_test.rb CHANGED
@@ -107,10 +107,10 @@ class HookTest < Test::Unit::TestCase
107
107
  File.join(project.path, 'data', '90.stats', "miga-project.#{ext}")
108
108
  )
109
109
  end
110
- assert_equal(:project_stats, project.next_task(nil, false))
110
+ assert_equal(:project_stats, project.next_task)
111
111
  assert_equal(:test, $res)
112
112
  assert_equal(1, $counter)
113
- assert_equal(:haai_distances, project.next_task)
113
+ assert_equal(:haai_distances, project.next_task(nil, true))
114
114
  assert_equal(:project_stats, $res)
115
115
  assert_equal(2, $counter)
116
116
  end
data/test/net_test.rb ADDED
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+
3
+ class FormatTest < Test::Unit::TestCase
4
+ include TestHelper
5
+
6
+ def test_known_hosts
7
+ m = MiGA::MiGA
8
+ assert_not_nil(m.known_hosts(:miga_db))
9
+ assert_not_nil(m.known_hosts('miga_db'))
10
+ assert_not_nil(m.known_hosts(:miga_dist))
11
+ assert_raise { m.known_kosts(:not_a_host) }
12
+ end
13
+
14
+ def test_remote_connection
15
+ declare_remote_access
16
+ m = MiGA::MiGA
17
+ assert_raise { m.remote_connection(:bad_descriptor) }
18
+ assert_raise { m.remote_connection('http://microbial-genomes.org/') }
19
+ c = m.remote_connection(:miga_db)
20
+ assert_equal(Net::FTP, c.class)
21
+ c.close
22
+ end
23
+
24
+ def test_download_file_ftp
25
+ declare_remote_access
26
+ m = MiGA::MiGA
27
+ f = tmpfile('t/test.txt')
28
+ d = File.dirname(f)
29
+ assert(!Dir.exist?(d))
30
+ m.download_file_ftp(:miga_online_ftp, 'test.txt', f)
31
+ assert(Dir.exist?(d))
32
+ assert_equal('miga', File.read(f).chomp)
33
+ end
34
+ end
@@ -15,7 +15,7 @@ m.say 'Cleaning Databases'
15
15
  (0..thr - 1).each do |t|
16
16
  fork do
17
17
  dsn.each_with_index do |i, idx|
18
- m.advance('Dataset:', dsn.size, idx + 1) if t == 0
18
+ m.advance('Dataset:', idx + 1, dsn.size) if t == 0
19
19
  next unless (idx % thr) == t
20
20
 
21
21
  d = p.dataset(i)
@@ -1,10 +1,12 @@
1
1
  Software Test exec Website Notes
2
2
  -------- --------- ------- -----
3
3
  Ruby ruby https://www.ruby-lang.org/ Required version: 2.3+
4
- Python python https://www.python.org/
4
+ Python python https://www.python.org/ Required version: 3+
5
5
  R R http://www.r-project.org/
6
6
  SQLite3 sqlite3 https://www.sqlite.org/
7
7
  NCBI BLAST+ blastp ftp://ftp.ncbi.nlm.nih.gov/blast/executables/blast+/LATEST
8
+ DIAMOND diamond http://ab.inf.uni-tuebingen.de/software/diamond Required version: v0.9.20+
9
+ FastANI fastANI https://github.com/ParBLiSS/FastANI Required version: 1.1+
8
10
  HMMer 3.0+ hmmsearch http://hmmer.janelia.org/software
9
11
  Bedtools bedtools http://bedtools.readthedocs.org/en/latest/
10
12
  Prodigal prodigal http://prodigal.ornl.gov
@@ -14,7 +16,6 @@ Barrnap barrnap http://www.vicbioinformatics.com/software.barrnap.shtml
14
16
  Scythe scythe https://github.com/vsbuffalo/scythe Required version: 0.991+
15
17
  FastQC fastqc http://www.bioinformatics.babraham.ac.uk/projects/fastqc
16
18
  SolexaQA++ SolexaQA++ http://solexaqa.sourceforge.net Required version: v3.1.3+
17
- DIAMOND (opt) diamond http://ab.inf.uni-tuebingen.de/software/diamond Required version: v0.9.20+
18
- MyTaxa (opt) MyTaxa http://enve-omics.ce.gatech.edu/mytaxa The folder must contain the db and utils dirs, and the AllGenomes.faa.dmnd database
19
- Krona (opt) ktImportText https://github.com/marbl/Krona/wiki
20
- FastANI (opt) fastANI https://github.com/ParBLiSS/FastANI Required version: 1.1+
19
+ OpenJDK (rdp) java https://adoptopenjdk.net/ Any Java VM would work
20
+ MyTaxa (mytaxa) MyTaxa http://enve-omics.ce.gatech.edu/mytaxa
21
+ Krona (mytaxa) ktImportText https://github.com/marbl/Krona/wiki
@@ -15,7 +15,7 @@ class MiGA::SubcladeRunner
15
15
  @step = step.to_sym
16
16
  @home = File.join(
17
17
  File.join(project.path, 'data', '10.clades'),
18
- @step == :clade_finding ? '01.find' : '02.ani'
18
+ @step == :clade_finding ? '01.find.running' : '02.ani.running'
19
19
  )
20
20
  @opts[:thr] ||= ENV.fetch('CORES') { 2 }.to_i
21
21
  @opts[:run_clades] = !!@project.metadata.data.fetch(:run_clades) { true }
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.7.20.1
4
+ version: 0.7.23.0
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: 2021-01-10 00:00:00.000000000 Z
11
+ date: 2021-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: daemons
@@ -145,6 +145,7 @@ files:
145
145
  - lib/miga/cli/action/index_wf.rb
146
146
  - lib/miga/cli/action/init.rb
147
147
  - lib/miga/cli/action/init/daemon_helper.rb
148
+ - lib/miga/cli/action/init/files_helper.rb
148
149
  - lib/miga/cli/action/lair.rb
149
150
  - lib/miga/cli/action/ln.rb
150
151
  - lib/miga/cli/action/ls.rb
@@ -169,6 +170,7 @@ files:
169
170
  - lib/miga/common/base.rb
170
171
  - lib/miga/common/format.rb
171
172
  - lib/miga/common/hooks.rb
173
+ - lib/miga/common/net.rb
172
174
  - lib/miga/common/path.rb
173
175
  - lib/miga/common/with_daemon.rb
174
176
  - lib/miga/common/with_daemon_class.rb
@@ -235,6 +237,7 @@ files:
235
237
  - test/json_test.rb
236
238
  - test/lair_test.rb
237
239
  - test/metadata_test.rb
240
+ - test/net_test.rb
238
241
  - test/project_test.rb
239
242
  - test/remote_dataset_test.rb
240
243
  - test/result_stats_test.rb