smc-get 0.1.0 → 0.2.0.beta1
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.
- data/COPYING +674 -674
- data/HISTORY.rdoc +31 -0
- data/README.rdoc +163 -148
- data/VERSION.txt +1 -1
- data/bin/smc-checksum +44 -0
- data/bin/smc-get +31 -31
- data/config/smc-get.yml +32 -32
- data/lib/smc_get.rb +23 -21
- data/lib/smc_get/cui.rb +325 -289
- data/lib/smc_get/cui_commands/build.rb +329 -0
- data/lib/smc_get/cui_commands/command.rb +117 -81
- data/lib/smc_get/cui_commands/getinfo.rb +92 -91
- data/lib/smc_get/cui_commands/help.rb +65 -64
- data/lib/smc_get/cui_commands/install.rb +101 -91
- data/lib/smc_get/cui_commands/list.rb +101 -80
- data/lib/smc_get/cui_commands/search.rb +106 -109
- data/lib/smc_get/cui_commands/uninstall.rb +80 -78
- data/lib/smc_get/cui_commands/update.rb +119 -0
- data/lib/smc_get/cui_commands/version.rb +58 -57
- data/lib/smc_get/errors.rb +140 -113
- data/lib/smc_get/gui.rb +20 -19
- data/lib/smc_get/local_repository.rb +277 -0
- data/lib/smc_get/package.rb +260 -279
- data/lib/smc_get/package_archive.rb +80 -0
- data/lib/smc_get/package_specification.rb +253 -0
- data/lib/smc_get/remote_repository.rb +272 -0
- data/lib/smc_get/repository.rb +10 -0
- data/lib/smc_get/smc_get.rb +117 -139
- data/smcpak.rdoc +332 -0
- data/test/test_smc-get-cui.rb +123 -121
- data/test/test_smc-get-lib.rb +172 -170
- metadata +71 -36
data/config/smc-get.yml
CHANGED
@@ -1,32 +1,32 @@
|
|
1
|
-
#Encoding: UTF-8
|
2
|
-
################################################################################
|
3
|
-
# This file is part of smc-get.
|
4
|
-
# Copyright (C) 2010-2011 Entertaining Software, Inc.
|
5
|
-
# Copyright (C) 2011 Marvin Gülker
|
6
|
-
#
|
7
|
-
# This program is free software: you can redistribute it and/or modify
|
8
|
-
# it under the terms of the GNU General Public License as published by
|
9
|
-
# the Free Software Foundation, either version 3 of the License, or
|
10
|
-
# (at your option) any later version.
|
11
|
-
#
|
12
|
-
# This program is distributed in the hope that it will be useful,
|
13
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
-
# GNU General Public License for more details.
|
16
|
-
#
|
17
|
-
# You should have received a copy of the GNU General Public License
|
18
|
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
-
################################################################################
|
20
|
-
#
|
21
|
-
#This is the configuration file for smc-get.
|
22
|
-
---
|
23
|
-
#This is the directory where everything gets installed into.
|
24
|
-
#Set this to the installation directory of SMC, e.g.
|
25
|
-
#/usr/share/smc.
|
26
|
-
data_directory: "/usr/share/smc"
|
27
|
-
#This is the URL of the repository where packages are downloaded from.
|
28
|
-
repo_url: "https://github.com/Luiji/Secret-Maryo-Chronicles-Contributed-Levels/
|
29
|
-
#This is the maximum number of tries smc-get makes in order to
|
30
|
-
#download a package.
|
31
|
-
max_tries: 3
|
32
|
-
|
1
|
+
#Encoding: UTF-8
|
2
|
+
################################################################################
|
3
|
+
# This file is part of smc-get.
|
4
|
+
# Copyright (C) 2010-2011 Entertaining Software, Inc.
|
5
|
+
# Copyright (C) 2011 Marvin Gülker
|
6
|
+
#
|
7
|
+
# This program is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
################################################################################
|
20
|
+
#
|
21
|
+
#This is the configuration file for smc-get.
|
22
|
+
---
|
23
|
+
#This is the directory where everything gets installed into.
|
24
|
+
#Set this to the installation directory of SMC, e.g.
|
25
|
+
#/usr/share/smc.
|
26
|
+
data_directory: "/usr/share/smc"
|
27
|
+
#This is the URL of the repository where packages are downloaded from.
|
28
|
+
repo_url: "https://raw.github.com/Luiji/Secret-Maryo-Chronicles-Contributed-Levels/master/packages"
|
29
|
+
#This is the maximum number of tries smc-get makes in order to
|
30
|
+
#download a package.
|
31
|
+
max_tries: 3
|
32
|
+
|
data/lib/smc_get.rb
CHANGED
@@ -1,21 +1,23 @@
|
|
1
|
-
#Encoding: UTF-8
|
2
|
-
################################################################################
|
3
|
-
# This file is part of smc-get.
|
4
|
-
# Copyright (C) 2010-2011 Entertaining Software, Inc.
|
5
|
-
# Copyright (C) 2011 Marvin Gülker
|
6
|
-
#
|
7
|
-
# This program is free software: you can redistribute it and/or modify
|
8
|
-
# it under the terms of the GNU General Public License as published by
|
9
|
-
# the Free Software Foundation, either version 3 of the License, or
|
10
|
-
# (at your option) any later version.
|
11
|
-
#
|
12
|
-
# This program is distributed in the hope that it will be useful,
|
13
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
-
# GNU General Public License for more details.
|
16
|
-
#
|
17
|
-
# You should have received a copy of the GNU General Public License
|
18
|
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
-
################################################################################
|
20
|
-
|
21
|
-
require_relative "smc_get/smc_get"
|
1
|
+
#Encoding: UTF-8
|
2
|
+
################################################################################
|
3
|
+
# This file is part of smc-get.
|
4
|
+
# Copyright (C) 2010-2011 Entertaining Software, Inc.
|
5
|
+
# Copyright (C) 2011 Marvin Gülker
|
6
|
+
#
|
7
|
+
# This program is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
################################################################################
|
20
|
+
|
21
|
+
require_relative "smc_get/smc_get"
|
22
|
+
|
23
|
+
# vim:set ts=8 sts=2 sw=2 et: #
|
data/lib/smc_get/cui.rb
CHANGED
@@ -1,289 +1,325 @@
|
|
1
|
-
#Encoding: UTF-8
|
2
|
-
################################################################################
|
3
|
-
# This file is part of smc-get.
|
4
|
-
# Copyright (C) 2010-2011 Entertaining Software, Inc.
|
5
|
-
# Copyright (C) 2011 Marvin Gülker
|
6
|
-
#
|
7
|
-
# This program is free software: you can redistribute it and/or modify
|
8
|
-
# it under the terms of the GNU General Public License as published by
|
9
|
-
# the Free Software Foundation, either version 3 of the License, or
|
10
|
-
# (at your option) any later version.
|
11
|
-
#
|
12
|
-
# This program is distributed in the hope that it will be useful,
|
13
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
-
# GNU General Public License for more details.
|
16
|
-
#
|
17
|
-
# You should have received a copy of the GNU General Public License
|
18
|
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
-
################################################################################
|
20
|
-
|
21
|
-
#Load all the files in the cui_commands directory.
|
22
|
-
require_relative "cui_commands/command"
|
23
|
-
Dir[File.join(File.expand_path(File.dirname(__FILE__)), "cui_commands", "*.rb")].each do |filename|
|
24
|
-
require_relative "cui_commands/#{File.basename(filename)}"
|
25
|
-
end
|
26
|
-
|
27
|
-
module SmcGet
|
28
|
-
|
29
|
-
#This is the Console User Interface smc-get exposes. Each command
|
30
|
-
#is represented by a class in the CUICommands module. Those classes
|
31
|
-
#have three methods: ::help, which should return a summary on how to use
|
32
|
-
#the command (NOT print it, that's done by an internal method), #parse,
|
33
|
-
#which gets the command-line for the subcommand passed in form of an
|
34
|
-
#array you should destructively (i.e. removing the elements) analyse,
|
35
|
-
#and #execute which finally executes the command. You are free to print out
|
36
|
-
#anything inside that method.
|
37
|
-
#
|
38
|
-
#Note that inside the #parse method you can set instance variables
|
39
|
-
#as you would do for any normal class. You can then grep their values
|
40
|
-
#inside the #execute method. Furthermore, if inside #parse you detect
|
41
|
-
#an error in the commandline the user provided to you, raise the
|
42
|
-
#CUI::InvalidCommandline exception with a meaningful message which will
|
43
|
-
#then be presented to the user.
|
44
|
-
#
|
45
|
-
#The last things one should do when adding a command, is to provide
|
46
|
-
#a ::help class method that returns help on the usage of the command
|
47
|
-
#(it will be called when the user issues <tt>smc-get help YOURCOMMAND</tt>
|
48
|
-
#and it's return value will be shown to the user) and to provide
|
49
|
-
#a ::summary class method whose return value is integrated in the
|
50
|
-
#output of <tt>smc-get help</tt> under the COMMANDS section.
|
51
|
-
#
|
52
|
-
#In every method you add, you can make use of the CUI.debug method. If you
|
53
|
-
#hand it a string, it will be printed only if running in debug mode, and
|
54
|
-
#if you hand it any other object, it's +inspect+ value will be printed--if
|
55
|
-
#running in debug mode. See the SmcGet::CUICommands::Command class's
|
56
|
-
#documentation for more information on the hook methods.
|
57
|
-
#
|
58
|
-
#Internally the flow is as follows:
|
59
|
-
#1. The user calls CUI#initialize with ARGV.
|
60
|
-
#2. That method triggers CUI#parse_commandline and passes ARGV to it.
|
61
|
-
#3. #parse_commandline analyses the array it receives and figures out
|
62
|
-
# what command class inside the CUICommands module to instantiate.
|
63
|
-
#4. CUICommand::Command.new calls #parse on the instantiated Command
|
64
|
-
# object (this is a subclass of CUICommand::Command). Note that
|
65
|
-
# smc-get has not been set up for now, and calls to
|
66
|
-
# the like will fail.
|
67
|
-
#5. The user calls CUI#start.
|
68
|
-
#6. #start looks into @command and invokes the #execute method on it.
|
69
|
-
#7. #start shuts down the interpreter via #exit. If the command execution
|
70
|
-
# method returned an integer value, it is used as the exit status.
|
71
|
-
#
|
72
|
-
#Have a look at the existing commands to see how it works. Especially
|
73
|
-
#+help+ is quite easy to understand, so begin there.
|
74
|
-
class CUI
|
75
|
-
|
76
|
-
#Default location of the configuration file.
|
77
|
-
DEFAULT_CONFIG_FILE = CONFIG_DIR + "smc-get.yml"
|
78
|
-
#
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
#
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
str
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
-
|
106
|
-
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
global
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
#
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
#
|
171
|
-
#
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
rescue
|
182
|
-
$stderr.puts(
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
#
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
1
|
+
#Encoding: UTF-8
|
2
|
+
################################################################################
|
3
|
+
# This file is part of smc-get.
|
4
|
+
# Copyright (C) 2010-2011 Entertaining Software, Inc.
|
5
|
+
# Copyright (C) 2011 Marvin Gülker
|
6
|
+
#
|
7
|
+
# This program is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
################################################################################
|
20
|
+
|
21
|
+
#Load all the files in the cui_commands directory.
|
22
|
+
require_relative "cui_commands/command"
|
23
|
+
Dir[File.join(File.expand_path(File.dirname(__FILE__)), "cui_commands", "*.rb")].each do |filename|
|
24
|
+
require_relative "cui_commands/#{File.basename(filename)}"
|
25
|
+
end
|
26
|
+
|
27
|
+
module SmcGet
|
28
|
+
|
29
|
+
#This is the Console User Interface smc-get exposes. Each command
|
30
|
+
#is represented by a class in the CUICommands module. Those classes
|
31
|
+
#have three methods: ::help, which should return a summary on how to use
|
32
|
+
#the command (NOT print it, that's done by an internal method), #parse,
|
33
|
+
#which gets the command-line for the subcommand passed in form of an
|
34
|
+
#array you should destructively (i.e. removing the elements) analyse,
|
35
|
+
#and #execute which finally executes the command. You are free to print out
|
36
|
+
#anything inside that method.
|
37
|
+
#
|
38
|
+
#Note that inside the #parse method you can set instance variables
|
39
|
+
#as you would do for any normal class. You can then grep their values
|
40
|
+
#inside the #execute method. Furthermore, if inside #parse you detect
|
41
|
+
#an error in the commandline the user provided to you, raise the
|
42
|
+
#CUI::InvalidCommandline exception with a meaningful message which will
|
43
|
+
#then be presented to the user.
|
44
|
+
#
|
45
|
+
#The last things one should do when adding a command, is to provide
|
46
|
+
#a ::help class method that returns help on the usage of the command
|
47
|
+
#(it will be called when the user issues <tt>smc-get help YOURCOMMAND</tt>
|
48
|
+
#and it's return value will be shown to the user) and to provide
|
49
|
+
#a ::summary class method whose return value is integrated in the
|
50
|
+
#output of <tt>smc-get help</tt> under the COMMANDS section.
|
51
|
+
#
|
52
|
+
#In every method you add, you can make use of the CUI.debug method. If you
|
53
|
+
#hand it a string, it will be printed only if running in debug mode, and
|
54
|
+
#if you hand it any other object, it's +inspect+ value will be printed--if
|
55
|
+
#running in debug mode. See the SmcGet::CUICommands::Command class's
|
56
|
+
#documentation for more information on the hook methods.
|
57
|
+
#
|
58
|
+
#Internally the flow is as follows:
|
59
|
+
#1. The user calls CUI#initialize with ARGV.
|
60
|
+
#2. That method triggers CUI#parse_commandline and passes ARGV to it.
|
61
|
+
#3. #parse_commandline analyses the array it receives and figures out
|
62
|
+
# what command class inside the CUICommands module to instantiate.
|
63
|
+
#4. CUICommand::Command.new calls #parse on the instantiated Command
|
64
|
+
# object (this is a subclass of CUICommand::Command). Note that
|
65
|
+
# smc-get has not been set up for now, and calls to Repository#install or
|
66
|
+
# the like will fail.
|
67
|
+
#5. The user calls CUI#start.
|
68
|
+
#6. #start looks into @command and invokes the #execute method on it.
|
69
|
+
#7. #start shuts down the interpreter via #exit. If the command execution
|
70
|
+
# method returned an integer value, it is used as the exit status.
|
71
|
+
#
|
72
|
+
#Have a look at the existing commands to see how it works. Especially
|
73
|
+
#+help+ is quite easy to understand, so begin there.
|
74
|
+
class CUI
|
75
|
+
|
76
|
+
#Default location of the configuration file.
|
77
|
+
DEFAULT_CONFIG_FILE = CONFIG_DIR + "smc-get.yml"
|
78
|
+
#The user’s personal directory.
|
79
|
+
USER_DIR = Pathname.new(ENV["HOME"])
|
80
|
+
#The user-level smc-get configuration file.
|
81
|
+
USER_CONFIG_FILE = USER_DIR + ".smc-get-conf.yml"
|
82
|
+
#A user’s personal SMC data directory.
|
83
|
+
USER_SMC_DIR = USER_DIR + ".smc"
|
84
|
+
#The help message displayed to the user when issueing "help".
|
85
|
+
GENERAL_HELP =<<EOF
|
86
|
+
USAGE:
|
87
|
+
#{File.basename($0)} [OPTIONS] COMMAND [PARAMETERS...]
|
88
|
+
|
89
|
+
DESCRIPTION:
|
90
|
+
Install and uninstall levels from the Secret Maryo Chronicles contributed level
|
91
|
+
repository.
|
92
|
+
|
93
|
+
COMMANDS:
|
94
|
+
#{str = ''
|
95
|
+
CUICommands.constants.sort.each do |c|
|
96
|
+
next if c == :Command or c == :InvalidCommandline
|
97
|
+
str << ' ' << CUICommands.const_get(c).summary << "\n"
|
98
|
+
end
|
99
|
+
str}
|
100
|
+
|
101
|
+
Use "help COMMAND" to get help on a specific command. "help" without an
|
102
|
+
argument displays this message.
|
103
|
+
|
104
|
+
OPTIONS FOR #{File.basename($0).upcase} ITSELF
|
105
|
+
-c\t--config-file FILE\tUse FILE as the configuration file.
|
106
|
+
-d\t--data-directory DIR\tSet the directory where to save packages into.
|
107
|
+
-D\t--debug\t\t\tEnter debug mode. A normal user shouldn't use this.
|
108
|
+
-r\t--repo-url URL\t\tSet the URL of the remote package repository.
|
109
|
+
|
110
|
+
CONFIGURATION FILES
|
111
|
+
You can use three kinds of configuration files with #{File.basename($0)}. They are,
|
112
|
+
in the order in which they are evaluated:
|
113
|
+
|
114
|
+
1. Global configuration file #{DEFAULT_CONFIG_FILE}.
|
115
|
+
2. If existant, user-level configuration file #{USER_CONFIG_FILE}.
|
116
|
+
3. If existant, configuration file given on the commandline via the -c option.
|
117
|
+
|
118
|
+
Configuration files loaded later overwrite values set in previously loaded
|
119
|
+
configuration files, i.e. values set in the configuration file provided via
|
120
|
+
the commandline override those in the global and user-level configuration
|
121
|
+
file, and those in the user-level configuration file override those in the
|
122
|
+
global configuration file, etc.
|
123
|
+
There is a 4th way to set options for #{File.basename($0)}:
|
124
|
+
|
125
|
+
4. Options given via the commandline
|
126
|
+
|
127
|
+
They override anything set in the configuration files, so specifying
|
128
|
+
'-d /opt/smc' on the commandline would override any 'data_directory'
|
129
|
+
setting in any of the configuration files.
|
130
|
+
|
131
|
+
BUG REPORTING
|
132
|
+
|
133
|
+
Report bugs at: https://github.com/Luiji/smc-get/issues
|
134
|
+
|
135
|
+
OTHER
|
136
|
+
|
137
|
+
smc-get project page: https://github.com/Luiji/smc-get
|
138
|
+
smc home page: http://www.secretmaryo.org/
|
139
|
+
EOF
|
140
|
+
|
141
|
+
attr_reader :config
|
142
|
+
attr_reader :remote_repository
|
143
|
+
attr_reader :local_repository
|
144
|
+
|
145
|
+
#Writes <tt>obj.inspect</tt> to $stdout if the CUI is running in debug
|
146
|
+
#mode. If +obj+ is a string, it is simply written out.
|
147
|
+
def self.debug(obj)
|
148
|
+
if @DEBUG_MODE
|
149
|
+
if obj.kind_of? String
|
150
|
+
puts obj
|
151
|
+
else
|
152
|
+
puts(obj.inspect)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
@DEBUG_MODE = false
|
158
|
+
|
159
|
+
#Returns wheather or not we're running in debug mode.
|
160
|
+
def self.debug_mode?
|
161
|
+
@DEBUG_MODE
|
162
|
+
end
|
163
|
+
|
164
|
+
#Set to +true+ to enable debug mode.
|
165
|
+
def self.debug_mode=(val)
|
166
|
+
@DEBUG_MODE = val
|
167
|
+
end
|
168
|
+
|
169
|
+
#Creates a new CUI. Pass in ARGV or a set of command-line arguments
|
170
|
+
#you want to and read this class's documentation for knowing what
|
171
|
+
#happens then. Call #start on the returned object when you want
|
172
|
+
#to execute everything.
|
173
|
+
def initialize(argv)
|
174
|
+
@config = {}
|
175
|
+
parse_commandline(argv)
|
176
|
+
load_config_file
|
177
|
+
SmcGet.setup
|
178
|
+
begin
|
179
|
+
@local_repository = SmcGet::LocalRepository.new(@config[:data_directory])
|
180
|
+
@remote_repository = SmcGet::RemoteRepository.new(@config[:repo_url])
|
181
|
+
rescue Errors::InvalidRepository => e
|
182
|
+
$stderr.puts("WARNING: Couldn't connect to this repository:")
|
183
|
+
$stderr.puts(e.repository_uri)
|
184
|
+
$stderr.puts("Reason: #{e.message}")
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
#Starts executing of the CUI. This method never returns, it
|
189
|
+
#calls #exit after the command has finished.
|
190
|
+
def start
|
191
|
+
begin
|
192
|
+
ret = @command.execute(@config)
|
193
|
+
#If numbers are returned they are supposed to be the exit code.
|
194
|
+
if ret.kind_of? Integer
|
195
|
+
exit ret
|
196
|
+
else
|
197
|
+
exit
|
198
|
+
end
|
199
|
+
rescue Errno::EACCES, Errors::SmcGetError => e
|
200
|
+
$stderr.puts("ERROR: #{e.message}") #All SmcGetErrors should have an informative message (and the EACCES one too)
|
201
|
+
if self.class.debug_mode?
|
202
|
+
$stderr.puts "====DEBUGGING INFORMATION===="
|
203
|
+
$stderr.puts "Class: #{e.class}"
|
204
|
+
$stderr.puts "Message: #{e.message}"
|
205
|
+
$stderr.puts "Backtrace: #{e.backtrace.join("\n\t")}"
|
206
|
+
end
|
207
|
+
exit 2
|
208
|
+
rescue => e #Ouch. Fatal error not intended.
|
209
|
+
$stderr.puts("[BUG] #{e.class}")
|
210
|
+
$stderr.puts("Please file a bug report at https://github.com/Luiji/smc-get/issues")
|
211
|
+
$stderr.puts("and attach this message. Describe what you did so we can")
|
212
|
+
$stderr.puts("reproduce it. ")
|
213
|
+
raise #Bubble up
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
private
|
218
|
+
|
219
|
+
#Destructively searches through +argv+ (i.e. emptying it) and
|
220
|
+
#sets the CLI up. Besides when +help+ is used as the
|
221
|
+
#command, nothing is actually executed.
|
222
|
+
#
|
223
|
+
#This method instantiates one of the various classes in the
|
224
|
+
#CUICommands module, making smc-get easily extendable by
|
225
|
+
#adding a new class inside that module.
|
226
|
+
def parse_commandline(argv)
|
227
|
+
#Get options for smc-get itself, rather than it's subcommands. Values set
|
228
|
+
#here override anything set in any configuration file; but since the
|
229
|
+
#keys are turned to symbols in #load_config_file, we have to use
|
230
|
+
#strings as keys here (otherwise merging with the config files'
|
231
|
+
#settings would fail).
|
232
|
+
@cmd_config = nil
|
233
|
+
while !argv.empty? and argv.first.start_with?("-") #All options start with a hyphen, commands cannot
|
234
|
+
arg = argv.shift
|
235
|
+
case arg
|
236
|
+
when "-c", "--config-file" then @cmd_config = Pathname.new(argv.shift)
|
237
|
+
when "-d", "--data-directory" then @config["data_directory"] = argv.shift
|
238
|
+
when "-D", "--debug" then CUI.debug_mode = true
|
239
|
+
when "-r", "--repo-url" then @config["repo_url"] = argv.shift
|
240
|
+
else
|
241
|
+
$stderr.puts("Invalid option #{arg}.")
|
242
|
+
$stderr.puts("Try #$0 help.")
|
243
|
+
exit 1
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
#If nothing is left, the command was left out. Assume 'help'.
|
248
|
+
argv << "help" if argv.empty?
|
249
|
+
|
250
|
+
#Now parse the subcommand.
|
251
|
+
command = argv.shift.to_sym
|
252
|
+
CUI.debug("Found subcommand #{command}.")
|
253
|
+
sym = :"#{command.capitalize}Command"
|
254
|
+
begin
|
255
|
+
if CUICommands.const_defined?(sym)
|
256
|
+
begin
|
257
|
+
@command = CUICommands.const_get(sym).new(self, argv)
|
258
|
+
rescue CUICommands::InvalidCommandline => e
|
259
|
+
$stderr.puts(e.message)
|
260
|
+
$stderr.puts("Try #$0 help.")
|
261
|
+
exit 1
|
262
|
+
end
|
263
|
+
else
|
264
|
+
$stderr.puts "Unrecognized command #{command}. Try 'help'."
|
265
|
+
exit 1
|
266
|
+
end
|
267
|
+
rescue NameError => e
|
268
|
+
$stderr.puts "Unrecognized command #{command}. Try 'help'."
|
269
|
+
if CUI.debug_mode?
|
270
|
+
$stderr.puts("Class: #{e.class}")
|
271
|
+
$stderr.puts("Message: #{e.message}")
|
272
|
+
$stderr.puts("Backtrace:")
|
273
|
+
$stderr.puts(e.backtrace.join("\n\t"))
|
274
|
+
end
|
275
|
+
exit 1
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
#Loads the configuration file from the <b>config/</b> directory.
|
280
|
+
def load_config_file
|
281
|
+
#First, load the global configuration file.
|
282
|
+
CUI.debug("Loading global config #{DEFAULT_CONFIG_FILE}.")
|
283
|
+
hsh = YAML.load_file(DEFAULT_CONFIG_FILE)
|
284
|
+
CUI.debug(hsh)
|
285
|
+
|
286
|
+
#Second, load the user config which overrides values set in
|
287
|
+
#the global config.
|
288
|
+
CUI.debug("Loading user-level config #{USER_CONFIG_FILE}.")
|
289
|
+
if USER_CONFIG_FILE.file?
|
290
|
+
hsh.merge!(YAML.load_file(USER_CONFIG_FILE.to_s))
|
291
|
+
else
|
292
|
+
CUI.debug("Not found.")
|
293
|
+
end
|
294
|
+
CUI.debug(hsh)
|
295
|
+
|
296
|
+
#Third, load the config file from the commandline, if any. This overrides
|
297
|
+
#values set in the user and global config.
|
298
|
+
if @cmd_config
|
299
|
+
CUI.debug("Loading -c option config #{@cmd_config}.")
|
300
|
+
if @cmd_config.file?
|
301
|
+
hsh.merge!(YAML.load_file(@cmd_config.to_s))
|
302
|
+
else
|
303
|
+
$stderr.puts("Configuration file #{@cmd_config} not found.")
|
304
|
+
end
|
305
|
+
CUI.debug(hsh)
|
306
|
+
end
|
307
|
+
|
308
|
+
#Fourth, check for values on the commandline. They override anything
|
309
|
+
#set previously. They are set directly in @config, so we simply have
|
310
|
+
#to retain the old values in it.
|
311
|
+
CUI.debug("Loading commandline options.")
|
312
|
+
@config.merge!(hsh){|key, old_val, new_val| old_val}
|
313
|
+
CUI.debug(@config)
|
314
|
+
|
315
|
+
#Fifth, turn all keys into symbols, because that's more Ruby-like.
|
316
|
+
CUI.debug("Converting to symbols.")
|
317
|
+
@config = Hash[@config.map{|k, v| [k.to_sym, v]}]
|
318
|
+
CUI.debug(@config)
|
319
|
+
end
|
320
|
+
|
321
|
+
end
|
322
|
+
|
323
|
+
end
|
324
|
+
|
325
|
+
# vim:set ts=8 sts=2 sw=2 et: #
|