themigrator 0.1.12 → 0.1.14

Sign up to get free protection for your applications and to get access to all the features.
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