miga-base 0.7.3.1 → 0.7.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/lib/miga/cli.rb +10 -8
  3. data/lib/miga/cli/action.rb +2 -3
  4. data/lib/miga/cli/action/about.rb +5 -6
  5. data/lib/miga/cli/action/add.rb +18 -12
  6. data/lib/miga/cli/action/add_result.rb +2 -3
  7. data/lib/miga/cli/action/archive.rb +1 -2
  8. data/lib/miga/cli/action/classify_wf.rb +8 -6
  9. data/lib/miga/cli/action/console.rb +0 -1
  10. data/lib/miga/cli/action/daemon.rb +7 -7
  11. data/lib/miga/cli/action/date.rb +0 -1
  12. data/lib/miga/cli/action/derep_wf.rb +5 -4
  13. data/lib/miga/cli/action/doctor.rb +71 -82
  14. data/lib/miga/cli/action/doctor/base.rb +102 -0
  15. data/lib/miga/cli/action/edit.rb +14 -2
  16. data/lib/miga/cli/action/files.rb +8 -8
  17. data/lib/miga/cli/action/find.rb +5 -6
  18. data/lib/miga/cli/action/generic.rb +7 -7
  19. data/lib/miga/cli/action/get.rb +20 -17
  20. data/lib/miga/cli/action/get_db.rb +8 -2
  21. data/lib/miga/cli/action/index_wf.rb +1 -1
  22. data/lib/miga/cli/action/init.rb +53 -41
  23. data/lib/miga/cli/action/init/daemon_helper.rb +65 -43
  24. data/lib/miga/cli/action/lair.rb +7 -7
  25. data/lib/miga/cli/action/ln.rb +6 -6
  26. data/lib/miga/cli/action/ls.rb +1 -2
  27. data/lib/miga/cli/action/ncbi_get.rb +11 -3
  28. data/lib/miga/cli/action/new.rb +4 -4
  29. data/lib/miga/cli/action/next_step.rb +0 -1
  30. data/lib/miga/cli/action/preproc_wf.rb +3 -3
  31. data/lib/miga/cli/action/quality_wf.rb +1 -1
  32. data/lib/miga/cli/action/rm.rb +2 -3
  33. data/lib/miga/cli/action/run.rb +8 -8
  34. data/lib/miga/cli/action/stats.rb +8 -4
  35. data/lib/miga/cli/action/summary.rb +7 -6
  36. data/lib/miga/cli/action/tax_dist.rb +8 -4
  37. data/lib/miga/cli/action/tax_index.rb +3 -4
  38. data/lib/miga/cli/action/tax_set.rb +7 -6
  39. data/lib/miga/cli/action/tax_test.rb +6 -5
  40. data/lib/miga/cli/action/wf.rb +25 -19
  41. data/lib/miga/cli/base.rb +34 -32
  42. data/lib/miga/cli/objects_helper.rb +27 -18
  43. data/lib/miga/cli/opt_helper.rb +3 -2
  44. data/lib/miga/common.rb +2 -5
  45. data/lib/miga/common/base.rb +15 -16
  46. data/lib/miga/common/format.rb +8 -5
  47. data/lib/miga/common/hooks.rb +1 -4
  48. data/lib/miga/common/path.rb +4 -9
  49. data/lib/miga/common/with_daemon.rb +5 -2
  50. data/lib/miga/common/with_daemon_class.rb +1 -1
  51. data/lib/miga/common/with_result.rb +2 -1
  52. data/lib/miga/daemon.rb +93 -44
  53. data/lib/miga/daemon/base.rb +30 -11
  54. data/lib/miga/dataset.rb +47 -37
  55. data/lib/miga/dataset/base.rb +52 -37
  56. data/lib/miga/dataset/hooks.rb +3 -4
  57. data/lib/miga/dataset/result.rb +17 -1
  58. data/lib/miga/dataset/status.rb +6 -5
  59. data/lib/miga/json.rb +5 -7
  60. data/lib/miga/lair.rb +4 -0
  61. data/lib/miga/metadata.rb +4 -3
  62. data/lib/miga/project.rb +29 -20
  63. data/lib/miga/project/base.rb +52 -37
  64. data/lib/miga/project/dataset.rb +33 -26
  65. data/lib/miga/project/hooks.rb +0 -3
  66. data/lib/miga/project/result.rb +14 -5
  67. data/lib/miga/remote_dataset.rb +85 -72
  68. data/lib/miga/remote_dataset/base.rb +11 -13
  69. data/lib/miga/remote_dataset/download.rb +34 -12
  70. data/lib/miga/result.rb +48 -53
  71. data/lib/miga/result/base.rb +0 -2
  72. data/lib/miga/result/dates.rb +1 -3
  73. data/lib/miga/result/source.rb +15 -16
  74. data/lib/miga/result/stats.rb +37 -27
  75. data/lib/miga/tax_dist.rb +6 -3
  76. data/lib/miga/tax_index.rb +17 -17
  77. data/lib/miga/taxonomy.rb +6 -1
  78. data/lib/miga/taxonomy/base.rb +19 -15
  79. data/lib/miga/version.rb +19 -16
  80. data/scripts/project_stats.bash +3 -0
  81. data/scripts/stats.bash +1 -1
  82. data/test/common_test.rb +3 -11
  83. data/test/daemon_helper.rb +38 -0
  84. data/test/daemon_test.rb +91 -99
  85. data/test/dataset_test.rb +63 -59
  86. data/test/format_test.rb +3 -11
  87. data/test/hook_test.rb +50 -55
  88. data/test/json_test.rb +7 -8
  89. data/test/lair_test.rb +22 -28
  90. data/test/metadata_test.rb +6 -14
  91. data/test/project_test.rb +33 -40
  92. data/test/remote_dataset_test.rb +26 -32
  93. data/test/result_stats_test.rb +17 -27
  94. data/test/result_test.rb +41 -34
  95. data/test/tax_dist_test.rb +2 -4
  96. data/test/tax_index_test.rb +4 -10
  97. data/test/taxonomy_test.rb +7 -9
  98. data/test/test_helper.rb +42 -1
  99. data/test/with_daemon_test.rb +14 -22
  100. data/utils/adapters.fa +13 -0
  101. data/utils/cleanup-databases.rb +6 -5
  102. data/utils/distance/base.rb +0 -1
  103. data/utils/distance/commands.rb +19 -12
  104. data/utils/distance/database.rb +24 -21
  105. data/utils/distance/pipeline.rb +23 -10
  106. data/utils/distance/runner.rb +20 -16
  107. data/utils/distance/temporal.rb +1 -3
  108. data/utils/distances.rb +1 -1
  109. data/utils/domain-ess-genes.rb +7 -7
  110. data/utils/index_metadata.rb +5 -4
  111. data/utils/mytaxa_scan.rb +18 -16
  112. data/utils/representatives.rb +5 -4
  113. data/utils/requirements.txt +1 -1
  114. data/utils/subclade/base.rb +0 -1
  115. data/utils/subclade/pipeline.rb +7 -6
  116. data/utils/subclade/runner.rb +9 -9
  117. data/utils/subclade/temporal.rb +0 -2
  118. data/utils/subclades-compile.rb +39 -37
  119. data/utils/subclades.rb +1 -1
  120. metadata +6 -4
@@ -13,17 +13,18 @@ db.execute 'create table metadata(' \
13
13
 
14
14
  def searchable(db, d, k, v)
15
15
  db.execute 'insert into metadata values(?,?,?)',
16
- d.name, k.to_s, " #{v.to_s.downcase.gsub(/[^A-Za-z0-9\-]+/, ' ')} "
16
+ d.name, k.to_s, " #{v.to_s.downcase.gsub(/[^A-Za-z0-9\-]+/, ' ')} "
17
17
  end
18
18
 
19
- p.each_dataset do |name, d|
19
+ p.each_dataset do |d|
20
20
  next unless d.is_ref?
21
21
  next unless d.is_active?
22
+
22
23
  searchable(db, d, :name, d.name)
23
24
  d.metadata.each do |k, v|
24
25
  next if [:created, :updated].include? k
25
- v = v.sorted_ranks.map{ |r| r[1] }.join(" ") if k==:tax
26
+
27
+ v = v.sorted_ranks.map { |r| r[1] }.join(' ') if k == :tax
26
28
  searchable(db, d, k, v)
27
29
  end
28
30
  end
29
-
@@ -15,42 +15,45 @@ begin
15
15
 
16
16
  # Extract gene IDs
17
17
  ifh = faa =~ /\.gz/ ? Zlib::GzipReader.open(faa) : File.open(faa, 'r')
18
- ids = ifh.each_line.grep(/^>/).map{|dl| dl.chomp.sub(/^>/,'').sub(/\s.*/,'')}
18
+ ids = ifh.each_line.grep(/^>/).map { |dl| dl.chomp.sub(/^>/, '').sub(/\s.*/, '') }
19
19
  ifh.close
20
- tax = Hash[ids.map{|k| [k, "NA"]}]
20
+ tax = Hash[ids.map { |k| [k, "NA"] }]
21
21
 
22
22
  # Get MyTaxa distributions
23
23
  k, l = nil
24
24
  File.open(mytaxa).each do |ln|
25
25
  ln.chomp!
26
- if $.%2 == 1
26
+ if $. % 2 == 1
27
27
  k, l = ln.split /\t/
28
28
  else
29
- tax[k] = ln.gsub(/<[^>]+>/,"").gsub(/;/,"::")
29
+ tax[k] = ln.gsub(/<[^>]+>/, '').gsub(/;/, '::')
30
30
  end
31
31
  end
32
- all_tax = tax.values.uniq.sort{|x,y| tax.values.count(y) <=> tax.values.count(x) }
32
+ all_tax = tax.values.uniq.sort do |x, y|
33
+ tax.values.count(y) <=> tax.values.count(x)
34
+ end
33
35
 
34
36
  # Estimate Windows and save gene IDs
35
- fh = File.open(outdata + ".genes", "w")
37
+ fh = File.open(outdata + '.genes', 'w')
36
38
  c = []
37
- c << all_tax.map{|t| tax.values.count(t) }
38
- n_wins = (ids.size/winsize).ceil
39
- (0 .. (n_wins-1)).each do |win|
40
- k = ids[win*winsize, winsize]
39
+ c << all_tax.map { |t| tax.values.count(t) }
40
+ n_wins = (ids.size / winsize).ceil
41
+ (0..(n_wins - 1)).each do |win|
42
+ k = ids[win * winsize, winsize]
41
43
  win_t = tax.values_at(*k)
42
44
  fh.puts k.join("\t")
43
- c << all_tax.map{|t| win_t.count(t)}
45
+ c << all_tax.map { |t| win_t.count(t) }
44
46
  end
45
- p = c.map{|col| col.map{|cell| cell.to_f/col.inject(:+)}}
47
+ p = c.map { |col| col.map { |cell| cell.to_f / col.inject(:+) } }
46
48
  fh.close
47
49
 
48
50
  # Save window profiles
49
51
  fh = File.open(outdata, "w")
50
52
  fh.puts "# Data derived from #{mytaxa}, with #{winsize}-genes windows"
51
- fh.puts "# " + (["Tax-label", "Genome"] + (1 .. n_wins).map{|i| "Win_#{i}"}).join("\t")
52
- (0 .. (all_tax.size - 1)).each do |row|
53
- fh.puts ([all_tax[row]] + p.map{|col| col[row]}).join "\t"
53
+ fh.puts '# ' + (['Tax-label', 'Genome'] +
54
+ (1..n_wins).map { |i| "Win_#{i}" }).join("\t")
55
+ (0..(all_tax.size - 1)).each do |row|
56
+ fh.puts ([all_tax[row]] + p.map { |col| col[row] }).join "\t"
54
57
  end
55
58
  fh.close
56
59
  rescue => err
@@ -58,4 +61,3 @@ rescue => err
58
61
  err.backtrace.each { |l| $stderr.puts l + "\n" }
59
62
  err
60
63
  end
61
-
@@ -19,7 +19,8 @@ end
19
19
  ani_spp = []
20
20
  File.open(pf, 'r') do |fh|
21
21
  fh.each_line do |ln|
22
- next if $.==1 and ln.chomp == 'G' # <- Legacy check
22
+ next if $. == 1 and ln.chomp == 'G' # <- Legacy check
23
+
23
24
  ani_spp << ln.chomp.split(',')
24
25
  end
25
26
  end
@@ -32,10 +33,10 @@ ani_spp.each_with_index do |datasets, i|
32
33
  dr = d.result(:essential_genes) or next
33
34
  q = dr[:stats][:quality] or next
34
35
  if best.nil? or q > best[:q]
35
- best = {d: d, q: q}
36
+ best = { d: d, q: q }
36
37
  end
37
38
  end
38
39
  raise "Unavailable statistics for any of:\n#{datasets}\n" if best.nil?
39
- puts "ANIsp_#{i+1}\t#{best[:d].name}"
40
- end
41
40
 
41
+ puts "ANIsp_#{i + 1}\t#{best[:d].name}"
42
+ end
@@ -1,6 +1,6 @@
1
1
  Software Test exec Website Notes
2
2
  -------- --------- ------- -----
3
- Ruby ruby https://www.ruby-lang.org/ Required version: 2.1+
3
+ Ruby ruby https://www.ruby-lang.org/ Required version: 2.3+
4
4
  Python python https://www.python.org/
5
5
  R R http://www.r-project.org/
6
6
  SQLite3 sqlite3 https://www.sqlite.org/
@@ -1,4 +1,3 @@
1
-
2
1
  require 'zlib'
3
2
  require 'miga'
4
3
 
@@ -1,7 +1,5 @@
1
-
2
1
  # High-end pipelines for SubcladeRunner
3
2
  module MiGA::SubcladeRunner::Pipeline
4
-
5
3
  # Run species-level clusterings using ANI > 95% / AAI > 90%
6
4
  def cluster_species
7
5
  tasks = {
@@ -12,7 +10,7 @@ module MiGA::SubcladeRunner::Pipeline
12
10
  # Final output
13
11
  ogs_file = "miga-project.#{k}-clades"
14
12
  next if File.size? ogs_file
15
-
13
+
16
14
  # Build ABC files
17
15
  abc_path = tmp_file("#{k}.abc")
18
16
  ofh = File.open(abc_path, 'w')
@@ -20,6 +18,7 @@ module MiGA::SubcladeRunner::Pipeline
20
18
  Zlib::GzipReader.open(metric_res.file_path(:matrix)) do |ifh|
21
19
  ifh.each_line do |ln|
22
20
  next if ln =~ /^metric\t/
21
+
23
22
  r = ln.chomp.split("\t")
24
23
  ofh.puts "G>#{r[1]}\tG>#{r[2]}\t#{r[3]}" if r[3].to_f >= par[1]
25
24
  end
@@ -55,7 +54,8 @@ module MiGA::SubcladeRunner::Pipeline
55
54
  ofh = File.open('miga-project.proposed-clades', 'w')
56
55
  File.open('miga-project.gsp-clades', 'r') do |ifh|
57
56
  ifh.each_line do |ln|
58
- next if $.==1
57
+ next if $. == 1
58
+
59
59
  r = ln.chomp.split(',')
60
60
  ofh.puts r.join("\t") if r.size >= 5
61
61
  end
@@ -70,8 +70,9 @@ module MiGA::SubcladeRunner::Pipeline
70
70
  matrix = metric_res.file_path(:matrix)
71
71
  `Rscript '#{src}' '#{matrix}' miga-project '#{opts[:thr]}' \
72
72
  miga-project.ani95-medoids '#{opts[:run_clades] ? 'cluster' : 'empty'}'`
73
- File.rename('miga-project.nwk',"miga-project.#{metric}.nwk") if
74
- File.exist? 'miga-project.nwk'
73
+ if File.exist? 'miga-project.nwk'
74
+ File.rename('miga-project.nwk', "miga-project.#{metric}.nwk")
75
+ end
75
76
  end
76
77
 
77
78
  def compile
@@ -1,33 +1,34 @@
1
-
2
1
  require_relative 'base.rb'
3
2
  require_relative 'temporal.rb'
4
3
  require_relative 'pipeline.rb'
5
4
 
6
5
  class MiGA::SubcladeRunner
7
-
8
6
  include MiGA::SubcladeRunner::Temporal
9
7
  include MiGA::SubcladeRunner::Pipeline
10
8
 
11
9
  attr_reader :project, :step, :opts, :home, :tmp
12
10
 
13
- def initialize(project_path, step, opts_hash={})
11
+ def initialize(project_path, step, opts_hash = {})
14
12
  @opts = opts_hash
15
13
  @project = MiGA::Project.load(project_path) or
16
- raise "No project at #{project_path}"
14
+ raise "No project at #{project_path}"
17
15
  @step = step.to_sym
18
- clades_dir = File.expand_path('data/10.clades', project.path)
19
- @home = File.expand_path(@step == :clade_finding ? '01.find' : '02.ani',
20
- clades_dir)
16
+ @home = File.join(
17
+ File.join(project.path, 'data', '10.clades'),
18
+ @step == :clade_finding ? '01.find' : '02.ani'
19
+ )
21
20
  @opts[:thr] ||= ENV.fetch('CORES') { 2 }.to_i
22
21
  @opts[:run_clades] = !!@project.metadata.data.fetch(:run_clades) { true }
23
22
  @opts[:gsp_ani] = @project.metadata.data.fetch(:gsp_ani) { 95.0 }.to_f
24
23
  @opts[:gsp_aai] = @project.metadata.data.fetch(:gsp_aai) { 90.0 }.to_f
25
- @opts[:gsp_metric] = @project.metadata.data.fetch(:gsp_metric){ 'ani' }.to_s
24
+ @opts[:gsp_metric] =
25
+ @project.metadata.data.fetch(:gsp_metric) { 'ani' }.to_s
26
26
  end
27
27
 
28
28
  # Launch the appropriate analysis
29
29
  def go!
30
30
  return if project.type == :metagenomes
31
+
31
32
  unless @project.dataset_names.any? { |i| @project.dataset(i).is_ref? }
32
33
  FileUtils.touch(File.expand_path('miga-project.empty', @home))
33
34
  return
@@ -54,5 +55,4 @@ class MiGA::SubcladeRunner
54
55
  subclades :ani
55
56
  compile
56
57
  end
57
-
58
58
  end
@@ -1,8 +1,6 @@
1
-
2
1
  require 'tmpdir'
3
2
 
4
3
  module MiGA::SubcladeRunner::Temporal
5
-
6
4
  # Create the empty temporal structure
7
5
  def create_temporals
8
6
  end
@@ -1,49 +1,51 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $:.push File.expand_path(File.dirname(__FILE__) + "/lib")
4
3
  dir = ARGV.shift
5
4
  out = ARGV.shift or abort "Usage: #{$0} <classif.dir> <out.base>"
6
5
 
7
- def read_classif(dir, classif={})
8
- classif_file = File.expand_path("miga-project.classif", dir)
9
- return classif unless File.exist? classif_file
10
- ready = File.expand_path('miga-project.ready', dir)
11
- File.size?(ready) or raise "Incomplete recursion found at #{dir}"
12
- File.unlink ready
13
- fh = File.open(classif_file, "r")
14
- klass = []
15
- while ln = fh.gets
16
- r = ln.chomp.split("\t")
17
- classif[r[0]] ||= []
18
- classif[r[0]] << r[1]
19
- klass[r[1].to_i] = r[1]
20
- end
21
- fh.close
22
- klass.each do |i|
23
- d = File.expand_path("miga-project.sc-#{i}", dir)
24
- classif = read_classif(d, classif) if Dir.exist? d
25
- end
26
- classif
6
+ def read_classif(dir, classif = {})
7
+ classif_file = File.expand_path('miga-project.classif', dir)
8
+ return classif unless File.exist? classif_file
9
+
10
+ ready = File.expand_path('miga-project.ready', dir)
11
+ File.size?(ready) or raise "Incomplete recursion found at #{dir}"
12
+ File.unlink ready
13
+ fh = File.open(classif_file, 'r')
14
+ klass = []
15
+ while ln = fh.gets
16
+ r = ln.chomp.split("\t")
17
+ classif[r[0]] ||= []
18
+ classif[r[0]] << r[1]
19
+ klass[r[1].to_i] = r[1]
20
+ end
21
+ fh.close
22
+ klass.each do |i|
23
+ d = File.expand_path("miga-project.sc-#{i}", dir)
24
+ classif = read_classif(d, classif) if Dir.exist? d
25
+ end
26
+ classif
27
27
  end
28
28
 
29
- def print_tree(classif, col=0)
30
- klass = classif.values.map{ |i| i[col] }.compact.uniq
31
- if klass.size<=1
32
- o = classif.keys
33
- else
34
- o = klass.map do |c|
35
- oo = print_tree(classif.select{ |k,v| v[col]==c }, col+1)
36
- "#{oo}[#{c}]" unless oo.nil?
37
- end.compact
38
- end
39
- o.size==0 ? nil :
40
- o.size==1 ? o[0] :
41
- "(#{o.join(",")})"
29
+ def print_tree(classif, col = 0)
30
+ klass = classif.values.map { |i| i[col] }.compact.uniq
31
+ if klass.size <= 1
32
+ o = classif.keys
33
+ else
34
+ o = klass.map do |c|
35
+ oo = print_tree(classif.select { |k, v| v[col] == c }, col + 1)
36
+ "#{oo}[#{c}]" unless oo.nil?
37
+ end.compact
38
+ end
39
+ case o.size
40
+ when 0; nil
41
+ when 1; o[0]
42
+ else; "(#{o.join(',')})"
43
+ end
42
44
  end
43
45
 
44
46
  c = read_classif(dir)
45
- max_depth = c.values.map{|i| i.count}.max
47
+ max_depth = c.values.map { |i| i.count }.max
46
48
  File.open("#{out}.tsv", 'w') do |fh|
47
- c.each { |k,v| fh.puts ([k] + v + ["0"]*(max_depth-v.count)).join("\t") }
49
+ c.each { |k, v| fh.puts ([k] + v + ['0'] * (max_depth - v.count)).join("\t") }
48
50
  end
49
- File.open("#{out}.nwk", 'w') { |fh| fh.puts print_tree(c).to_s + ";" }
51
+ File.open("#{out}.nwk", 'w') { |fh| fh.puts print_tree(c).to_s + ';' }
@@ -4,6 +4,6 @@ require_relative 'subclade/runner.rb'
4
4
 
5
5
  project = ARGV.shift
6
6
  step = ARGV.shift
7
- opts = Hash[ ARGV.map{ |i| i.split("=",2).tap{ |j| j[0] = j[0].to_sym } } ]
7
+ opts = Hash[ARGV.map { |i| i.split("=", 2).tap { |j| j[0] = j[0].to_sym } }]
8
8
  runner = MiGA::SubcladeRunner.new(project, step, opts)
9
9
  runner.go!
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.3.1
4
+ version: 0.7.8.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: 2020-04-23 00:00:00.000000000 Z
11
+ date: 2020-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: daemons
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.4'
47
+ version: '1.3'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.4'
54
+ version: '1.3'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -124,6 +124,7 @@ files:
124
124
  - lib/miga/cli/action/date.rb
125
125
  - lib/miga/cli/action/derep_wf.rb
126
126
  - lib/miga/cli/action/doctor.rb
127
+ - lib/miga/cli/action/doctor/base.rb
127
128
  - lib/miga/cli/action/edit.rb
128
129
  - lib/miga/cli/action/files.rb
129
130
  - lib/miga/cli/action/find.rb
@@ -213,6 +214,7 @@ files:
213
214
  - scripts/trimmed_fasta.bash
214
215
  - scripts/trimmed_reads.bash
215
216
  - test/common_test.rb
217
+ - test/daemon_helper.rb
216
218
  - test/daemon_test.rb
217
219
  - test/dataset_test.rb
218
220
  - test/format_test.rb