miga-base 0.7.22.0 → 0.7.25.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/README.md +1 -1
  4. data/Rakefile +1 -0
  5. data/lib/miga/cli/action/add.rb +10 -8
  6. data/lib/miga/cli/action/classify_wf.rb +12 -11
  7. data/lib/miga/cli/action/derep_wf.rb +3 -9
  8. data/lib/miga/cli/action/edit.rb +0 -1
  9. data/lib/miga/cli/action/find.rb +1 -1
  10. data/lib/miga/cli/action/generic.rb +1 -1
  11. data/lib/miga/cli/action/get.rb +7 -2
  12. data/lib/miga/cli/action/get_db.rb +16 -21
  13. data/lib/miga/cli/action/index_wf.rb +4 -2
  14. data/lib/miga/cli/action/init.rb +93 -144
  15. data/lib/miga/cli/action/init/daemon_helper.rb +1 -2
  16. data/lib/miga/cli/action/init/files_helper.rb +119 -0
  17. data/lib/miga/cli/action/ncbi_get.rb +1 -1
  18. data/lib/miga/cli/action/new.rb +15 -9
  19. data/lib/miga/cli/action/option.rb +44 -0
  20. data/lib/miga/cli/action/preproc_wf.rb +7 -5
  21. data/lib/miga/cli/action/quality_wf.rb +3 -3
  22. data/lib/miga/cli/action/tax_dist.rb +1 -1
  23. data/lib/miga/cli/action/tax_test.rb +1 -1
  24. data/lib/miga/cli/action/wf.rb +71 -53
  25. data/lib/miga/cli/base.rb +17 -5
  26. data/lib/miga/cli/objects_helper.rb +23 -18
  27. data/lib/miga/common.rb +4 -2
  28. data/lib/miga/common/net.rb +74 -0
  29. data/lib/miga/common/with_option.rb +83 -0
  30. data/lib/miga/common/with_result.rb +3 -2
  31. data/lib/miga/dataset/base.rb +20 -2
  32. data/lib/miga/dataset/result.rb +5 -3
  33. data/lib/miga/metadata.rb +25 -13
  34. data/lib/miga/project/base.rb +82 -2
  35. data/lib/miga/project/result.rb +4 -4
  36. data/lib/miga/remote_dataset.rb +2 -0
  37. data/lib/miga/result/stats.rb +2 -2
  38. data/lib/miga/version.rb +4 -2
  39. data/scripts/essential_genes.bash +18 -3
  40. data/scripts/miga.bash +8 -2
  41. data/scripts/mytaxa.bash +6 -5
  42. data/scripts/mytaxa_scan.bash +8 -7
  43. data/scripts/ogs.bash +2 -3
  44. data/scripts/ssu.bash +16 -2
  45. data/test/dataset_test.rb +5 -5
  46. data/test/lair_test.rb +1 -2
  47. data/test/net_test.rb +34 -0
  48. data/test/with_option_test.rb +115 -0
  49. data/utils/FastAAI/00.Libraries/01.SCG_HMMs/Archaea_SCG.hmm +41964 -0
  50. data/utils/FastAAI/00.Libraries/01.SCG_HMMs/Bacteria_SCG.hmm +32439 -0
  51. data/utils/FastAAI/00.Libraries/01.SCG_HMMs/Complete_SCG_DB.hmm +62056 -0
  52. data/utils/FastAAI/FastAAI/FastAAI +1336 -0
  53. data/utils/FastAAI/README.md +84 -0
  54. data/utils/FastAAI/kAAI_v1.0_virus.py +1296 -0
  55. data/utils/cleanup-databases.rb +2 -3
  56. data/utils/distance/base.rb +9 -0
  57. data/utils/distance/commands.rb +183 -81
  58. data/utils/distance/database.rb +69 -10
  59. data/utils/distance/pipeline.rb +15 -21
  60. data/utils/distance/runner.rb +27 -49
  61. data/utils/distance/temporal.rb +4 -2
  62. data/utils/distances.rb +2 -2
  63. data/utils/index_metadata.rb +1 -2
  64. data/utils/requirements.txt +6 -5
  65. data/utils/subclade/runner.rb +10 -11
  66. metadata +18 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 02ebfc11d56c4647f2ad4aac749d507f5ff142840bc67efec81eac54c4514b13
4
- data.tar.gz: cdc1c8d3433ea6bb2fea77580645d9069b0311ec0fe2a6ca0ad8bae02553a4ea
3
+ metadata.gz: fefd5ed0ec84f2b49d25243ecaec7e567000c04598605ba8a78d0a866c35e5b1
4
+ data.tar.gz: b0f473401ccf64d31fcfc0ed19b54a2b84d29c138e3f983a69083659fcfe547e
5
5
  SHA512:
6
- metadata.gz: a19fa111709a73948496269ad583773ecc26aaf3e6285f38241614fc33aff509d4d379b5a0bf752b40e59f388d22432440eba977946afdfa59fda2a39f82b0ba
7
- data.tar.gz: 7cbafa4d27b1516de8e6cc1c17bc5044fcba085adabb4c9c20d3c5cce6b1b3155aa53e90b4cb2afd86e43d72b63dba32c06e2317651fbcecac63837b3b31b383
6
+ metadata.gz: 2520f7169e91e38aed0027e679d0cbc126271a6948ce27916bef9a34299eb50df249568d06bbdb09c5ff13754ec7628d48d7154a18c5bf363628b69d241757c2
7
+ data.tar.gz: 0e684e321ec13e022f95d0499c2c83fea6230bbcadbaacce226e20423cda9ea7466fac929b579e29b6a50745b243da53b9d1697a5e08876b2d423d577205e269
data/Gemfile CHANGED
@@ -1,6 +1,9 @@
1
1
  source "https://rubygems.org"
2
2
  gemspec name: "miga-base"
3
+
3
4
  group :test do
4
5
  gem "simplecov"
5
6
  gem "codeclimate-test-reporter", "~> 1.0.0"
6
7
  end
8
+
9
+ gem "rake", "~> 12.0"
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
 
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ require 'bundler/gem_tasks'
1
2
  require 'rake/testtask'
2
3
 
3
4
  SOURCES = FileList['lib/**/*.rb']
@@ -6,10 +6,7 @@ require 'miga/cli/action'
6
6
  class MiGA::Cli::Action::Add < MiGA::Cli::Action
7
7
  def parse_cli
8
8
  cli.expect_files = true
9
- cli.defaults = {
10
- ref: true, ignore_dups: false,
11
- regexp: MiGA::Cli.FILE_REGEXP
12
- }
9
+ cli.defaults = { ref: true, ignore_dups: false }
13
10
  cli.parse do |opt|
14
11
  opt.separator 'You can create multiple datasets with a single command; ' \
15
12
  'simply pass all the files at the end: {FILES...}'
@@ -37,7 +34,10 @@ class MiGA::Cli::Action::Add < MiGA::Cli::Action
37
34
  opt.on(
38
35
  '-R', '--name-regexp REGEXP', Regexp,
39
36
  'Regular expression indicating how to extract the name from the path',
40
- "By default: '#{cli[:regexp]}'"
37
+ 'By default for paired files:',
38
+ "'#{MiGA::Cli.FILE_REGEXP(true)}'",
39
+ 'By default for other files:',
40
+ "'#{MiGA::Cli.FILE_REGEXP}'"
41
41
  ) { |v| cli[:regexp] = v }
42
42
  opt.on(
43
43
  '--prefix STRING',
@@ -59,14 +59,16 @@ class MiGA::Cli::Action::Add < MiGA::Cli::Action
59
59
  p = cli.load_project
60
60
  files, file_type = get_files_and_type
61
61
 
62
+ paired = cli[:input_type].to_s.include?('_paired')
63
+ cli[:regexp] ||= MiGA::Cli.FILE_REGEXP(paired)
64
+
62
65
  cli.say 'Creating datasets:'
63
66
  files.each do |file|
64
67
  d = create_dataset(file, p)
65
68
  next if d.nil?
66
69
 
67
70
  copy_file_to_project(file, file_type, d, p)
68
- d = cli.add_metadata(d)
69
- d.save
71
+ cli.add_metadata(d)
70
72
  p.add_dataset(d.name)
71
73
  res = d.first_preprocessing(true)
72
74
  cli.say " result: #{res}"
@@ -167,7 +169,7 @@ class MiGA::Cli::Action::Add < MiGA::Cli::Action
167
169
  file_type[2].each_with_index do |ext, i|
168
170
  gz = file[i] =~ /\.gz/ ? '.gz' : ''
169
171
  FileUtils.cp(file[i], "#{r_path}#{ext}#{gz}")
170
- cli.say " file: #{file[i]}"
172
+ cli.say " file: #{File.basename(file[i])}"
171
173
  end
172
174
  File.open("#{r_path}.done", 'w') { |f| f.print Time.now.to_s }
173
175
  end
@@ -49,23 +49,24 @@ class MiGA::Cli::Action::ClassifyWf < MiGA::Cli::Action
49
49
  def perform
50
50
  # Input data
51
51
  ref_db = reference_db
52
- p_metadata = Hash[
53
- %w[project_stats haai_distances aai_distances ani_distances clade_finding]
54
- .map { |i| ["run_#{i}", false] }
52
+ norun = %w[
53
+ project_stats haai_distances aai_distances ani_distances clade_finding
55
54
  ]
56
- p_metadata[:ref_project] = ref_db.path
57
- p_metadata[:tax_pvalue] = cli[:pvalue]
58
- p = create_project(:assembly, p_metadata,
59
- run_ssu: false, run_mytaxa_scan: false, run_distances: false)
55
+ p_metadata = Hash[norun.map { |i| ["run_#{i}", false] }]
56
+ p = create_project(
57
+ :assembly,
58
+ p_metadata,
59
+ run_ssu: false, run_mytaxa_scan: false, run_distances: false
60
+ )
61
+ p.set_option(:ref_project, ref_db.path)
62
+ p.set_option(:tax_pvalue, cli[:pvalue], true)
60
63
  # Run
61
64
  run_daemon
62
65
  summarize(%w[cds assembly essential_genes]) if cli[:summaries]
63
66
  summarize(['taxonomy'])
64
67
  cli.say "Summary: classification"
65
- call_cli([
66
- 'ls', '-P', cli[:outdir], '-m', 'tax', '--tab',
67
- '-o', File.expand_path('classification.tsv', cli[:outdir])
68
- ])
68
+ ofile = File.expand_path('classification.tsv', cli[:outdir])
69
+ call_cli(['ls', '-P', cli[:outdir], '-m', 'tax', '--tab', '-o', ofile])
69
70
  cleanup
70
71
  end
71
72
 
@@ -52,17 +52,11 @@ class MiGA::Cli::Action::DerepWf < MiGA::Cli::Action
52
52
  # Input data
53
53
  p = create_project(
54
54
  :assembly,
55
- {
56
- run_project_stats: false,
57
- run_clades: false,
58
- gsp_metric: cli[:metric],
59
- :"gsp_#{cli[:metric]}" => cli[:threshold]
60
- },
55
+ { run_project_stats: false, run_clades: false },
61
56
  { run_mytaxa_scan: false, run_ssu: false }
62
57
  )
63
- unless cli[:threshold] >= 0.0 && cli[:threshold] <= 100.0
64
- raise 'The threshold of identity must be in the range [0,100]'
65
- end
58
+ p.set_option(:gsp_metric, cli[:metric].to_s)
59
+ p.set_option(:"gsp_#{cli[:metric]}", cli[:threshold])
66
60
 
67
61
  # Run
68
62
  run_daemon
@@ -34,6 +34,5 @@ class MiGA::Cli::Action::Edit < MiGA::Cli::Action
34
34
  cli[:activate] ? obj.activate! : obj.inactivate!(cli[:reason])
35
35
  end
36
36
  cli.add_metadata(obj)
37
- obj.save
38
37
  end
39
38
  end
@@ -37,7 +37,7 @@ class MiGA::Cli::Action::Find < MiGA::Cli::Action
37
37
  if cli[:add]
38
38
  cli.say "Registering: #{dn}"
39
39
  d = Dataset.new(p, dn, cli[:ref])
40
- d = add_metadata(d)
40
+ add_metadata(d)
41
41
  p.add_dataset(dn)
42
42
  res = d.first_preprocessing(true)
43
43
  cli.say "- #{res}"
@@ -20,7 +20,7 @@ class MiGA::Cli::Action::Generic < MiGA::Cli::Action
20
20
  opt.on(
21
21
  '-v', '--version',
22
22
  'Show MiGA version'
23
- ) { puts MiGA::MiGA.VERSION; exit }
23
+ ) { puts MiGA::MiGA.FULL_VERSION; exit }
24
24
  opt.on(
25
25
  '-V', '--long-version',
26
26
  'Show complete MiGA version'
@@ -6,8 +6,9 @@ require 'miga/remote_dataset'
6
6
 
7
7
  class MiGA::Cli::Action::Get < MiGA::Cli::Action
8
8
  def parse_cli
9
- cli.defaults = { query: false, universe: :ncbi, db: :nuccore,
10
- get_md: false, only_md: false }
9
+ cli.defaults = {
10
+ query: false, universe: :ncbi, db: :nuccore, get_md: false, only_md: false
11
+ }
11
12
  cli.parse do |opt|
12
13
  cli.opt_object(opt, [:project, :dataset, :dataset_type])
13
14
  opt.on(
@@ -141,6 +142,10 @@ class MiGA::Cli::Action::Get < MiGA::Cli::Action
141
142
 
142
143
  def create_dataset(sub_cli, p, rd)
143
144
  sub_cli.say 'Creating dataset'
145
+ if Dataset.exist?(p, sub_cli[:dataset])
146
+ raise "Dataset already exists: #{sub_cli[:dataset]}"
147
+ end
148
+
144
149
  dummy_d = Dataset.new(p, sub_cli[:dataset])
145
150
  md = sub_cli.add_metadata(dummy_d).metadata.data
146
151
  md[:metadata_only] = true if cli[:only_md]
@@ -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)
@@ -16,8 +16,10 @@ class MiGA::Cli::Action::IndexWf < MiGA::Cli::Action
16
16
  'Perform MyTaxa scan analysis'
17
17
  ) { |v| cli[:mytaxa] = v }
18
18
  opts_for_wf_distances(opt)
19
- opts_for_wf(opt, 'Input genome assemblies (nucleotides, FastA)',
20
- cleanup: false, project_type: true)
19
+ opts_for_wf(
20
+ opt, 'Input genome assemblies (nucleotides, FastA)',
21
+ cleanup: false, project_type: true
22
+ )
21
23
  end
22
24
  end
23
25
 
@@ -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,12 @@ 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_libraries(paths)
55
65
  configure_daemon
56
- close_rc_file rc_fh
66
+ close_rc_file(rc_fh)
57
67
  cli.puts 'Configuration complete. MiGA is ready to work!'
58
68
  cli.puts ''
59
69
  end
@@ -72,34 +82,6 @@ class MiGA::Cli::Action::Init < MiGA::Cli::Action
72
82
  )
73
83
  end
74
84
 
75
- def test_r_package(cli, paths, pkg)
76
- run_r_cmd(cli, paths, "library('#{pkg}')")
77
- $?.success?
78
- end
79
-
80
- def install_r_package(cli, paths, pkg)
81
- r_cmd = "install.packages('#{pkg}', repos='http://cran.rstudio.com/')"
82
- run_r_cmd(cli, paths, r_cmd)
83
- end
84
-
85
- def test_ruby_gem(cli, paths, pkg)
86
- run_cmd(
87
- cli,
88
- "#{paths['ruby'].shellescape} -r #{pkg.shellescape} -e '' 2>/dev/null"
89
- )
90
- $?.success?
91
- end
92
-
93
- def install_ruby_gem(cli, paths, pkg)
94
- gem_cmd = "Gem::GemRunner.new.run %w(install --user #{pkg})"
95
- run_cmd(
96
- cli,
97
- "#{paths['ruby'].shellescape} \
98
- -r rubygems -r rubygems/gem_runner \
99
- -e #{gem_cmd.shellescape} 2>&1"
100
- )
101
- end
102
-
103
85
  def list_requirements
104
86
  if cli.ask_user(
105
87
  'Would you like to see all the requirements before starting?',
@@ -116,58 +98,18 @@ class MiGA::Cli::Action::Init < MiGA::Cli::Action
116
98
 
117
99
  private
118
100
 
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
101
  def check_software_requirements(rc_fh)
158
102
  cli.puts 'Looking for requirements:'
159
- ask_for_mytaxa
160
- rc_fh.puts 'export MIGA_MYTAXA="no"' unless cli[:mytaxa]
103
+ ask_for_optional(:mytaxa, 'MyTaxa')
104
+ rc_fh.puts "export MIGA_MYTAXA='#{cli[:mytaxa] ? 'yes' : 'no'}'"
105
+ ask_for_optional(:rdp, 'RDP classifier')
106
+ rc_fh.puts "export MIGA_RDP='#{cli[:rdp] ? 'yes' : 'no'}'"
161
107
  paths = {}
162
108
  rc_fh.puts 'MIGA_PATH=""'
163
109
  req_path = File.expand_path('utils/requirements.txt', MiGA.root_path)
164
110
  File.open(req_path, 'r') do |fh|
165
111
  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
-
112
+ r = define_software(ln) or next
171
113
  cli.print "Testing #{r[0]}#{" (#{r[3]})" if r[3]}... "
172
114
  path = find_software(r[1])
173
115
  paths[r[1]] = File.expand_path(r[1], path).shellescape
@@ -178,11 +120,20 @@ class MiGA::Cli::Action::Init < MiGA::Cli::Action
178
120
  paths
179
121
  end
180
122
 
181
- def ask_for_mytaxa
182
- if cli[:mytaxa].nil?
183
- cli[:mytaxa] =
123
+ def define_software(ln)
124
+ r = ln.chomp.split(/\t+/)
125
+ return if %w[Software --------].include?(r[0])
126
+ return if r[0] =~ /\(mytaxa\)$/ && !cli[:mytaxa]
127
+ return if r[0] =~ /\(rdp\)$/ && !cli[:rdp]
128
+
129
+ r
130
+ end
131
+
132
+ def ask_for_optional(symbol, name)
133
+ if cli[symbol].nil?
134
+ cli[symbol] =
184
135
  cli.ask_user(
185
- 'Should I include MyTaxa modules?',
136
+ "Should I include #{name} modules?",
186
137
  'yes', %w(yes no)
187
138
  ) == 'yes'
188
139
  end
@@ -209,72 +160,70 @@ class MiGA::Cli::Action::Init < MiGA::Cli::Action
209
160
  path
210
161
  end
211
162
 
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)
163
+ def check_libraries(paths)
164
+ req_libraries = {
165
+ r: %w[ape cluster vegan],
166
+ ruby: %w[sqlite3 daemons json],
167
+ python: %w[numpy]
168
+ }
169
+
170
+ req_libraries.each do |language, libraries|
171
+ cli.puts "Looking for #{language.to_s.capitalize} libraries:"
172
+ libraries.each do |lib|
173
+ check_and_install_library(paths, language, lib)
228
174
  end
229
175
  cli.puts ''
230
176
  end
231
177
  end
232
178
 
233
- def check_r_packages(paths)
234
- cli.puts 'Looking for R packages:'
235
- %w(ape cluster vegan).each do |pkg|
236
- cli.print "Testing #{pkg}... "
237
- if test_r_package(cli, paths, pkg)
238
- cli.puts 'yes'
239
- else
240
- cli.puts 'no, installing'
241
- cli.print '' + install_r_package(cli, paths, pkg)
242
- unless test_r_package(cli, paths, pkg)
243
- raise "Unable to auto-install R package: #{pkg}"
244
- end
179
+ def check_and_install_library(paths, language, library)
180
+ cli.print "Testing #{library}... "
181
+ if test_library(cli, paths, language, library)
182
+ cli.puts 'yes'
183
+ else
184
+ cli.puts 'no, installing'
185
+ cli.print '' + install_library(cli, paths, language, library)
186
+ unless test_library(cli, paths, language, library)
187
+ raise "Cannot install #{language.to_s.capitalize} library: #{library}"
245
188
  end
246
189
  end
247
- cli.puts ''
248
190
  end
249
191
 
250
- def check_ruby_gems(paths)
251
- cli.puts 'Looking for Ruby gems:'
252
- %w(sqlite3 daemons json).each do |pkg|
253
- cli.print "Testing #{pkg}... "
254
- if test_ruby_gem(cli, paths, pkg)
255
- cli.puts 'yes'
256
- else
257
- cli.puts 'no, installing'
258
- # This hackey mess is meant to ensure the test and installation are done
259
- # on the configuration Ruby, not on the Ruby currently executing the
260
- # init action
261
- cli.print install_ruby_gem(cli, paths, pkg)
262
- unless test_ruby_gem(cli, paths, pkg)
263
- raise "Unable to auto-install Ruby gem: #{pkg}"
264
- end
265
- end
192
+ def test_library(cli, paths, language, pkg)
193
+ case language
194
+ when :r
195
+ run_r_cmd(cli, paths, "library('#{pkg}')")
196
+ when :ruby
197
+ x = "#{paths['ruby'].shellescape} -r #{pkg.shellescape} -e '' 2>/dev/null"
198
+ run_cmd(cli, x)
199
+ when :python
200
+ x = "#{paths['python3'].shellescape} -c 'import #{pkg}' 2>/dev/null"
201
+ run_cmd(cli, x)
202
+ else
203
+ raise "Unrecognized language: #{language}"
266
204
  end
267
- cli.puts ''
205
+ $?.success?
268
206
  end
269
207
 
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
208
+ def install_library(cli, paths, language, pkg)
209
+ case language
210
+ when :r
211
+ r_cmd = "install.packages('#{pkg}', repos='http://cran.rstudio.com/')"
212
+ run_r_cmd(cli, paths, r_cmd)
213
+ when :ruby
214
+ # This hackey mess is meant to ensure the test and installation are done
215
+ # on the configuration Ruby, not on the Ruby currently executing the
216
+ # init action
217
+ gem_cmd = "Gem::GemRunner.new.run %w(install --user #{pkg})"
218
+ x = "#{paths['ruby'].shellescape} -r rubygems -r rubygems/gem_runner \
219
+ -e #{gem_cmd.shellescape} 2>&1"
220
+ run_cmd(cli, x)
221
+ when :python
222
+ x = "#{paths['python3'].shellescape} \
223
+ -m pip install #{pkg.shellescape} 2>&1"
224
+ run_cmd(cli, x)
225
+ else
226
+ raise "Unrecognized language: #{language}"
227
+ end
279
228
  end
280
229
  end