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 +4 -4
- data/.gitignore +1 -0
- data/Rakefile +5 -5
- data/bin/console +3 -3
- data/bin/testui +20 -0
- data/exe/themigrator +1 -6
- data/how_to_run_it +1 -0
- data/lib/themigrator/cli.rb +11 -16
- data/lib/themigrator/logger.rb +8 -10
- data/lib/themigrator/migration.rb +13 -19
- data/lib/themigrator/migration_progress.rb +69 -59
- data/lib/themigrator/migrator.rb +24 -29
- data/lib/themigrator/progress_window.rb +20 -0
- data/lib/themigrator/script.rb +29 -32
- data/lib/themigrator/script_pool.rb +18 -22
- data/lib/themigrator/ui/getchar.rb +40 -0
- data/lib/themigrator/ui/log_area.rb +173 -0
- data/lib/themigrator/ui/progress_window.rb +52 -0
- data/lib/themigrator/ui/title_bar.rb +31 -0
- data/lib/themigrator/ui.rb +128 -118
- data/lib/themigrator/version.rb +1 -1
- data/lib/themigrator.rb +8 -10
- data/themigrator.gemspec +15 -14
- metadata +23 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6188fef0eab108a19c231eac874aaa8f0fa50fd1
|
4
|
+
data.tar.gz: ae45a477ef136e1641f34a15d9f84304026e8e11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 225f6f0eeb58ab239c4fadd552c29ce31297d54f23c83b7b94a3254a292fde2b31e25d9376e7059ff83974792efc55e6ded1bd59b36935d0dfc144d7d607d15b
|
7
|
+
data.tar.gz: 76a90c14c5ef81e56b56afc963c7de373d5f2f4697a1de2e58c84ad767341f392d158056d7add2026ed7b501a91ba7004924aa50767b430d935136539ca17765
|
data/.gitignore
CHANGED
data/Rakefile
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
3
|
|
4
4
|
Rake::TestTask.new(:test) do |t|
|
5
|
-
t.libs <<
|
6
|
-
t.libs <<
|
5
|
+
t.libs << 'test'
|
6
|
+
t.libs << 'lib'
|
7
7
|
t.test_files = FileList['test/**/*_test.rb']
|
8
8
|
end
|
9
9
|
|
10
|
-
task :
|
10
|
+
task default: :test
|
data/bin/console
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
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
|
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
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
|
data/lib/themigrator/cli.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
19
|
-
exit migrator.migrate! ? 0 : -1
|
20
|
-
end
|
15
|
+
exit migrator.migrate! ? 0 : -1 unless options[:background]
|
21
16
|
|
22
|
-
pid = fork do
|
23
|
-
|
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
|
-
|
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
|
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
|
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)
|
data/lib/themigrator/logger.rb
CHANGED
@@ -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 |
|
17
|
-
|
18
|
-
|
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,
|
44
|
-
mkdir_p(dir, mode:
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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(
|
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
|
-
|
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
|
-
|
28
|
-
@
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
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
|
-
|
54
|
-
|
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
|
-
|
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
|
-
|
80
|
+
@start_time = Time.parse("#{Regexp.last_match(1)} #{Regexp.last_match(2)}")
|
71
81
|
else
|
72
|
-
|
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
|
-
|
92
|
+
@pid = Regexp.last_match(1).to_i
|
83
93
|
when /roles: (.+)/
|
84
|
-
|
85
|
-
|
94
|
+
@roles = Regexp.last_match(1).strip.split.sort
|
95
|
+
call_cbk(:has_roles, @roles)
|
86
96
|
when /(#{scripts}) => start/
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|
-
|
94
|
-
|
95
|
-
|
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
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
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
|
-
|
104
|
-
|
105
|
-
|
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
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
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
|
-
|
118
|
-
|
119
|
-
else
|
120
|
-
|
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("#{
|
127
|
-
line =
|
128
|
-
|
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?(
|
143
|
+
@actions.keys.include?('rollback')
|
133
144
|
end
|
134
145
|
|
135
146
|
def to_success(val)
|
136
|
-
val ==
|
147
|
+
val == 'done' ? true : false
|
137
148
|
end
|
138
|
-
|
139
149
|
end
|
140
150
|
end
|
data/lib/themigrator/migrator.rb
CHANGED
@@ -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(
|
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
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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 ?
|
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
|
-
|
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
|
-
|
55
|
-
|
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
|
-
|
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
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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 ?
|
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
|