redmine-installer 1.0.7 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/.travis.yml +7 -0
- data/Gemfile +3 -15
- data/README.md +49 -177
- data/bin/redmine +4 -5
- data/lib/redmine-installer/backup.rb +13 -40
- data/lib/redmine-installer/cli.rb +92 -61
- data/lib/redmine-installer/command.rb +63 -117
- data/lib/redmine-installer/configuration.rb +148 -0
- data/lib/redmine-installer/database.rb +204 -0
- data/lib/redmine-installer/environment.rb +21 -0
- data/lib/redmine-installer/errors.rb +7 -0
- data/lib/redmine-installer/install.rb +37 -42
- data/lib/redmine-installer/logger.rb +83 -0
- data/lib/redmine-installer/package.rb +180 -0
- data/lib/redmine-installer/patches/ruby.rb +35 -0
- data/lib/redmine-installer/patches/tty.rb +16 -0
- data/lib/redmine-installer/profile.rb +24 -55
- data/lib/redmine-installer/redmine.rb +551 -0
- data/lib/redmine-installer/spec/spec.rb +81 -0
- data/lib/redmine-installer/task.rb +18 -77
- data/lib/redmine-installer/task_module.rb +12 -0
- data/lib/redmine-installer/upgrade.rb +51 -59
- data/lib/redmine-installer/utils.rb +46 -233
- data/lib/redmine-installer/version.rb +2 -4
- data/lib/redmine-installer.rb +69 -56
- data/redmine-installer.gemspec +20 -19
- data/spec/custom_matchers.rb +21 -0
- data/spec/installer_helper.rb +107 -0
- data/spec/installer_process.rb +82 -0
- data/spec/lib/backup_restore_spec.rb +81 -0
- data/spec/lib/install_spec.rb +125 -36
- data/spec/lib/upgrade_spec.rb +73 -52
- data/spec/packages/redmine-3.1.0.zip +0 -0
- data/spec/packages/redmine-3.2.0.zip +0 -0
- data/spec/packages/redmine-3.3.0-bad-migration.zip +0 -0
- data/spec/packages/redmine-3.3.0.zip +0 -0
- data/spec/packages/something-else.zip +0 -0
- data/spec/packages_helper.rb +19 -0
- data/spec/shared_contexts.rb +13 -0
- data/spec/spec_helper.rb +34 -18
- metadata +62 -63
- data/lib/redmine-installer/config_param.rb +0 -100
- data/lib/redmine-installer/error.rb +0 -5
- data/lib/redmine-installer/exec.rb +0 -158
- data/lib/redmine-installer/ext/module.rb +0 -7
- data/lib/redmine-installer/ext/string.rb +0 -15
- data/lib/redmine-installer/git.rb +0 -51
- data/lib/redmine-installer/helper.rb +0 -5
- data/lib/redmine-installer/helpers/generate_config.rb +0 -29
- data/lib/redmine-installer/locales/cs.yml +0 -147
- data/lib/redmine-installer/locales/en.yml +0 -154
- data/lib/redmine-installer/plugin.rb +0 -9
- data/lib/redmine-installer/plugins/base.rb +0 -24
- data/lib/redmine-installer/plugins/database.rb +0 -180
- data/lib/redmine-installer/plugins/email_sending.rb +0 -82
- data/lib/redmine-installer/plugins/redmine_plugin.rb +0 -82
- data/lib/redmine-installer/plugins/web_server.rb +0 -26
- data/lib/redmine-installer/step.rb +0 -16
- data/lib/redmine-installer/steps/backup.rb +0 -125
- data/lib/redmine-installer/steps/base.rb +0 -79
- data/lib/redmine-installer/steps/database_config.rb +0 -15
- data/lib/redmine-installer/steps/email_config.rb +0 -11
- data/lib/redmine-installer/steps/env_check.rb +0 -20
- data/lib/redmine-installer/steps/install.rb +0 -23
- data/lib/redmine-installer/steps/load_package.rb +0 -226
- data/lib/redmine-installer/steps/move_redmine.rb +0 -22
- data/lib/redmine-installer/steps/redmine_root.rb +0 -52
- data/lib/redmine-installer/steps/upgrade.rb +0 -57
- data/lib/redmine-installer/steps/validation.rb +0 -38
- data/lib/redmine-installer/steps/webserver_config.rb +0 -22
- data/spec/load_redmine.rb +0 -24
@@ -0,0 +1,81 @@
|
|
1
|
+
# $stdin.sync = true
|
2
|
+
# $stdout.sync = true
|
3
|
+
|
4
|
+
# # require 'redmine-installer/spec/cursor'
|
5
|
+
|
6
|
+
# class TestPrompt < TTY::Prompt
|
7
|
+
|
8
|
+
# def initialize(*args)
|
9
|
+
# # @input = StringIO.new
|
10
|
+
# # @output = StringIO.new
|
11
|
+
# # super(input: @input, output: @output)
|
12
|
+
# super
|
13
|
+
# @pastel = Pastel.new(enabled: false)
|
14
|
+
# end
|
15
|
+
|
16
|
+
# end
|
17
|
+
|
18
|
+
# module RedmineInstaller
|
19
|
+
|
20
|
+
# # def self.prompt
|
21
|
+
# # @prompt ||= TestPrompt.new
|
22
|
+
# # end
|
23
|
+
|
24
|
+
# def self.pastel
|
25
|
+
# @pastel ||= Pastel.new(enabled: false)
|
26
|
+
# end
|
27
|
+
|
28
|
+
# end
|
29
|
+
|
30
|
+
# module TTY
|
31
|
+
# module Cursor
|
32
|
+
|
33
|
+
# singleton_methods.each do |name|
|
34
|
+
# class_eval <<-METHODS
|
35
|
+
|
36
|
+
# def #{name}(*)
|
37
|
+
# ''
|
38
|
+
# end
|
39
|
+
|
40
|
+
# def self.#{name}(*)
|
41
|
+
# ''
|
42
|
+
# end
|
43
|
+
|
44
|
+
# METHODS
|
45
|
+
# end
|
46
|
+
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
|
50
|
+
$stdin.sync = true
|
51
|
+
$stdout.sync = true
|
52
|
+
|
53
|
+
module TTY::Cursor
|
54
|
+
|
55
|
+
singleton_methods.each do |name|
|
56
|
+
class_eval <<-METHODS
|
57
|
+
|
58
|
+
def #{name}(*)
|
59
|
+
''
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.#{name}(*)
|
63
|
+
''
|
64
|
+
end
|
65
|
+
|
66
|
+
METHODS
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
class TestPrompt < TTY::Prompt
|
72
|
+
|
73
|
+
def initialize(*args)
|
74
|
+
super
|
75
|
+
@pastel = Pastel.new(enabled: false)
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
RedmineInstaller.instance_variable_set(:@prompt, TestPrompt.new)
|
81
|
+
RedmineInstaller.instance_variable_set(:@pastel, Pastel.new(enabled: false))
|
@@ -1,94 +1,35 @@
|
|
1
|
-
|
2
|
-
# Parent for all commands (Install, Upgrade, Backup)
|
3
|
-
#
|
4
|
-
module Redmine::Installer
|
1
|
+
module RedmineInstaller
|
5
2
|
class Task
|
3
|
+
include Utils
|
6
4
|
|
7
|
-
|
8
|
-
attr_accessor :tmp_redmine_root
|
9
|
-
attr_accessor :options
|
10
|
-
attr_accessor :settings
|
11
|
-
attr_accessor :env
|
5
|
+
attr_reader :options
|
12
6
|
|
13
|
-
|
7
|
+
def initialize(**options)
|
8
|
+
@options = OpenStruct.new(options)
|
14
9
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
self.env = options[:env]
|
19
|
-
|
20
|
-
# Initialize steps for task
|
21
|
-
@steps = {}
|
22
|
-
index = 1
|
23
|
-
self.class::STEPS.each do |step|
|
24
|
-
@steps[index] = step.new(index, self)
|
25
|
-
index += 1
|
26
|
-
end
|
10
|
+
logger.info "#{class_name} initialized with #{options}"
|
11
|
+
logger.info "RUBY_VERSION: #{RUBY_VERSION}"
|
12
|
+
logger.info "USER: #{env_user}"
|
27
13
|
end
|
28
14
|
|
29
15
|
def run
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@steps.each do |_, step|
|
35
|
-
step.print_title
|
36
|
-
step.print_header
|
37
|
-
step.up
|
38
|
-
step.print_footer
|
39
|
-
step.ran = true
|
40
|
-
puts
|
41
|
-
end
|
42
|
-
|
43
|
-
@steps.each do |_, step|
|
44
|
-
step.final
|
45
|
-
end
|
16
|
+
up
|
17
|
+
rescue => e
|
18
|
+
@error = e
|
46
19
|
|
47
|
-
|
48
|
-
|
49
|
-
plugin.final(self)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
rescue Redmine::Installer::Error => e
|
53
|
-
# Rescue from error comes from installer
|
54
|
-
# run steps again for cleaning
|
55
|
-
@steps.values.reverse.each do |step|
|
56
|
-
next unless step.ran
|
57
|
-
step.down
|
58
|
-
end
|
20
|
+
logger.error(e.message)
|
21
|
+
logger.error(*e.backtrace)
|
59
22
|
|
60
|
-
|
61
|
-
$stderr.flush
|
62
|
-
exit(1)
|
63
|
-
end
|
23
|
+
puts pastel.red(e.message)
|
64
24
|
|
65
|
-
|
66
|
-
# upgrade with source file
|
67
|
-
def check_package
|
68
|
-
if package.nil?
|
69
|
-
raise Redmine::Installer::Error, I18n.translate(:error_argument_package_is_missing)
|
70
|
-
end
|
25
|
+
down
|
71
26
|
end
|
72
27
|
|
73
|
-
def
|
74
|
-
|
28
|
+
def up
|
29
|
+
raise NotImplementedError
|
75
30
|
end
|
76
31
|
|
77
|
-
|
78
|
-
#
|
79
|
-
# == Examples:
|
80
|
-
# class Install < Task
|
81
|
-
# end
|
82
|
-
#
|
83
|
-
# Install.new.install? #=> true
|
84
|
-
#
|
85
|
-
def self.inherited(child)
|
86
|
-
method_name = "#{child.class_name.downcase}?".to_sym
|
87
|
-
|
88
|
-
define_method(method_name) { false }
|
89
|
-
child.send(:define_method, method_name) { true }
|
90
|
-
|
91
|
-
super
|
32
|
+
def down
|
92
33
|
end
|
93
34
|
|
94
35
|
end
|
@@ -1,68 +1,60 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
#
|
4
|
-
# You can upgrade current redmine by archive or currently defined git repository.
|
5
|
-
# If your redmine contain plugins which are not part of new package - all these
|
6
|
-
# plugins will be kept otherwise are replaced with those from package.
|
7
|
-
#
|
8
|
-
# Final step will ask you if you want save steps configuration.
|
9
|
-
# If you say YES, configuration will be stored as profile so next time
|
10
|
-
# you can upgrade redmine faster.
|
11
|
-
#
|
12
|
-
# redmine upgrade PACKAGE --profile PROFILE_ID
|
13
|
-
# Profiles are stored on HOME_FOLDER/.redmine-installer-profiles.yml.
|
14
|
-
#
|
15
|
-
# == Steps:
|
16
|
-
# 1. Redmine root - where should be new redmine located
|
17
|
-
# 2. Load package - extract package
|
18
|
-
# 3. Validation - current redmine should be valid
|
19
|
-
# 4. Backup - backup current redmine (see backup section)
|
20
|
-
# 5. Upgrading - install commands are executed
|
21
|
-
# 6. Moving redmine - redmine is moved from temporarily folder to given redmine_root
|
22
|
-
# 7. Profile saving - generating profile (see profile section)
|
23
|
-
#
|
24
|
-
# == Usage:
|
25
|
-
#
|
26
|
-
# From archive::
|
27
|
-
# # minimal
|
28
|
-
# redmine upgrade PATH_TO_PACKAGE
|
29
|
-
#
|
30
|
-
# # full
|
31
|
-
# redmine upgrade PATH_TO_PACKAGE --env ENV1,ENV2,ENV3
|
32
|
-
#
|
33
|
-
# From git::
|
34
|
-
# # minimal
|
35
|
-
# redmine upgrade --source git
|
36
|
-
#
|
37
|
-
# # full
|
38
|
-
# redmine upgrade --source git --env ENV1,ENV2,ENV3
|
39
|
-
#
|
40
|
-
module Redmine::Installer
|
41
|
-
class Upgrade < Task
|
1
|
+
module RedmineInstaller
|
2
|
+
class Upgrade < Install
|
42
3
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
step::Validation,
|
48
|
-
step::Backup,
|
49
|
-
step::Upgrade,
|
50
|
-
step::MoveRedmine
|
51
|
-
]
|
4
|
+
def up
|
5
|
+
if options.profile
|
6
|
+
@profile = Profile.get!(options.profile)
|
7
|
+
end
|
52
8
|
|
53
|
-
|
9
|
+
if @profile
|
10
|
+
@target_redmine.load_profile(@profile)
|
11
|
+
end
|
54
12
|
|
55
|
-
|
56
|
-
|
57
|
-
|
13
|
+
@environment.check
|
14
|
+
@target_redmine.ensure_and_valid_root
|
15
|
+
@target_redmine.validate
|
16
|
+
@target_redmine.check_running_state
|
58
17
|
|
59
|
-
|
18
|
+
@package.ensure_and_valid_package
|
19
|
+
@package.extract
|
20
|
+
|
21
|
+
@temp_redmine.root = @package.redmine_root
|
22
|
+
|
23
|
+
@target_redmine.make_backup
|
24
|
+
|
25
|
+
@temp_redmine.copy_importants_from(@target_redmine)
|
26
|
+
@temp_redmine.copy_missing_plugins_from(@target_redmine)
|
27
|
+
|
28
|
+
@temp_redmine.upgrade
|
29
|
+
|
30
|
+
print_title('Finishing installation')
|
31
|
+
ok('Cleaning root'){ @target_redmine.delete_root }
|
32
|
+
ok('Moving redmine to target directory'){ @target_redmine.move_from(@temp_redmine) }
|
33
|
+
ok('Cleanning up'){ @package.clean_up }
|
34
|
+
ok('Moving installer log'){ logger.move_to(@target_redmine, suffix: 'upgrade') }
|
35
|
+
|
36
|
+
puts
|
37
|
+
puts pastel.bold('Redmine was upgraded')
|
38
|
+
logger.info('Redmine was upgraded')
|
39
|
+
|
40
|
+
if @profile.nil? && prompt.yes?('Do you want save steps for further use?', default: false)
|
41
|
+
profile = Profile.new
|
42
|
+
@target_redmine.save_profile(profile)
|
43
|
+
profile.save
|
44
|
+
end
|
60
45
|
end
|
61
46
|
|
62
|
-
def
|
63
|
-
|
64
|
-
|
65
|
-
|
47
|
+
def down
|
48
|
+
@temp_redmine.clean_up
|
49
|
+
@package.clean_up
|
50
|
+
|
51
|
+
if @target_redmine.database && @target_redmine.database.backuped?
|
52
|
+
puts
|
53
|
+
puts "Database have been backed up on #{pastel.bold(@target_redmine.database.backup)}"
|
54
|
+
end
|
55
|
+
|
56
|
+
puts
|
57
|
+
puts "(Log is located on #{pastel.bold(logger.path)})"
|
66
58
|
end
|
67
59
|
|
68
60
|
end
|
@@ -1,248 +1,61 @@
|
|
1
|
-
|
2
|
-
require 'notifier'
|
3
|
-
require 'ansi'
|
4
|
-
require 'io/console'
|
5
|
-
|
6
|
-
module Redmine::Installer
|
1
|
+
module RedmineInstaller
|
7
2
|
module Utils
|
8
3
|
|
9
|
-
|
10
|
-
base.send :extend, Methods
|
11
|
-
base.send :include, Methods
|
4
|
+
PROGRESSBAR_FORMAT = ':elapsed [:bar] :percent'
|
12
5
|
|
13
|
-
|
14
|
-
|
15
|
-
end
|
6
|
+
def class_name
|
7
|
+
self.class.name.split('::').last
|
16
8
|
end
|
17
9
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
# Generals
|
22
|
-
|
23
|
-
def plugin
|
24
|
-
Redmine::Installer::Plugin
|
25
|
-
end
|
26
|
-
|
27
|
-
def command
|
28
|
-
Redmine::Installer::Command.instance
|
29
|
-
end
|
30
|
-
|
31
|
-
def error(*args)
|
32
|
-
# Translate message
|
33
|
-
if args.first.is_a?(Symbol)
|
34
|
-
message = translate(*args)
|
35
|
-
else
|
36
|
-
message = args.first
|
37
|
-
end
|
38
|
-
|
39
|
-
# Colorize message
|
40
|
-
colorize(message)
|
41
|
-
|
42
|
-
raise Redmine::Installer::Error, message
|
43
|
-
end
|
44
|
-
|
45
|
-
# Try create a dir
|
46
|
-
# When mkdir raise an error (permission problem) method
|
47
|
-
# ask user if wants exist or try again
|
48
|
-
def try_create_dir(dir)
|
49
|
-
begin
|
50
|
-
FileUtils.mkdir_p(dir)
|
51
|
-
rescue
|
52
|
-
choices = {}
|
53
|
-
choices[:exit] = t(:exit)
|
54
|
-
choices[:try_again] = t(:try_again)
|
55
|
-
|
56
|
-
answer = choose(t(:dir_not_exist_and_cannot_be_created, dir: dir), choices, default: :exit)
|
57
|
-
|
58
|
-
case answer
|
59
|
-
when :exit
|
60
|
-
error ''
|
61
|
-
when :try_again
|
62
|
-
try_create_dir(dir)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# Check if there are plugins in plugin dir
|
68
|
-
def some_plugins?
|
69
|
-
Dir.glob(File.join('plugins', '*')).select{|record| File.directory?(record)}.any?
|
70
|
-
end
|
71
|
-
|
72
|
-
def windows?
|
73
|
-
RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
|
74
|
-
end
|
75
|
-
|
76
|
-
def root?
|
77
|
-
Process.euid == 0
|
78
|
-
end
|
79
|
-
|
80
|
-
|
81
|
-
# =======================================================================
|
82
|
-
# Input, output
|
83
|
-
|
84
|
-
# Print message to stdout
|
85
|
-
def say(message, lines=0)
|
86
|
-
# Translate message
|
87
|
-
if message.is_a?(Symbol)
|
88
|
-
message = translate(message)
|
89
|
-
end
|
90
|
-
|
91
|
-
# Colorize message
|
92
|
-
colorize(message)
|
93
|
-
|
94
|
-
$stdout.print(message)
|
95
|
-
lines.times { $stdout.puts }
|
96
|
-
$stdout.flush
|
97
|
-
end
|
98
|
-
|
99
|
-
# Colorize text based on XML marks
|
100
|
-
#
|
101
|
-
# == Examples:
|
102
|
-
# colorize("<bright><on_black><white>text</white></on_black></bright>")
|
103
|
-
# # => "\e[1m\e[40m\e[37mtext\e[0m\e[0m\e[0m"
|
104
|
-
#
|
105
|
-
def colorize(text)
|
106
|
-
return unless text.is_a?(String)
|
107
|
-
|
108
|
-
text.gsub!(/<([a-zA-Z0-9_]+)>/) do
|
109
|
-
if ANSI::CHART.has_key?($1.to_sym)
|
110
|
-
ANSI.send($1)
|
111
|
-
else
|
112
|
-
"<#{$1}>"
|
113
|
-
end
|
114
|
-
end
|
115
|
-
text.gsub!(/<\/([a-zA-Z0-9_]+)>/) do
|
116
|
-
if ANSI::CHART.has_key?($1.to_sym)
|
117
|
-
ANSI.clear
|
118
|
-
else
|
119
|
-
"</#{$1}>"
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
# Instead of `super` take only what I need
|
125
|
-
def gets(hide=false)
|
126
|
-
if hide
|
127
|
-
input = $stdin.noecho{|io| io.gets}.to_s.chomp
|
128
|
-
$stdout.puts # noecho is also for enter
|
129
|
-
input
|
130
|
-
else
|
131
|
-
$stdin.gets.to_s.chomp
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
# Asking on 1 line
|
136
|
-
def ask(message=nil, options={})
|
137
|
-
# Translate message
|
138
|
-
if message.is_a?(Symbol)
|
139
|
-
message = translate(message)
|
140
|
-
end
|
141
|
-
default = options[:default]
|
142
|
-
|
143
|
-
if default
|
144
|
-
message << " [#{default}]"
|
145
|
-
end
|
146
|
-
|
147
|
-
if !options[:without_colon]
|
148
|
-
message << ': '
|
149
|
-
end
|
150
|
-
|
151
|
-
say(message)
|
152
|
-
input = gets(options[:hide])
|
153
|
-
|
154
|
-
# Ctrl-D or enter was pressed
|
155
|
-
return default if input.empty?
|
156
|
-
|
157
|
-
input
|
158
|
-
end
|
159
|
-
|
160
|
-
# User can choose from selection
|
161
|
-
def choose(message, choices, options={})
|
162
|
-
choices = choices.to_a
|
163
|
-
default = options[:default]
|
164
|
-
index = 1
|
165
|
-
|
166
|
-
say(message, 1) unless message.nil?
|
167
|
-
choices.each do |(key, message)|
|
168
|
-
if key == default
|
169
|
-
pre = '*'
|
170
|
-
else
|
171
|
-
pre = ' '
|
172
|
-
end
|
173
|
-
|
174
|
-
say(" #{pre}#{index}) #{message}", 1)
|
175
|
-
index += 1
|
176
|
-
end
|
177
|
-
|
178
|
-
input = ask('> ', without_colon: true).to_i
|
179
|
-
puts
|
180
|
-
|
181
|
-
# Without default is input 0
|
182
|
-
return default if input.zero? || input > choices.size
|
183
|
-
|
184
|
-
choices[input-1][0]
|
185
|
-
end
|
186
|
-
|
187
|
-
# Say 'Do you want?'
|
188
|
-
# -> YES, NO
|
189
|
-
#
|
190
|
-
def confirm(message, default=true)
|
191
|
-
# Translate message
|
192
|
-
if message.is_a?(Symbol)
|
193
|
-
message = translate(message)
|
194
|
-
end
|
195
|
-
|
196
|
-
# Colorize message
|
197
|
-
colorize(message)
|
198
|
-
|
199
|
-
yes = t(:yes_t)
|
200
|
-
no = t(:no_t)
|
201
|
-
|
202
|
-
if default
|
203
|
-
yes.upcase!
|
204
|
-
else
|
205
|
-
no.upcase!
|
206
|
-
end
|
207
|
-
|
208
|
-
message << " (#{yes}/#{no}): "
|
10
|
+
def logger
|
11
|
+
RedmineInstaller.logger
|
12
|
+
end
|
209
13
|
|
210
|
-
|
211
|
-
|
14
|
+
def prompt
|
15
|
+
RedmineInstaller.prompt
|
16
|
+
end
|
212
17
|
|
213
|
-
|
18
|
+
def pastel
|
19
|
+
RedmineInstaller.pastel
|
20
|
+
end
|
214
21
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
return false
|
219
|
-
end
|
220
|
-
end
|
22
|
+
def run_command(cmd, title=nil)
|
23
|
+
RedmineInstaller::Command.new(cmd, title: title).run
|
24
|
+
end
|
221
25
|
|
26
|
+
def ok(title)
|
27
|
+
print "#{title} ... "
|
28
|
+
yield
|
29
|
+
puts pastel.green('OK')
|
30
|
+
rescue => e
|
31
|
+
puts pastel.red('FAIL')
|
32
|
+
raise
|
33
|
+
end
|
222
34
|
|
223
|
-
|
224
|
-
|
35
|
+
def env_user
|
36
|
+
ENV['USER'] || ENV['USERNAME']
|
37
|
+
end
|
225
38
|
|
226
|
-
|
227
|
-
|
39
|
+
# Try create a dir
|
40
|
+
# When mkdir raise an error (permission problem) method ask user if wants exist or try again
|
41
|
+
def create_dir(dir)
|
42
|
+
FileUtils.mkdir_p(dir)
|
43
|
+
rescue
|
44
|
+
if prompt.yes?("Dir #{dir} doesn't exist and can't be created. Try again?", default: true)
|
45
|
+
create_dir(dir)
|
46
|
+
else
|
47
|
+
error('Dir creating was aborted by user.')
|
228
48
|
end
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
# =======================================================================
|
233
|
-
# Notifications
|
49
|
+
end
|
234
50
|
|
235
|
-
|
236
|
-
|
51
|
+
def print_title(title)
|
52
|
+
puts
|
53
|
+
puts pastel.white.on_black(title)
|
54
|
+
end
|
237
55
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
image: image.to_s
|
242
|
-
)
|
243
|
-
thread.join
|
244
|
-
end
|
56
|
+
def error(message)
|
57
|
+
raise RedmineInstaller::Error, message
|
58
|
+
end
|
245
59
|
|
246
|
-
|
247
|
-
|
248
|
-
end # Redmine::Installer
|
60
|
+
end
|
61
|
+
end
|