yuyi 1.0.8 → 1.1.3
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/.new +1 -1
- data/.ruby-version +1 -0
- data/Gemfile +7 -2
- data/Gemfile.lock +16 -21
- data/Guardfile +1 -1
- data/README.md +41 -24
- data/Rakefile +38 -0
- data/bin/yuyi +9 -1
- data/lib/yuyi/cli.rb +32 -363
- data/lib/yuyi/core.rb +4 -0
- data/lib/yuyi/dsl.rb +131 -0
- data/lib/yuyi/menu.rb +174 -166
- data/lib/yuyi/roll.rb +95 -140
- data/lib/yuyi/source.rb +4 -3
- data/lib/yuyi/ui.rb +103 -0
- data/lib/yuyi.rb +17 -2
- data/spec/fixtures/menu.yaml +3 -2
- data/spec/fixtures/menu2.yaml +5 -2
- data/spec/fixtures/roll_dir/{nested/foo_roll.rb → foo_roll.rb} +0 -0
- data/spec/fixtures/roll_dir/foo_roll_model.rb +2 -0
- data/spec/fixtures/roll_dir/nested/bar_roll.rb +1 -1
- data/spec/fixtures/roll_zip.zip +0 -0
- data/spec/lib/yuyi/cli_spec.rb +11 -310
- data/spec/lib/yuyi/core_spec.rb +1 -1
- data/spec/lib/yuyi/dsl_spec.rb +135 -0
- data/spec/lib/yuyi/menu_spec.rb +177 -117
- data/spec/lib/yuyi/roll_spec.rb +38 -227
- data/spec/lib/yuyi/source_spec.rb +6 -2
- data/spec/lib/yuyi/ui_spec.rb +36 -0
- data/spec/roll_validator.rb +51 -0
- data/spec/spec_helper.rb +2 -0
- data/yuyi_menu +8 -0
- metadata +36 -10
- data/bin/install +0 -42
data/lib/yuyi/roll.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
class Yuyi::Roll
|
4
4
|
|
5
|
-
# DSL API Methods
|
5
|
+
# CLASS DSL API Methods
|
6
6
|
#
|
7
7
|
def self.title title = nil
|
8
8
|
title ? @title = title : @title
|
@@ -13,108 +13,85 @@ class Yuyi::Roll
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.pre_install &block
|
16
|
-
|
17
|
-
@pre_install = block
|
18
|
-
else
|
19
|
-
@pre_install
|
20
|
-
end
|
16
|
+
block_given? ? @pre_install = block : @pre_install
|
21
17
|
end
|
22
18
|
|
23
19
|
def self.install &block
|
24
|
-
|
25
|
-
@install = block
|
26
|
-
else
|
27
|
-
@install
|
28
|
-
end
|
20
|
+
block_given? ? @install = block : @install
|
29
21
|
end
|
30
22
|
|
31
23
|
def self.post_install &block
|
32
|
-
|
33
|
-
@post_install = block
|
34
|
-
else
|
35
|
-
@post_install
|
36
|
-
end
|
24
|
+
block_given? ? @post_install = block : @post_install
|
37
25
|
end
|
38
26
|
|
39
27
|
def self.uninstall &block
|
40
|
-
|
41
|
-
@uninstall = block
|
42
|
-
else
|
43
|
-
@uninstall
|
44
|
-
end
|
28
|
+
block_given? ? @uninstall = block : @uninstall
|
45
29
|
end
|
46
30
|
|
47
31
|
def self.upgrade &block
|
48
|
-
|
49
|
-
@upgrade = block
|
50
|
-
else
|
51
|
-
@upgrade
|
52
|
-
end
|
32
|
+
block_given? ? @upgrade = block : @upgrade
|
53
33
|
end
|
54
34
|
|
55
35
|
def self.installed? &block
|
56
|
-
|
57
|
-
@installed = block
|
58
|
-
else
|
59
|
-
@installed
|
60
|
-
end
|
36
|
+
block_given? ? @installed = block : @installed
|
61
37
|
end
|
62
38
|
|
63
39
|
def self.dependencies *dependencies
|
64
|
-
|
65
|
-
|
66
|
-
unless dependencies.empty?
|
67
|
-
@dependencies |= dependencies
|
68
|
-
require_dependencies
|
40
|
+
dependencies.each do |d|
|
41
|
+
Yuyi::Menu.find_roll d
|
69
42
|
end
|
70
43
|
|
71
|
-
@dependencies
|
44
|
+
@dependencies ||= []
|
45
|
+
@dependencies |= dependencies
|
72
46
|
end
|
73
47
|
|
74
48
|
# set option definitions
|
75
|
-
def self.options
|
76
|
-
@option_defs
|
49
|
+
def self.options option_defs = {}
|
50
|
+
@option_defs = option_defs
|
77
51
|
end
|
78
52
|
|
79
|
-
# DSL Helper methods
|
80
|
-
#
|
81
|
-
def title; self.class.title; end
|
82
|
-
def file_name; self.class.file_name; end
|
83
53
|
|
84
|
-
#
|
85
|
-
|
86
|
-
|
54
|
+
# INSTANCE DSL METHODS
|
55
|
+
#
|
56
|
+
def method_missing method, *args, &block
|
57
|
+
begin
|
58
|
+
self.class.send method, *args, &block
|
59
|
+
rescue
|
60
|
+
Yuyi.send method, *args, &block
|
61
|
+
rescue
|
62
|
+
super
|
63
|
+
end
|
87
64
|
end
|
88
65
|
|
89
|
-
def
|
90
|
-
Yuyi.
|
66
|
+
def on_the_menu? roll
|
67
|
+
Yuyi::Menu.on_the_menu? roll
|
91
68
|
end
|
92
69
|
|
93
|
-
|
94
|
-
|
70
|
+
# return definitions instaed of user options
|
71
|
+
#
|
72
|
+
def option_defs
|
73
|
+
self.class.options
|
95
74
|
end
|
96
75
|
|
76
|
+
# return user option values
|
77
|
+
#
|
97
78
|
def options
|
98
79
|
option_defaults = {}
|
99
|
-
option_defs.each do |
|
100
|
-
option_defaults[
|
80
|
+
option_defs.each do |option_name, option_settings|
|
81
|
+
option_defaults[option_name] = option_settings[:default]
|
101
82
|
end
|
102
83
|
|
103
|
-
option_defaults.merge Yuyi::Menu.options(self)
|
104
|
-
end
|
105
|
-
|
106
|
-
def dependencies
|
107
|
-
self.class.dependencies
|
84
|
+
option_defaults.merge Yuyi::Menu.options(self.class.file_name)
|
108
85
|
end
|
109
86
|
|
110
87
|
# Run the roll
|
111
88
|
#
|
112
|
-
def
|
89
|
+
def order
|
113
90
|
if installed?
|
114
91
|
if options[:uninstall]
|
115
92
|
Yuyi.say "🍣\s Uninstalling #{title}...", :color => 33
|
116
93
|
uninstall
|
117
|
-
elsif upgrade
|
94
|
+
elsif Yuyi.upgrade
|
118
95
|
Yuyi.say "🍣\s Upgrading #{title}", :color => 36
|
119
96
|
upgrade
|
120
97
|
end
|
@@ -123,115 +100,93 @@ class Yuyi::Roll
|
|
123
100
|
install
|
124
101
|
end
|
125
102
|
end
|
126
|
-
alias_method :
|
127
|
-
alias_method :entree, :install
|
103
|
+
alias_method :entree, :order
|
128
104
|
|
129
|
-
|
105
|
+
# Methods to execute block
|
106
|
+
#
|
107
|
+
def pre_install
|
108
|
+
return if !self.class.pre_install || installed?
|
109
|
+
say title, :type => :success
|
110
|
+
instance_eval(&self.class.pre_install)
|
111
|
+
end
|
130
112
|
alias_method :appetizers, :pre_install
|
131
113
|
|
132
|
-
def
|
114
|
+
def install
|
115
|
+
begin
|
116
|
+
instance_eval(&self.class.install).inspect
|
117
|
+
rescue
|
118
|
+
say "The #{self.title} roll does not have `install` defined", :type => :fail
|
119
|
+
exit
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def post_install
|
124
|
+
return if !self.class.post_install || installed?
|
125
|
+
say title, :type => :success
|
126
|
+
instance_eval(&self.class.post_install)
|
127
|
+
end
|
133
128
|
alias_method :dessert, :post_install
|
134
129
|
|
135
|
-
|
130
|
+
def uninstall
|
131
|
+
begin
|
132
|
+
instance_eval(&self.class.uninstall)
|
133
|
+
rescue
|
134
|
+
say "The #{self.title} roll does not have `uninstall` defined", :type => :fail
|
135
|
+
exit
|
136
|
+
end
|
137
|
+
end
|
136
138
|
|
137
|
-
|
138
|
-
|
139
|
+
def upgrade
|
140
|
+
begin
|
141
|
+
instance_eval(&self.class.upgrade)
|
142
|
+
rescue
|
143
|
+
say "The #{self.title} roll does not have `upgrade` defined", :type => :fail
|
144
|
+
exit
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def installed?
|
149
|
+
if Yuyi.verbose
|
150
|
+
say "INSTALLED?: #{self.title}", :color => 36
|
139
151
|
end
|
140
152
|
|
153
|
+
begin
|
154
|
+
!!instance_eval(&self.class.installed?)
|
155
|
+
rescue
|
156
|
+
say "The #{self.title} roll does not have `installed?` defined", :type => :fail
|
157
|
+
exit
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
141
163
|
# Add to global collection of rolls
|
142
164
|
#
|
143
165
|
def self.inherited klass
|
144
|
-
return if klass.to_s.include? 'RollModel'
|
145
|
-
|
146
166
|
add_roll klass, caller
|
147
167
|
end
|
148
168
|
|
169
|
+
# method that actually passes the new roll to the menu
|
170
|
+
#
|
149
171
|
def self.add_roll klass, caller
|
150
172
|
# convert class name to a title string
|
151
173
|
klass.title class_to_title klass
|
152
174
|
|
153
175
|
# convert caller to a file name symbol
|
154
|
-
klass.file_name caller_to_file_name
|
176
|
+
klass.file_name caller_to_file_name(caller)
|
155
177
|
|
156
178
|
Yuyi::Menu.add_roll klass.file_name, klass
|
157
179
|
end
|
158
180
|
|
181
|
+
# Convert long class name to a readable title
|
182
|
+
#
|
159
183
|
def self.class_to_title klass
|
160
184
|
klass.to_s.match(/[^:]+$/)[0].gsub(/(?=[A-Z])/, ' ').strip
|
161
185
|
end
|
162
186
|
|
187
|
+
# Convert long file name to a roll name symbol
|
188
|
+
#
|
163
189
|
def self.caller_to_file_name caller
|
164
190
|
caller.first[/[a-z_]+?(?=\.rb)/].to_sym
|
165
191
|
end
|
166
|
-
|
167
|
-
def self.require_dependencies
|
168
|
-
@dependencies.each do |roll|
|
169
|
-
unless Yuyi::Menu.on_the_menu? roll
|
170
|
-
Yuyi::Menu.find_roll roll
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
def pre_install
|
176
|
-
return if self.class.installed? || !self.class.pre_install
|
177
|
-
say title, :type => :success
|
178
|
-
instance_eval(&self.class.pre_install)
|
179
|
-
end
|
180
|
-
|
181
|
-
def install
|
182
|
-
begin
|
183
|
-
instance_eval(&self.class.install)
|
184
|
-
rescue
|
185
|
-
say "The #{self.title} roll does not have `install` defined", :type => :fail
|
186
|
-
exit
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
def post_install
|
191
|
-
return if self.class.installed? || !self.class.post_install
|
192
|
-
say title, :type => :success
|
193
|
-
instance_eval(&self.class.post_install)
|
194
|
-
end
|
195
|
-
|
196
|
-
def uninstall
|
197
|
-
begin
|
198
|
-
instance_eval(&self.class.uninstall)
|
199
|
-
rescue
|
200
|
-
say "The #{self.title} roll does not have `uninstall` defined", :type => :fail
|
201
|
-
exit
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
def upgrade
|
206
|
-
begin
|
207
|
-
instance_eval(&self.class.upgrade)
|
208
|
-
rescue
|
209
|
-
say "The #{self.title} roll does not have `upgrade` defined", :type => :fail
|
210
|
-
exit
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
def installed?
|
215
|
-
if Yuyi.verbose?
|
216
|
-
say "INSTALLED?: #{self.title}", :color => 36
|
217
|
-
end
|
218
|
-
|
219
|
-
begin
|
220
|
-
!!instance_eval(&self.class.installed?)
|
221
|
-
rescue
|
222
|
-
say "The #{self.title} roll does not have `installed?` defined", :type => :fail
|
223
|
-
exit
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
# Helpers for Yuyi Cli methods
|
228
|
-
def say *args; Yuyi.say *args; end
|
229
|
-
def ask *args; Yuyi.ask *args; end
|
230
|
-
def run *args; Yuyi.run *args; end
|
231
|
-
def command? *args; Yuyi.command? *args; end
|
232
|
-
def osx_version; Yuyi.osx_version; end
|
233
|
-
|
234
|
-
def on_the_menu? roll
|
235
|
-
Yuyi::Menu.on_the_menu? roll
|
236
|
-
end
|
237
192
|
end
|
data/lib/yuyi/source.rb
CHANGED
@@ -5,7 +5,7 @@ require 'tmpdir'
|
|
5
5
|
class Yuyi::Source
|
6
6
|
ROLL_FILE_GLOB = '**/*.rb'
|
7
7
|
|
8
|
-
def
|
8
|
+
def rolls; @rolls end
|
9
9
|
def roll_models; @roll_models end
|
10
10
|
|
11
11
|
private
|
@@ -16,7 +16,7 @@ private
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def initialize name, path
|
19
|
-
@
|
19
|
+
@rolls = {}
|
20
20
|
@roll_models = {}
|
21
21
|
@name = name
|
22
22
|
@path = path
|
@@ -30,6 +30,7 @@ private
|
|
30
30
|
dir = FileUtils.mkdir_p(File.join(@@root_tmp_dir, @name.to_s))
|
31
31
|
|
32
32
|
# RUBY_VERSION
|
33
|
+
# DEPRECATION
|
33
34
|
# mkdir_p <= 1.8 returns a string
|
34
35
|
# mkdir_p >= 1.9 returns an array
|
35
36
|
#
|
@@ -105,7 +106,7 @@ private
|
|
105
106
|
if r.include?('roll_model.rb')
|
106
107
|
@roll_models[name] = require_path
|
107
108
|
else
|
108
|
-
@
|
109
|
+
@rolls[name] = require_path
|
109
110
|
end
|
110
111
|
end
|
111
112
|
end
|
data/lib/yuyi/ui.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
module Yuyi::Ui
|
2
|
+
def header
|
3
|
+
line_length = 50
|
4
|
+
say
|
5
|
+
say '-' * line_length, :color => 4
|
6
|
+
say
|
7
|
+
say '____ ____ __ __ ____ ____ __ ', :color => 31, :justify => :center, :padding => line_length
|
8
|
+
say '\ \ / / | | | | \ \ / / | | ', :color => 32, :justify => :center, :padding => line_length
|
9
|
+
say ' \ \/ / | | | | \ \/ / | | ', :color => 33, :justify => :center, :padding => line_length
|
10
|
+
say ' \_ _/ | | | | \_ _/ | | ', :color => 34, :justify => :center, :padding => line_length
|
11
|
+
say ' | | | `--\' | | | | | ', :color => 35, :justify => :center, :padding => line_length
|
12
|
+
say ' |__| \______/ |__| |__| ', :color => 36, :justify => :center, :padding => line_length
|
13
|
+
say
|
14
|
+
say "VERSION #{Yuyi::VERSION}", :justify => :center, :padding => line_length
|
15
|
+
say
|
16
|
+
say '-' * line_length, :color => 4
|
17
|
+
say
|
18
|
+
end
|
19
|
+
|
20
|
+
# If any rolls on the menu have options, confirm the options before continuing
|
21
|
+
#
|
22
|
+
def confirm_options
|
23
|
+
confirm = false
|
24
|
+
Yuyi::Menu.rolls.each do |name, roll|
|
25
|
+
|
26
|
+
unless roll.class.options.empty?
|
27
|
+
present_options roll
|
28
|
+
confirm = true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
if confirm
|
33
|
+
say 'Your menu is being loaded from: ', :type => :warn, :newline => false
|
34
|
+
say Yuyi::Menu.menu_path
|
35
|
+
ask 'Make any changes you need to it, save it, and then press enter to continue.', :type => :warn do
|
36
|
+
Yuyi::Menu.load_from_file
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def authenticate
|
42
|
+
say 'Yuyi does not need your admin password, but some installations do.', :type => :warn
|
43
|
+
say 'You may be asked to enter your password several times.', :type => :warn
|
44
|
+
say
|
45
|
+
|
46
|
+
# keep the sudo timestamp fresh just in case
|
47
|
+
Thread::new do
|
48
|
+
loop do
|
49
|
+
sleep 1.minute
|
50
|
+
`sudo -v`
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Show formatted options
|
56
|
+
#
|
57
|
+
def present_options roll, examples = true
|
58
|
+
indent = 2
|
59
|
+
longest_option = roll.options.keys.map(&:to_s).max_by(&:length).length + indent
|
60
|
+
|
61
|
+
say "Available options for #{roll.title}...", :color => 32
|
62
|
+
|
63
|
+
roll.option_defs.each do |k, v|
|
64
|
+
option_color = v[:required] ? 31 : 36
|
65
|
+
|
66
|
+
say "#{k.to_s.rjust(longest_option)}: ", :color => option_color, :newline => false
|
67
|
+
say v[:description]
|
68
|
+
say (' ' * (longest_option + indent)), :newline => false
|
69
|
+
if v[:default]
|
70
|
+
say 'default: ', :color => 36, :newline => false
|
71
|
+
say v[:default]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
if examples
|
76
|
+
examples_hash = {}
|
77
|
+
example_indent = longest_option + indent
|
78
|
+
options = roll.options.dup
|
79
|
+
|
80
|
+
# merge examples from roll source in
|
81
|
+
options.each do |option, value|
|
82
|
+
if example = roll.option_defs[option][:example]
|
83
|
+
options[option] = example
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
examples_hash[roll.file_name.to_s] = options
|
88
|
+
|
89
|
+
say
|
90
|
+
say 'Example', :color => 33, :indent => example_indent, :newline => false
|
91
|
+
say examples_hash.deep_stringify_keys!.to_yaml.sub('---', '').gsub(/\n(\s*)/, "\n\\1#{' ' * example_indent}")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Output text with a certain color (or style)
|
96
|
+
# Reference for color codes
|
97
|
+
# https://github.com/flori/term-ansicolor/blob/master/lib/term/ansicolor.rb
|
98
|
+
#
|
99
|
+
def colorize text, color_code
|
100
|
+
return text unless color_code
|
101
|
+
"\e[#{color_code}m#{text}\e[0m"
|
102
|
+
end
|
103
|
+
end
|
data/lib/yuyi.rb
CHANGED
@@ -1,16 +1,31 @@
|
|
1
1
|
class Yuyi; end
|
2
2
|
|
3
|
-
require 'yuyi/cli'
|
4
3
|
require 'yuyi/core'
|
4
|
+
require 'yuyi/dsl'
|
5
5
|
require 'yuyi/menu'
|
6
6
|
require 'yuyi/roll'
|
7
7
|
require 'yuyi/source'
|
8
|
+
require 'yuyi/ui'
|
8
9
|
|
9
10
|
class Yuyi
|
10
11
|
require 'yaml'
|
11
|
-
extend Yuyi::
|
12
|
+
extend Yuyi::Dsl
|
13
|
+
extend Yuyi::Ui
|
12
14
|
|
13
15
|
NAME = 'Yuyi'
|
14
16
|
VERSION = YAML.load(File.read(File.dirname(__FILE__) + '/../.new'))['version']
|
15
17
|
DEFAULT_MENU = File.expand_path('~/yuyi_menu')
|
18
|
+
|
19
|
+
def self.start
|
20
|
+
header
|
21
|
+
|
22
|
+
Yuyi::Menu.new menu_path
|
23
|
+
|
24
|
+
# confirm with user
|
25
|
+
confirm_options
|
26
|
+
authenticate
|
27
|
+
|
28
|
+
# order
|
29
|
+
Yuyi::Menu.order
|
30
|
+
end
|
16
31
|
end
|
data/spec/fixtures/menu.yaml
CHANGED
data/spec/fixtures/menu2.yaml
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
+
# menu should be the exact same as menu.yaml, except with the options changes for foo_roll
|
2
|
+
# this is to test that when a menu is edited and options are changed, yuyi picks up the changes.
|
1
3
|
sources:
|
2
|
-
|
3
|
-
|
4
|
+
dir: spec/fixtures/roll_dir
|
5
|
+
zip: spec/fixtures/roll_zip.zip
|
4
6
|
rolls:
|
5
7
|
foo_roll:
|
6
8
|
bar: foo
|
9
|
+
bar_roll:
|
File without changes
|
@@ -1,2 +1,2 @@
|
|
1
|
-
class
|
1
|
+
class BarRoll < Yuyi::Roll
|
2
2
|
end
|
data/spec/fixtures/roll_zip.zip
CHANGED
Binary file
|