miga-base 0.6.0.0 → 0.6.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 13b2ec821a69376491a0a3a31da7ccf717d8aafd1dc7753acaec36f3b7aa42c4
4
- data.tar.gz: f6d513971e2c06c3f299bc5bf680682c533b380ff4340443f789446a6835b54f
3
+ metadata.gz: 1b7ff73c17fe13dbe5952bb607981bba291cf29d34c372157281339061036157
4
+ data.tar.gz: d5af6ded80c32042dbc3463fab085f2bc5c58ea9fc8755224baeb8d08f527ff1
5
5
  SHA512:
6
- metadata.gz: 5a4de9af15f63372d98b64cf1604e64fc576c3809f435dc543acb98cab9779155998e5f1b382af856e5d4760faba0d9f606f614654afdad10659b764c9c6a17f
7
- data.tar.gz: bd01962ae2c1f75ec3768d2515bab711191c4a2b256996c51a69bcbdce5f87b06215816a6368fad0e399d69c09ec7992f97b9868e8670f3866bc1fdcb29d6c41
6
+ metadata.gz: b178fdfbe3ee23519fa7a6c23d15e6a9f393c1bea610124fa1ccf8245edbb3b95bb8ae9b46382eae3ca2e2664b1dd536fdd7a7c2b34c23cba35fb4e82c8a4123
7
+ data.tar.gz: 96e1ff434584528ae8dcf0b6435cc1dbe74a312eb9a1a1dbab86d7464dfe50eb38bced778caf0ef46446c11864495af4b8902ab76ac9700716f5d82ddf8370d9
data/bin/miga CHANGED
@@ -3,7 +3,7 @@
3
3
  # @package MiGA
4
4
  # @license Artistic-2.0
5
5
 
6
- $:.push File.expand_path('../../lib', __FILE__)
6
+ $LOAD_PATH.push File.expand_path('../../lib', __FILE__)
7
7
  require 'miga'
8
8
  require 'miga/cli'
9
9
 
@@ -0,0 +1,99 @@
1
+ # @package MiGA
2
+ # @license Artistic-2.0
3
+
4
+ require 'miga/cli/action'
5
+ require 'rubygems/package'
6
+
7
+ class MiGA::Cli::Action::Archive < MiGA::Cli::Action
8
+
9
+ def parse_cli
10
+ cli.parse do |opt|
11
+ opt.on(
12
+ '-o', '--tarball PATH',
13
+ '(Mandatory) Path to the archive to be created ending in .tar.gz'
14
+ ) { |v| cli[:tarball] = v }
15
+ opt.on(
16
+ '-f', '--folder STRING',
17
+ 'Name of the output folder. By default: name of the source project'
18
+ ) { |v| cli[:folder] = v }
19
+ cli.opt_object(opt, [:project, :dataset_opt])
20
+ cli.opt_filter_datasets(opt)
21
+ end
22
+ end
23
+
24
+ def perform
25
+ cli.ensure_par(tarball: '-o')
26
+ unless cli[:tarball] =~ /\.tar\.gz$/
27
+ raise 'The tarball path (-o) must have .tar.gz extension'
28
+ end
29
+ cli[:folder] ||= cli.load_project.name
30
+ ds = cli.load_and_filter_datasets
31
+
32
+ open_tarball do |tar|
33
+ # Datasets
34
+ cli.say 'Archiving datasets'
35
+ each_file_listed(ds) do |rel_path, abs_path|
36
+ add_file_to_tar(tar, rel_path, abs_path)
37
+ end
38
+
39
+ # Project
40
+ cli.say 'Archiving project'
41
+ pmd = cli.load_project.metadata.dup
42
+ pmd[:datasets] = ds.map(&:name)
43
+ add_string_to_tar(tar, 'miga.project.json', pmd.to_json)
44
+ add_string_to_tar(tar, 'daemon/daemon.json', '{}')
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def open_tarball(&blk)
51
+ File.open(cli[:tarball], 'wb') do |fh|
52
+ Zlib::GzipWriter.wrap(fh) do |gz|
53
+ Gem::Package::TarWriter.new(gz) do |tar|
54
+ blk.call(tar)
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ def each_file_listed(datasets, &blk)
61
+ datasets.each_with_index do |ds, k|
62
+ cli.advance('Datasets:', k + 1, datasets.size, false)
63
+ # Metadata
64
+ blk.call(
65
+ File.join('metadata', File.basename(ds.metadata.path)),
66
+ ds.metadata.path
67
+ )
68
+ # Results
69
+ ds.each_result do |sym, res|
70
+ res.each_file do |_sym, rel_path, abs_path|
71
+ blk.call(File.join(res.relative_dir, rel_path), abs_path)
72
+ end
73
+ blk.call(res.relative_path, res.path) # <- JSON
74
+ end
75
+ end
76
+ cli.say
77
+ end
78
+
79
+ def add_file_to_tar(tar, rel_path, abs_path)
80
+ if File.directory? abs_path
81
+ Dir["#{abs_path}/*"].each do |f|
82
+ add_file_to_tar(tar, File.join(rel_path, File.basename(f)), f)
83
+ end
84
+ else
85
+ in_tar = File.join(cli[:folder], rel_path)
86
+ tar.add_file_simple(in_tar, 0666, File.size(abs_path)) do |ofh|
87
+ File.open(abs_path, 'rb') do |ifh|
88
+ ofh.write(ifh.read(1024)) until ifh.eof?
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ def add_string_to_tar(tar, rel_path, string)
95
+ in_tar = File.join(cli[:folder], rel_path)
96
+ tar.add_file_simple(in_tar, 0666, string.size) { |fh| fh.write(string) }
97
+ end
98
+
99
+ end
data/lib/miga/cli/base.rb CHANGED
@@ -24,6 +24,7 @@ module MiGA::Cli::Base
24
24
  find: 'Finds unregistered datasets based on result files',
25
25
  ln: 'Link datasets (including results) from one project to another',
26
26
  ls: 'Lists all registered datasets in an MiGA project',
27
+ archive: 'Generates a tar-ball with all files from select datasets',
27
28
  # Results
28
29
  add_result: 'Registers a result',
29
30
  stats: 'Extracts statistics for the given result',
data/lib/miga/cli.rb CHANGED
@@ -119,7 +119,7 @@ class MiGA::Cli < MiGA::MiGA
119
119
  def advance(step, n = 0, total = nil, bin = true)
120
120
  return unless self[:verbose]
121
121
  adv = total.nil? ? (n == 0 ? '' : num_suffix(n, bin)) :
122
- ('%.1f%% (%s/%s)' % [100 * n / total,
122
+ ('%.1f%% (%s/%s)' % [100.0 * n / total,
123
123
  num_suffix(n, bin), num_suffix(total, bin)])
124
124
  $stderr.print("[%s] %s %s \r" % [Time.now, step, adv])
125
125
  end
@@ -39,6 +39,7 @@ module MiGA::Dataset::Hooks
39
39
  metadata.data.keys
40
40
  .select { |k| k.to_s =~ /^_try_/ }
41
41
  .each { |k| metadata[k] = nil }
42
+ metadata[:_step] = nil
42
43
  save
43
44
  end
44
45
 
data/lib/miga/metadata.rb CHANGED
@@ -22,18 +22,18 @@ class MiGA::Metadata < MiGA::MiGA
22
22
  # Instance-level
23
23
 
24
24
  ##
25
- # Path to the JSON file describing the metadata.
25
+ # Path to the JSON file describing the metadata
26
26
  attr_reader :path
27
27
 
28
28
  ##
29
- # Initiate a MiGA::Metadata object with description in +path+. It will create
30
- # it if it doesn't exist.
31
- def initialize(path, defaults={})
29
+ # Initiate a MiGA::Metadata object with description in +path+.
30
+ # It will create it if it doesn't exist
31
+ def initialize(path, defaults = {})
32
32
  @data = nil
33
33
  @path = File.absolute_path(path)
34
34
  unless File.exist? path
35
35
  @data = {}
36
- defaults.each_pair{ |k,v| self[k]=v }
36
+ defaults.each { |k,v| self[k] = v }
37
37
  create
38
38
  end
39
39
  end
@@ -57,10 +57,11 @@ class MiGA::Metadata < MiGA::MiGA
57
57
  def save
58
58
  MiGA.DEBUG "Metadata.save #{path}"
59
59
  self[:updated] = Time.now.to_s
60
- json = MiGA::Json.generate(data)
60
+ json = to_json
61
61
  sleeper = 0.0
62
62
  slept = 0
63
63
  while File.exist?(lock_file)
64
+ MiGA::MiGA.DEBUG "Waiting for lock: #{lock_file}"
64
65
  sleeper += 0.1 if sleeper <= 10.0
65
66
  sleep(sleeper.to_i)
66
67
  slept += sleeper.to_i
@@ -70,7 +71,7 @@ class MiGA::Metadata < MiGA::MiGA
70
71
  ofh = File.open("#{path}.tmp", 'w')
71
72
  ofh.puts json
72
73
  ofh.close
73
- raise "Lock-racing detected for #{path}." unless
74
+ raise "Lock-racing detected for #{path}" unless
74
75
  File.exist?("#{path}.tmp") and File.exist?(lock_file)
75
76
  File.rename("#{path}.tmp", path)
76
77
  File.unlink(lock_file)
@@ -122,4 +123,10 @@ class MiGA::Metadata < MiGA::MiGA
122
123
  # Iterate +blk+ for each data with 2 arguments key and value.
123
124
  def each(&blk) data.each{ |k,v| blk.call(k,v) } ; end
124
125
 
126
+ ##
127
+ # Show contents in JSON format as a String
128
+ def to_json
129
+ MiGA::Json.generate(data)
130
+ end
131
+
125
132
  end
@@ -18,14 +18,21 @@ module MiGA::Result::Source
18
18
  ##
19
19
  # Detect the result key assigned to this result
20
20
  def key
21
- @key ||= MiGA::Result.RESULT_DIRS.find { |k, v| v == relative_dir }.first
21
+ @key ||= MiGA::Result.RESULT_DIRS.find do |k, v|
22
+ "data/#{v}" == relative_dir
23
+ end.first
22
24
  end
23
25
 
24
26
  ##
25
- # Path of the result containing the directory relative to the +data+ folder in
26
- # the parent project
27
+ # Path of the result containing the directory relative to the parent project
27
28
  def relative_dir
28
- @relative_dir ||= dir.sub("#{project_path}data/", '')
29
+ @relative_dir ||= dir.sub("#{project_path}/", '')
30
+ end
31
+
32
+ ##
33
+ # Path of the result's JSON definition relative to the parent project
34
+ def relative_path
35
+ @relative_path ||= path.sub("#{project_path}/", '')
29
36
  end
30
37
 
31
38
  ##
@@ -40,7 +47,7 @@ module MiGA::Result::Source
40
47
  # so the path referencing is identical to that of +self.path+ whenever they
41
48
  # need to be compared.
42
49
  def project_path
43
- path[ 0 .. path.rindex('/data/') ]
50
+ path[ 0 .. path.rindex('/data/') - 1 ]
44
51
  end
45
52
  end
46
53
 
data/lib/miga/version.rb CHANGED
@@ -10,7 +10,7 @@ module MiGA
10
10
  # - Float representing the major.minor version.
11
11
  # - Integer representing gem releases of the current version.
12
12
  # - Integer representing minor changes that require new version number.
13
- VERSION = [0.6, 0, 0]
13
+ VERSION = [0.6, 1, 0]
14
14
 
15
15
  ##
16
16
  # Nickname for the current major.minor version.
@@ -18,7 +18,7 @@ module MiGA
18
18
 
19
19
  ##
20
20
  # Date of the current gem release.
21
- VERSION_DATE = Date.new(2020, 3, 7)
21
+ VERSION_DATE = Date.new(2020, 3, 10)
22
22
 
23
23
  ##
24
24
  # Reference of MiGA.
data/test/common_test.rb CHANGED
@@ -1,7 +1,7 @@
1
- require "test_helper"
1
+ require 'test_helper'
2
2
 
3
3
  class CommonTest < Test::Unit::TestCase
4
-
4
+
5
5
  def setup
6
6
  #$jruby_tests = !ENV["JRUBY_TESTS"].nil?
7
7
  end
@@ -12,14 +12,14 @@ class CommonTest < Test::Unit::TestCase
12
12
  assert_respond_to(MiGA::MiGA, :DEBUG_OFF)
13
13
  MiGA::MiGA.DEBUG_ON
14
14
  err = capture_stderr do
15
- MiGA::MiGA.DEBUG "Tralari"
15
+ MiGA::MiGA.DEBUG 'Tralari'
16
16
  end
17
17
  assert_equal("Tralari\n", err.string)
18
18
  MiGA::MiGA.DEBUG_OFF
19
19
  err = capture_stderr do
20
- MiGA::MiGA.DEBUG "Tralara"
20
+ MiGA::MiGA.DEBUG 'Tralara'
21
21
  end
22
- assert_equal("", err.string)
22
+ assert_equal('', err.string)
23
23
  ensure
24
24
  MiGA::MiGA.DEBUG_OFF
25
25
  end
@@ -31,12 +31,12 @@ class CommonTest < Test::Unit::TestCase
31
31
  #omit_if($jruby_tests, "JRuby doesn't like interceptions.")
32
32
  MiGA::MiGA.DEBUG_TRACE_ON
33
33
  err = capture_stderr do
34
- MiGA::MiGA.DEBUG "Dandadi"
34
+ MiGA::MiGA.DEBUG 'Dandadi'
35
35
  end
36
36
  assert(err.string =~ /Dandadi\n .*block in test_debug_trace/)
37
37
  MiGA::MiGA.DEBUG_TRACE_OFF
38
38
  err = capture_stderr do
39
- MiGA::MiGA.DEBUG "Dandada"
39
+ MiGA::MiGA.DEBUG 'Dandada'
40
40
  end
41
41
  assert_equal("Dandada\n", err.string)
42
42
  ensure
@@ -46,37 +46,37 @@ class CommonTest < Test::Unit::TestCase
46
46
 
47
47
  def test_generic_transfer
48
48
  $tmp = Dir.mktmpdir
49
- hello = File.expand_path("Hello", $tmp)
50
- world = File.expand_path("World", $tmp)
49
+ hello = File.expand_path('Hello', $tmp)
50
+ world = File.expand_path('World', $tmp)
51
51
  assert_respond_to(File, :generic_transfer)
52
52
  FileUtils.touch(hello)
53
53
  File.generic_transfer(hello, world, :symlink)
54
- assert_equal("link", File.ftype(world), "World should be a link.")
54
+ assert_equal('link', File.ftype(world), 'World should be a link.')
55
55
  File.generic_transfer(hello, world, :copy)
56
- assert_equal("link", File.ftype(world), "World should still be a link.")
56
+ assert_equal('link', File.ftype(world), 'World should still be a link.')
57
57
  File.unlink world
58
58
  File.generic_transfer(hello, world, :hardlink)
59
- assert_equal("file", File.ftype(world), "A hardlink should be a file.")
60
- File.open(hello, "w"){ |fh| fh.print "!" }
61
- File.open(world, "r"){ |fh| assert_equal("!", fh.gets) }
59
+ assert_equal('file', File.ftype(world), 'A hardlink should be a file.')
60
+ File.open(hello, 'w') { |fh| fh.print '!' }
61
+ File.open(world, 'r') { |fh| assert_equal('!', fh.gets) }
62
62
  File.unlink world
63
63
  File.generic_transfer(hello, world, :copy)
64
- assert_equal("file", File.ftype(world), "A copy should be a file.")
64
+ assert_equal('file', File.ftype(world), 'A copy should be a file.')
65
65
  File.unlink world
66
66
  assert_raise do
67
67
  File.generic_transfer(hello, world, :monkey)
68
68
  end
69
- assert(!File.exist?(world), "A monkey shouldn't create files.")
69
+ assert(!File.exist?(world), 'A monkey shouldn\'t create files.')
70
70
  ensure
71
71
  FileUtils.rm_rf $tmp
72
72
  end
73
73
 
74
74
  def test_tabulate
75
75
  tab = MiGA::MiGA.tabulate(%w[a b], [%w[123 45], %w[678 90]])
76
- assert_equal(" a b ", tab[0])
77
- assert_equal(" - - ", tab[1])
78
- assert_equal("123 45", tab[2])
79
- assert_equal("678 90", tab[3])
76
+ assert_equal(' a b ', tab[0])
77
+ assert_equal(' - - ', tab[1])
78
+ assert_equal('123 45', tab[2])
79
+ assert_equal('678 90', tab[3])
80
80
  end
81
81
 
82
82
  def test_miga_name
data/test/daemon_test.rb CHANGED
@@ -1,29 +1,29 @@
1
- require "test_helper"
2
- require "miga/daemon"
1
+ require 'test_helper'
2
+ require 'miga/daemon'
3
3
 
4
4
  class DaemonTest < Test::Unit::TestCase
5
-
5
+
6
6
  def setup
7
- $jruby_tests = !ENV["JRUBY_TESTS"].nil?
7
+ $jruby_tests = !ENV['JRUBY_TESTS'].nil?
8
8
  $tmp = Dir.mktmpdir
9
- ENV["MIGA_HOME"] = $tmp
10
- FileUtils.touch("#{ENV["MIGA_HOME"]}/.miga_rc")
11
- File.open("#{ENV["MIGA_HOME"]}/.miga_daemon.json", "w") do |fh|
9
+ ENV['MIGA_HOME'] = $tmp
10
+ FileUtils.touch(File.expand_path('.miga_rc', ENV['MIGA_HOME']))
11
+ daemon_json = File.expand_path('.miga_daemon.json', ENV['MIGA_HOME'])
12
+ File.open(daemon_json, 'w') do |fh|
12
13
  fh.puts '{"maxjobs":1,"ppn":1,"latency":2,"varsep":" ",
13
14
  "var":"{{key}}={{value}}","cmd":"{{task_name}}",
14
15
  "alive":"echo 1 # {{pid}}","type":"bash","format_version":1}'
15
16
  end
16
- $p1 = MiGA::Project.new(File.expand_path("project1", $tmp))
17
+ $p1 = MiGA::Project.new(File.expand_path('project1', $tmp))
17
18
  $d1 = MiGA::Daemon.new($p1)
18
19
  end
19
20
 
20
21
  def teardown
21
22
  FileUtils.rm_rf $tmp
22
- ENV["MIGA_HOME"] = nil
23
+ ENV['MIGA_HOME'] = nil
23
24
  end
24
25
 
25
26
  def test_check_project
26
-
27
27
  end
28
28
 
29
29
  def test_check_datasets
@@ -31,20 +31,24 @@ class DaemonTest < Test::Unit::TestCase
31
31
  d = $d1
32
32
  d.runopts(:maxjobs, 0, true)
33
33
  assert(d.jobs_to_run.empty?)
34
- ds = p.add_dataset("ds1")
34
+ ds = p.add_dataset('ds1')
35
35
  d.check_datasets
36
36
  assert(d.jobs_to_run.empty?)
37
- FileUtils.cp(File.expand_path("daemon/daemon.json", p.path),
38
- File.expand_path("data/01.raw_reads/ds1.1.fastq", p.path))
39
- FileUtils.cp(File.expand_path("daemon/daemon.json", p.path),
40
- File.expand_path("data/01.raw_reads/ds1.done", p.path))
37
+ FileUtils.cp(
38
+ File.expand_path('daemon/daemon.json', p.path),
39
+ File.expand_path('data/01.raw_reads/ds1.1.fastq', p.path)
40
+ )
41
+ FileUtils.cp(
42
+ File.expand_path('daemon/daemon.json', p.path),
43
+ File.expand_path('data/01.raw_reads/ds1.done', p.path)
44
+ )
41
45
  ds.first_preprocessing(true)
42
46
  out = capture_stdout do
43
47
  d.check_datasets
44
48
  end
45
49
  assert(out.string =~ /Queueing #{ds.name}:d/)
46
50
  assert_equal(1, d.jobs_to_run.size)
47
- assert_equal("project1:d:ds1", d.jobs_to_run.first[:cmd])
51
+ assert_equal('project1:d:ds1', d.jobs_to_run.first[:cmd])
48
52
  assert_equal(d.jobs_to_run.first, d.get_job(:d, ds))
49
53
  end
50
54
 
@@ -54,16 +58,12 @@ class DaemonTest < Test::Unit::TestCase
54
58
  d.runopts(:latency, 0, true)
55
59
  assert_equal(-1, d.loop_i)
56
60
  assert_nil(d.last_alive)
57
- out = capture_stdout do
58
- d.in_loop
59
- end
61
+ out = capture_stdout { d.in_loop }
60
62
  assert_equal(Time, d.last_alive.class)
61
63
  assert(out.string =~ /-{20}\n.*MiGA:#{p.name} launched/)
62
64
  10.times{ d.in_loop }
63
65
  assert_equal(11, d.loop_i)
64
- out = capture_stdout do
65
- d.in_loop
66
- end
66
+ out = capture_stdout { d.in_loop }
67
67
  assert(out.string =~ /Probing running jobs/)
68
68
  assert_equal(0, d.loop_i)
69
69
  end
@@ -73,8 +73,8 @@ class DaemonTest < Test::Unit::TestCase
73
73
  d = $d1
74
74
  d.runopts(:latency, 0, true)
75
75
  assert_equal(0, d.latency)
76
- omit_if($jruby_tests, "JRuby doesn't implement fork.")
77
- $child = fork { d.start(["--shush"]) }
76
+ omit_if($jruby_tests, 'JRuby doesn\'t implement fork.')
77
+ $child = fork { d.start(['--shush']) }
78
78
  sleep(3)
79
79
  dpath = File.expand_path("daemon/MiGA:#{p.name}",p.path)
80
80
  assert(File.exist?("#{dpath}.pid"))
@@ -90,11 +90,11 @@ class DaemonTest < Test::Unit::TestCase
90
90
  assert(l[3] =~ /Probing running jobs\n/)
91
91
  end
92
92
  ensure
93
- Process.kill("KILL", $child) unless $child.nil?
93
+ Process.kill('KILL', $child) unless $child.nil?
94
94
  end
95
95
 
96
96
  def test_last_alive
97
- p = MiGA::Project.new(File.expand_path("last_alive", $tmp))
97
+ p = MiGA::Project.new(File.expand_path('last_alive', $tmp))
98
98
  d = MiGA::Daemon.new(p)
99
99
  assert_nil(d.last_alive)
100
100
  d.declare_alive
@@ -110,18 +110,14 @@ class DaemonTest < Test::Unit::TestCase
110
110
  assert_equal(1, $d1.ppn)
111
111
  $d1.runopts(:alo, :ha)
112
112
  assert_equal(:ha, $d1.runopts(:alo))
113
- $d1.runopts(:maxjobs, "1")
113
+ $d1.runopts(:maxjobs, '1')
114
114
  assert_equal(1, $d1.maxjobs)
115
- assert_raise do
116
- $d1.runopts(:latency, "!")
117
- end
118
- assert_equal("bash", $d1.runopts(:type))
115
+ assert_raise { $d1.runopts(:latency, '!') }
116
+ assert_equal('bash', $d1.runopts(:type))
119
117
  end
120
118
 
121
119
  def test_say
122
- out = capture_stdout do
123
- $d1.say "Olm"
124
- end
120
+ out = capture_stdout { $d1.say 'Olm' }
125
121
  assert(out.string =~ /^\[.*\] Olm/)
126
122
  end
127
123
 
@@ -129,9 +125,7 @@ class DaemonTest < Test::Unit::TestCase
129
125
  d = $d1
130
126
  d.declare_alive
131
127
  assert_not_nil(d.last_alive)
132
- out = capture_stdout do
133
- d.terminate
134
- end
128
+ out = capture_stdout { d.terminate }
135
129
  assert(out.string =~ /Terminating daemon/)
136
130
  assert_nil(d.last_alive)
137
131
  end