themigrator 0.1.12 → 0.1.14

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
  SHA1:
3
- metadata.gz: c881ca29c75388a9cb240c301e340245c1d9ae6f
4
- data.tar.gz: b6d56b409c7e265b6cc5f425c1bdccb3cb2fdccd
3
+ metadata.gz: 6188fef0eab108a19c231eac874aaa8f0fa50fd1
4
+ data.tar.gz: ae45a477ef136e1641f34a15d9f84304026e8e11
5
5
  SHA512:
6
- metadata.gz: e2a3ecfcefedd3315e8b81624a5004c5989c468e94986350036292b14e80097ec93ea56d512ee5ae19d58b863add06d4f5547da3f6779776303c7223ce09b83f
7
- data.tar.gz: 71d2296919a8e7d1b07f17666fd9cbbbc62442247ff161a8a67ea51637fe1ef4cc5ad4e44b425c7f027c3a8280e1bc98938cfc56c750031166988f4c4e71b384
6
+ metadata.gz: 225f6f0eeb58ab239c4fadd552c29ce31297d54f23c83b7b94a3254a292fde2b31e25d9376e7059ff83974792efc55e6ded1bd59b36935d0dfc144d7d607d15b
7
+ data.tar.gz: 76a90c14c5ef81e56b56afc963c7de373d5f2f4697a1de2e58c84ad767341f392d158056d7add2026ed7b501a91ba7004924aa50767b430d935136539ca17765
data/.gitignore CHANGED
@@ -9,3 +9,4 @@
9
9
  /tmp/
10
10
  test/fixtures/sample_project/logs/
11
11
  .byebug_history
12
+ tags
data/Rakefile CHANGED
@@ -1,10 +1,10 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
3
 
4
4
  Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
5
+ t.libs << 'test'
6
+ t.libs << 'lib'
7
7
  t.test_files = FileList['test/**/*_test.rb']
8
8
  end
9
9
 
10
- task :default => :test
10
+ task default: :test
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "themigrator"
3
+ require 'bundler/setup'
4
+ require 'themigrator'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "themigrator"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start
data/bin/testui ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'themigrator'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'themigrator/ui'
14
+ require 'ostruct'
15
+
16
+ i = Themigrator::UI.new(OpenStruct.new(roles: %w(mariadb riak app), run_id: 'asdf'))
17
+
18
+ i.init_ui
19
+ i.render
20
+ sleep 2
data/exe/themigrator CHANGED
@@ -1,10 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "themigrator/cli"
3
+ require 'themigrator/cli'
4
4
 
5
5
  Themigrator::CLI.start(ARGV)
6
-
7
-
8
-
9
-
10
-
data/how_to_run_it ADDED
@@ -0,0 +1 @@
1
+ ruby -I ../themigrator/lib -r themigrator ../themigrator/exe/themigrator visualize 2016-09-01-15:46:24
@@ -1,42 +1,37 @@
1
1
  require 'thor'
2
2
  require 'themigrator'
3
3
 
4
-
5
4
  module Themigrator
6
5
  class CLI < Thor
7
-
8
- desc "migrate", "Migrate the current project"
9
- option :roles, desc: "list of roles. By default all."
6
+ desc 'migrate', 'Migrate the current project'
7
+ option :roles, desc: 'list of roles. By default all.'
10
8
  option :background, default: true, type: :boolean, desc: "Don't move the migrator to the background"
11
9
  def migrate
12
10
  migrator_opts = {}
13
- if options[:roles]
14
- migrator_opts[:roles] = options[:roles].split(",")
15
- end
11
+ migrator_opts[:roles] = options[:roles].split(',') if options[:roles]
12
+ migrator_opts[:log_stdout] = true unless options[:background]
16
13
  migrator = Themigrator::Migrator.new(Dir.pwd, migrator_opts)
17
14
 
18
- if !options[:background]
19
- exit migrator.migrate! ? 0 : -1
20
- end
15
+ exit migrator.migrate! ? 0 : -1 unless options[:background]
21
16
 
22
- pid = fork do
23
- exit migrator.migrate! ? 0 : -1
17
+ pid = fork do
18
+ exit migrator.migrate! ? 0 : -1
24
19
  end
25
20
  Process.detach(pid)
26
21
  log_file = migrator.main_log_path(Dir.pwd, migrator.run_id)
27
22
  sleep 0.1
28
- system("tail --pid=#{pid} --lines=+0 --follow #{log_file}")
29
- #system("#{$0} visualize #{migrator.run_id}")
23
+ # system("tail --pid=#{pid} --lines=+0 --follow #{log_file}")
24
+ system("#{$PROGRAM_NAME} visualize #{migrator.run_id}")
30
25
  end
31
26
 
32
- desc "roles", "show the list of roles"
27
+ desc 'roles', 'show the list of roles'
33
28
  def roles
34
29
  migration = Themigrator::Migration.new(Dir.pwd)
35
30
  migration.analyze_project!
36
31
  puts migration.roles.join("\n")
37
32
  end
38
33
 
39
- desc "visualize RUNID", "visualize a migration"
34
+ desc 'visualize RUNID', 'visualize a migration'
40
35
  def visualize(run_id)
41
36
  mp = Themigrator::MigrationProgress.new(Dir.pwd, run_id)
42
37
  ui = Themigrator::UI.new(mp)
@@ -3,8 +3,7 @@ require 'logger'
3
3
 
4
4
  module Themigrator
5
5
  module Logger
6
-
7
- MAINLOGFILE = "themigrator.log"
6
+ MAINLOGFILE = 'themigrator.log'.freeze
8
7
  include FileUtils
9
8
 
10
9
  def log(msg)
@@ -13,9 +12,9 @@ module Themigrator
13
12
 
14
13
  def init_logger(log_file)
15
14
  @logger = ::Logger.new(log_file)
16
- @logger.formatter = proc do |severity, datetime, progname, msg|
17
- t = datetime.strftime('%Y-%m-%d %H:%M:%S')
18
- "#{t}: #{msg}\n"
15
+ @logger.formatter = proc do |_severity, datetime, _progname, msg|
16
+ t = datetime.strftime('%Y-%m-%d %H:%M:%S')
17
+ "#{t}: #{msg}\n"
19
18
  end
20
19
  end
21
20
 
@@ -30,20 +29,19 @@ module Themigrator
30
29
  def main_log_path(base_dir, run_id)
31
30
  filename = MAINLOGFILE
32
31
  directory = log_dir(base_dir, run_id)
33
- File.join(directory,filename)
32
+ File.join(directory, filename)
34
33
  end
35
34
 
36
35
  def log_path(base_dir, run_id, role, action)
37
36
  filename = "#{role}-#{action}.log"
38
37
  directory = log_dir(base_dir, run_id)
39
- File.join(directory,filename)
38
+ File.join(directory, filename)
40
39
  end
41
40
 
42
41
  def log_dir(base_dir, run_id)
43
- dir = File.join(base_dir,"logs",run_id)
44
- mkdir_p(dir, mode: 0700)
42
+ dir = File.join(base_dir, 'logs', run_id)
43
+ mkdir_p(dir, mode: 0o700)
45
44
  dir
46
45
  end
47
-
48
46
  end
49
47
  end
@@ -1,18 +1,16 @@
1
1
  require 'set'
2
2
 
3
3
  module Themigrator
4
-
5
4
  # Holds the plan of the migration
6
5
  class Migration
7
-
8
- ACTIONS = %w(setup pre-migrate migrate post-migrate cleanup)
6
+ ACTIONS = %w(setup pre-migrate migrate post-migrate cleanup).freeze
9
7
  SCRIPTS = ACTIONS | %w(rollback)
10
8
 
11
9
  attr_reader :roles, :actions
12
10
 
13
11
  def initialize(dir, options = {})
14
12
  @dir = dir
15
- @action_and_roles = Hash.new{|hash,key| hash[key] = [] }
13
+ @action_and_roles = Hash.new { |hash, key| hash[key] = [] }
16
14
  @roles = []
17
15
  @user_roles = options[:roles] || []
18
16
  @actions = []
@@ -23,28 +21,24 @@ module Themigrator
23
21
  used_actions = [] # Should be in order
24
22
 
25
23
  SCRIPTS.each do |action|
26
- path_match = File.join(@dir,"*/#{action}")
27
- Dir[path_match].select { |f|
28
- File.executable?(f)
29
- }.each {|f|
30
- role = File.basename(File.dirname(f))
31
- if @user_roles.none? || @user_roles.include?(role)
32
- roles.add(role)
33
- used_actions << action
34
- @action_and_roles[action] << role
35
- end
36
-
37
- }
38
-
24
+ path_match = File.join(@dir, "*/#{action}")
25
+ Dir[path_match].select do |f|
26
+ File.executable?(f)
27
+ end.each do |f|
28
+ role = File.basename(File.dirname(f))
29
+ next unless @user_roles.none? || @user_roles.include?(role)
30
+ roles.add(role)
31
+ used_actions << action
32
+ @action_and_roles[action] << role
33
+ end
39
34
  end
40
35
  @roles = roles.to_a.sort
41
36
  @actions = used_actions.uniq
42
- @actions.delete("rollback")
37
+ @actions.delete('rollback')
43
38
  end
44
39
 
45
40
  def roles_for_action(action)
46
41
  @action_and_roles[action]
47
42
  end
48
-
49
43
  end
50
44
  end
@@ -8,12 +8,10 @@ module Themigrator
8
8
 
9
9
  attr_reader :roles, :run_id, :start_time, :pid, :status, :current_action, :actions
10
10
 
11
- def cbks=(a)
12
- @cbks=a
13
- end
11
+ attr_writer :cbks
14
12
 
15
13
  # cbks
16
- #
14
+
17
15
  # :has_roles
18
16
  # :start_action
19
17
  # :start_role_action
@@ -22,25 +20,25 @@ module Themigrator
22
20
  # :start_migration
23
21
  # :end_migration
24
22
  #
25
-
26
-
27
- def initialize(dir, run_id)
28
- @dir, @run_id = dir, run_id
23
+
24
+ def initialize(dir, run_id)
25
+ @dir = dir
26
+ @run_id = run_id
29
27
  @log_file_path = main_log_path(dir, run_id)
30
28
  @roles = []
31
29
  @current_action = nil
32
30
  @cbks = {}
33
- @actions = Hash.new do |h,k|
34
- h[k] = {
35
- start_time: nil,
36
- roles: Hash.new {|rh,rk| rh[rk] = {} },
37
- end_time: nil}
31
+ @actions = Hash.new do |h, k|
32
+ h[k] = {
33
+ start_time: nil,
34
+ roles: Hash.new { |rh, rk| rh[rk] = {} },
35
+ end_time: nil
36
+ }
38
37
  end
39
-
40
38
  end
41
39
 
42
- def log_file(role,action)
43
- log_path(@dir,@run_id,role,action)
40
+ def log_file(role, action)
41
+ log_path(@dir, @run_id, role, action)
44
42
  end
45
43
 
46
44
  def start
@@ -50,91 +48,103 @@ module Themigrator
50
48
  private
51
49
 
52
50
  def start_log_parser
53
- IO.foreach(@log_file_path) do |line|
54
- process_line(line)
51
+ @buffer = ''
52
+ File.open(@log_file_path, 'r') do |f|
53
+ loop do
54
+ @buffer += f.read
55
+ @buffer = each_line(@buffer) do |line|
56
+ process_line(line)
57
+ end
58
+ end
55
59
  end
56
- rescue EOFError
60
+ # rescue EOFError
57
61
  end
58
62
 
63
+ def each_line(line, &block)
64
+ i = line.index("\n")
65
+ return line if i.nil?
66
+
67
+ yield line[0..i]
68
+ each_line(line[i + 1..-1], &block)
69
+ end
59
70
 
60
71
  def call_cbk(name, *args)
61
72
  cbk = @cbks[name]
62
73
  cbk.call(*args) if cbk
63
74
  end
64
75
 
65
-
66
76
  def process_line(line)
67
77
  line.strip!
68
78
  case line
69
79
  when /^# Logfile created on ([0-9-]+) ([0-9:]+) /
70
- @start_time = Time.parse("#{$1} #{$2}")
80
+ @start_time = Time.parse("#{Regexp.last_match(1)} #{Regexp.last_match(2)}")
71
81
  else
72
- process_log_entry(line)
82
+ process_log_entry(line)
73
83
  end
74
84
  call_cbk(:new_line, line)
75
85
  end
76
86
 
77
87
  def process_log_entry(line)
78
88
  time, line = extract_time(line)
79
- scripts = Themigrator::Migration::SCRIPTS.join("|")
89
+ scripts = Themigrator::Migration::SCRIPTS.join('|')
80
90
  case line
81
91
  when /start PID=(\d+)/
82
- @pid = $1.to_i
92
+ @pid = Regexp.last_match(1).to_i
83
93
  when /roles: (.+)/
84
- @roles = $1.strip.split.sort
85
- call_cbk(:has_roles, @roles)
94
+ @roles = Regexp.last_match(1).strip.split.sort
95
+ call_cbk(:has_roles, @roles)
86
96
  when /(#{scripts}) => start/
87
- action = $1.to_sym
88
- @current_action = action
89
- @actions[action][:start_time] = time
90
- call_cbk(:start_action, action)
97
+ action = Regexp.last_match(1)
98
+ @current_action = action
99
+ @actions[action][:start_time] = time
100
+ call_cbk(:start_action, action)
91
101
 
92
102
  when /(#{scripts}) => (done|fail) \(([0-9\.]+) ms\)/
93
- action = $1.to_sym
94
- success = to_success($2)
95
- run_time = $3.to_f
103
+ action = Regexp.last_match(1)
104
+ success = to_success(Regexp.last_match(2))
105
+ run_time = Regexp.last_match(3).to_f
96
106
 
97
- @actions[action][:end_time] = time
98
- @actions[action][:run_time] = run_time
99
- @actions[action][:success] = success
100
- @current_action = nil
107
+ @actions[action][:end_time] = time
108
+ @actions[action][:run_time] = run_time
109
+ @actions[action][:success] = success
110
+ @current_action = nil
101
111
 
102
112
  when /(#{scripts}) \| (.*) => start/
103
- action = $1.to_sym
104
- role = $2
105
- @actions[action][:roles][role][:start_time] = time
113
+ action = Regexp.last_match(1)
114
+ role = Regexp.last_match(2)
115
+ @actions[action][:roles][role][:start_time] = time
116
+ call_cbk(:start_role_action, role, action)
106
117
  when /(#{scripts}) \| (.*) => exited with (\d+) \(([0-9\.]+) ms\)/
107
- action = $1.to_sym
108
- role = $2
109
- exitcode = $3.to_i
110
- success = exitcode == 0
111
- run_time = $4.to_f
112
- @actions[action][:roles][role][:end_time] = time
113
- @actions[action][:roles][role][:exitcode] = exitcode
114
- @actions[action][:roles][role][:success] = success
115
- @actions[action][:roles][role][:run_time] = run_time
118
+ action = Regexp.last_match(1)
119
+ role = Regexp.last_match(2)
120
+ exitcode = Regexp.last_match(3).to_i
121
+ success = exitcode.zero?
122
+ run_time = Regexp.last_match(4).to_f
123
+ @actions[action][:roles][role][:end_time] = time
124
+ @actions[action][:roles][role][:exitcode] = exitcode
125
+ @actions[action][:roles][role][:success] = success
126
+ @actions[action][:roles][role][:run_time] = run_time
116
127
  when /end => (done|fail) \(([0-9.]+) ms\)/
117
- @current_action = nil
118
- @run_time = $3.to_f
119
- else
120
- raise line.inspect
128
+ @current_action = nil
129
+ @run_time = Regexp.last_match(3).to_f
130
+ else
131
+ raise line.inspect
121
132
  end
122
133
  end
123
134
 
124
135
  def extract_time(line)
125
136
  line =~ /^([0-9-]+) ([0-9:]+) (.*)/
126
- time = Time.parse("#{$1} #{$2}")
127
- line = $3
128
- return time, line.strip
137
+ time = Time.parse("#{Regexp.last_match(1)} #{Regexp.last_match(2)}")
138
+ line = Regexp.last_match(3)
139
+ [time, line.strip]
129
140
  end
130
141
 
131
142
  def rollback?
132
- @actions.keys.include?("rollback")
143
+ @actions.keys.include?('rollback')
133
144
  end
134
145
 
135
146
  def to_success(val)
136
- val == "done" ? true : false
147
+ val == 'done' ? true : false
137
148
  end
138
-
139
149
  end
140
150
  end
@@ -2,7 +2,6 @@ require 'themigrator/logger'
2
2
  require 'themigrator/migration'
3
3
  require 'themigrator/script_pool'
4
4
 
5
-
6
5
  module Themigrator
7
6
  class Migrator
8
7
  include Logger
@@ -14,71 +13,68 @@ module Themigrator
14
13
  @dir = dir
15
14
  @runned_roles = []
16
15
  @start_time = Time.now
17
- @run_id = @start_time.strftime("%Y-%m-%d-%H:%M:%S")
16
+ @run_id = @start_time.strftime('%Y-%m-%d-%H:%M:%S')
18
17
  end
19
18
 
20
19
  def migrate!
21
20
  @migration = Migration.new(@dir, roles: @options[:roles])
22
21
  @migration.analyze_project!
23
22
 
24
- init_logger(main_log_path(@dir, run_id))
25
-
26
- log "start PID=#{$$}"
27
- log "roles: #{@migration.roles.join(" ")}"
23
+ init_logger(main_log_path(@dir, run_id)) unless @options[:log_stdout]
24
+
25
+ log "start PID=#{$PROCESS_ID}"
26
+ log "roles: #{@migration.roles.join(' ')}"
28
27
  did_it_work = true
29
28
  each_action do |action|
30
- if !run_action_and_wait(action)
31
- did_it_work = false
32
- run_action_and_wait("rollback")
33
- return -1
34
- end
29
+ next if run_action_and_wait(action)
30
+ did_it_work = false
31
+ run_action_and_wait('rollback')
32
+ return -1
35
33
  end
36
- close_logger
37
34
  did_it_work
38
35
  ensure
39
36
  @end_time = Time.now
40
- msg = did_it_work ? "done" : "fail"
37
+ msg = did_it_work ? 'done' : 'fail'
41
38
  log "end => #{msg} (#{run_time * 1000} ms)"
39
+ close_logger
42
40
  end
43
41
 
44
42
  private
45
43
 
46
44
  def each_action
47
45
  Migration::ACTIONS.each do |action|
48
- yield action
46
+ yield action
49
47
  end
50
48
  end
51
49
 
52
50
  def each_role(action)
53
51
  @migration.roles_for_action(action).each do |role|
54
- @runned_roles << role # To prevent calling rollback on roles that
55
- yield role
52
+ @runned_roles << role # To prevent calling rollback on roles that
53
+ yield role
56
54
  end
57
55
  @runned_roles.uniq!
58
56
  end
59
57
 
60
-
61
58
  def run_action_and_wait(action)
62
59
  log "#{action} => start"
63
60
  script_pool = ScriptPool.new
64
61
 
65
62
  each_role(action) do |role|
66
- next if role == "rollback" && !@runned_roles.include?(role)
67
-
68
- script_path = find_script(role, action)
69
- log_path = log_path(@dir,run_id,role, action)
63
+ next if role == 'rollback' && !@runned_roles.include?(role)
70
64
 
65
+ script_path = find_script(role, action)
66
+ log_path = log_path(@dir, run_id, role, action)
71
67
 
72
- log "#{action} | #{role} => start"
73
- script_pool.add_script(script_path,log_path, role: role, action: action) do |s|
74
- action = s.attr[:action]
75
- role = s.attr[:role]
76
- log "#{action} | #{role} => exited with #{s.exitcode} (#{s.run_time * 1000} ms)"
77
- end
68
+ log "#{action} | #{role} => start"
69
+ script_pool.add_script(script_path, log_path, role: role, action: action) do |s|
70
+ action = s.attr[:action]
71
+ role = s.attr[:role]
72
+ log "#{action} | #{role} => exited with #{s.exitcode} (#{s.run_time * 1000} ms)"
73
+ end
78
74
  end
79
75
 
80
76
  ok = script_pool.run_and_wait
81
- log("#{action} => #{ok ? "done" : "fail"} (#{script_pool.run_time*1000} ms)")
77
+ log("#{action} => #{ok ? 'done' : 'fail'} (#{script_pool.run_time * 1000} ms)")
82
78
  ok
83
79
  end
84
80
 
@@ -90,5 +86,4 @@ module Themigrator
90
86
  @end_time - @start_time if @end_time
91
87
  end
92
88
  end
93
-
94
89
  end
@@ -0,0 +1,20 @@
1
+
2
+ module Themigrator
3
+ class UI
4
+ module ProgressWindow
5
+ def render_progress
6
+ progress_window.setpos(0, 0)
7
+ progress_window.addstr(@pm.roles.inspect)
8
+ progress_window.addstr(@pm.current_action.inspect)
9
+ progress_window.addstr(@action)
10
+ progress_window.refresh
11
+ end
12
+
13
+ def progress_window
14
+ @progress_widnow ||= Window.new(@lines - 1, @cols - 1, @lines - 1, 0).tap do |w|
15
+ w.attrset(A_DIM)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end