miga-base 0.7.22.0 → 0.7.25.0

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.
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