redmine-installer 1.0.7 → 2.0.0.rc1
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 +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
|