ki-repo 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/cmd/cmd.rb ADDED
@@ -0,0 +1,224 @@
1
+ # encoding: UTF-8
2
+
3
+ # Copyright 2012 Mikko Apo
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'optparse'
18
+
19
+ module Ki
20
+
21
+ # Common launcher for all Ki commands
22
+ # * all command classes can register themselves using the register_cmd method
23
+ class KiCommand
24
+ # Shared command registry
25
+ KiExtensions = ServiceRegistry.new
26
+ CommandPrefix = "/commands/"
27
+
28
+ # Shared KiHome for commands
29
+ attr_chain :ki_home, -> { KiHome.new(ENV["KIHOME"] || File.expand_path(File.join("~", "ki"))).mkdir }
30
+
31
+ attr_chain :user_pref, -> { UserPrefFile.new.parent(ki_home) }
32
+
33
+ # Command classes are registered using this method
34
+ def self.register_cmd(name, clazz)
35
+ register(CommandPrefix + name, clazz)
36
+ end
37
+
38
+ def self.register(name, clazz)
39
+ KiExtensions.register(name, clazz)
40
+ end
41
+
42
+ def load_scripts
43
+ # load all script files defined in UserPrefFile uses
44
+ uses = @use.empty? ? user_pref.uses : @use
45
+ uses.each do |use_str|
46
+ ver, tags_str = use_str.split(":")
47
+ tags = tags_str ? tags_str.split(",") : "ki-cmd"
48
+ version = ki_home.version(ver)
49
+ version.find_files.tags(tags).file_list.each do |full_path|
50
+ load full_path
51
+ end
52
+ end
53
+ end
54
+
55
+ def find_cmd(name)
56
+ prefixed_command_names = user_pref.prefixes.map { |p| [p+name, p+"-"+name] }.flatten
57
+
58
+ # Finds all matching combinations of prefix+name -> there should be exactly one
59
+ all_commands = {}
60
+ KiExtensions.find("/commands").each { |(command, clazz)| all_commands[command[CommandPrefix.size..-1]]=clazz }
61
+ prefixed_command_names.unshift(name)
62
+ found_command_names = prefixed_command_names.select { |p| all_commands.key?(p) }
63
+
64
+ # abort if found_command_names.size != 1
65
+ if found_command_names.size > 1
66
+ raise "Multiple commands match: " + found_command_names.join(", ")
67
+ elsif found_command_names.size == 0
68
+ raise "No commands match: " + prefixed_command_names.join(", ")
69
+ end
70
+ found_command_name = found_command_names.first
71
+ initialize_cmd(all_commands[found_command_name], found_command_name)
72
+ end
73
+
74
+ def initialize_cmd(cmd_class, name)
75
+ cmd = cmd_class.new
76
+ if cmd.respond_to?(:shell_command=)
77
+ cmd.shell_command="#{$0} #{name}"
78
+ end
79
+ cmd
80
+ end
81
+
82
+ # bin/kaiju command line tool calls this method, which finds the correct class to manage the execution
83
+ def execute(args)
84
+ @use = []
85
+ my_args = opts.parse(args.dup)
86
+ load_scripts
87
+ if my_args.empty?
88
+ KiCommandHelp.new.shell_command("#{0} help").execute(self, [])
89
+ else
90
+ find_cmd(my_args.delete_at(0)).execute(self, my_args)
91
+ end
92
+ end
93
+
94
+ def opts
95
+ o = SimpleOptionParser.new do |opts|
96
+ opts.on("-h", "--home HOME-PATH", "Path to Ki root directory") do |v|
97
+ ki_home(KiHome.new(v))
98
+ end
99
+ opts.on("-u", "--use VER", "Use defined scripts") do |v|
100
+ @use << v
101
+ end
102
+ end
103
+ o
104
+ end
105
+
106
+ def help
107
+ <<EOF
108
+ "ki" is the main command line tool that starts all other Ki processes. Whenever ki command line tools
109
+ are executed, ki goes through the following startup process
110
+
111
+ 1. Common command line parameters are parsed. These can used to set execution parameters for this invocation.
112
+ 2. Extension scripts are loaded from repository. Version configuration is from either -u or user preferences
113
+ 3. Find command by name
114
+ 4. Execute the command and pass rest of the command line parameters
115
+
116
+ Examples
117
+
118
+ ki build-version *.txt
119
+ ki -u my/tools compile
120
+ ki -u my/tools:scripts,tools compile
121
+
122
+ note: By default only files with tag "ki-cmd" are used. Use the 'my/tools:scripts,tools' to define additional tags.
123
+
124
+ Common parameters:
125
+
126
+ #{opts}
127
+ EOF
128
+ end
129
+ end
130
+
131
+ # Displays help for given command
132
+ class KiCommandHelp
133
+ # Summary
134
+ attr_chain :summary, -> { "Displays help for given Ki command" }
135
+ attr_chain :shell_command, :require
136
+
137
+ def help
138
+ <<EOF
139
+ "#{shell_command}" shows information Ki and its commands.
140
+
141
+ ### Examples
142
+
143
+ #{shell_command}
144
+ #{shell_command} version-build
145
+ EOF
146
+ end
147
+
148
+ # Finds matching command and displays its help
149
+ def execute(ctx, args)
150
+ if args.size == 1
151
+ puts ctx.find_cmd(args.first).help
152
+ puts "Common ki options:\n#{ctx.opts}"
153
+ else
154
+ finder = ctx.ki_home.finder
155
+ puts <<EOF
156
+ ki-repo is a repository for storing packages and metadata.
157
+
158
+ #{help}
159
+ Info:
160
+ Home directory: #{ctx.ki_home.path}
161
+ Repositories:
162
+ #{finder.all_repositories.map { |repo| " - #{repo.path} (components: #{repo.components.size})" }.join("\n")}
163
+ Components in all repositories: #{finder.components.size}
164
+
165
+ Available commands:
166
+ EOF
167
+ KiInfoCommand.new.execute(ctx, ["-c"])
168
+
169
+ puts "\nRun '#{$0} help COMMAND' for more information about that command."
170
+ end
171
+ end
172
+ end
173
+
174
+ # Lists available Ki commands
175
+ class KiInfoCommand
176
+ # Summary
177
+ attr_chain :summary, -> { "Show information about Ki" }
178
+ attr_chain :shell_command, :require
179
+
180
+ # Finds all commands under /commands and outputs their id and summary
181
+ def execute(ctx, args)
182
+ opts.parse(args.empty? ? ["-c"] : args)
183
+ end
184
+
185
+ def help
186
+ <<EOF
187
+ "#{shell_command}" shows information about Ki.
188
+
189
+ ### Examples
190
+
191
+ #{shell_command} -c
192
+ #{shell_command} -r
193
+
194
+ ### Parameters
195
+ #{opts}
196
+ EOF
197
+ end
198
+
199
+ def opts
200
+ o = SimpleOptionParser.new do |opts|
201
+ opts.on("-c", "--commands", "List commands") do |v|
202
+ commands = KiCommand::KiExtensions.find(KiCommand::CommandPrefix[0..-2])
203
+ commands.each do |id, service_class|
204
+ puts " #{id[KiCommand::CommandPrefix.size..-1]}: #{service_class.new.summary}"
205
+ end
206
+ end
207
+ opts.on("-r", "--registered", "List all registered extensions") do |v|
208
+ by_parent = KiCommand::KiExtensions.by_parent
209
+ by_parent.keys.sort.each do |parent_key|
210
+ puts "#{parent_key}:"
211
+ by_parent[parent_key].each do |url, clazz|
212
+ puts " - #{url[parent_key.size+1..-1]} (#{clazz.name})"
213
+ end
214
+ end
215
+ end
216
+ end
217
+ o
218
+ end
219
+ end
220
+
221
+ KiCommand.register_cmd("help", KiCommandHelp)
222
+ KiCommand.register_cmd("ki-info", KiInfoCommand)
223
+
224
+ end
@@ -0,0 +1,122 @@
1
+ # encoding: UTF-8
2
+
3
+ # Copyright 2012 Mikko Apo
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module Ki
18
+
19
+ # File contains information for user
20
+ class UserPrefFile < KiJSONHashFile
21
+ attr_chain :uses, -> { Array.new }, :accessor => CachedData
22
+ attr_chain :prefixes, -> { Array.new }, :accessor => CachedData
23
+
24
+ def initialize
25
+ super("ki-user-pref.json")
26
+ end
27
+ end
28
+
29
+ # Sets user specific configurations
30
+ # @see UserPrefFile
31
+ class UserPrefCommand
32
+ attr_chain :shell_command
33
+
34
+ def help
35
+ <<EOF
36
+ #{summary}
37
+ Syntax: #{shell_command} prefix|use parameters...
38
+
39
+ ### Examples for command prefixes:
40
+ #{shell_command} prefix
41
+ - shows command prefixes, when a "ki command" is executed ki looks for the command with all prefix combinations
42
+ #{shell_command} prefix version package
43
+ - sets two command prefixes, looks for "command", "version-command" and "package-command"
44
+ #{shell_command} prefix + foo
45
+ - adds one command prefix to existing ones, looks for "command", "version-command", "package-command", "foo-command"
46
+ #{shell_command} prefix - package foo
47
+ - removes two command prefixes from list
48
+ #{shell_command} prefix -c
49
+ - clears command prefix list
50
+
51
+ ### Examples for automatic script loading:
52
+ #{shell_command} use
53
+ - shows list of automatically loading scripts. when ki starts up, it looks for all defined versions and loads all files tagged with ki-cmd
54
+ #{shell_command} use ki/http ki/ftp/123:ki-extra
55
+ - scripts are loaded from two different version. ki/http uses latest available version and files tagged with "ki-cmd", ki/ftp uses specific version and files tagged with "ki-extra"
56
+ #{shell_command} use + ki/scp
57
+ - adds one more script package version
58
+ #{shell_command} use - ki/scp ki/ftp/123:ki-extra
59
+ - removes two configurations
60
+ #{shell_command} use -c
61
+ - clear use list
62
+
63
+ EOF
64
+ end
65
+
66
+ def summary
67
+ "Sets user preferences"
68
+ end
69
+
70
+ def execute(ctx, args)
71
+ user_pref = ctx.user_pref
72
+ pref = args.delete_at(0)
73
+ if pref == "prefix"
74
+ arr = user_pref.prefixes
75
+ str = "Prefixes"
76
+ elsif pref == "use"
77
+ arr = user_pref.uses
78
+ str = "Use"
79
+ elsif pref.nil?
80
+ puts "User preferences:"
81
+ user_pref.cached_data.each_pair do |key, values|
82
+ if values && values.size > 0
83
+ puts "#{key}: " + values.join(", ")
84
+ end
85
+ end
86
+ else
87
+ raise "not supported: " + pref
88
+ end
89
+ if arr && str
90
+ args = opts(arr).parse(args)
91
+ if args.size > 0
92
+ if args[0] == "+"
93
+ args.delete_at(0)
94
+ arr.concat(args)
95
+ elsif args[0] == "-"
96
+ args.delete_at(0)
97
+ args.each do |a|
98
+ arr.delete(a)
99
+ end
100
+ else
101
+ arr.clear
102
+ arr.concat(args)
103
+ end
104
+ arr.uniq!
105
+ user_pref.save
106
+ end
107
+ puts "#{str}: " + arr.join(", ")
108
+ end
109
+ end
110
+
111
+ def opts(arr)
112
+ OptionParser.new do |opts|
113
+ opts.banner = ""
114
+ opts.on("-c", "--clear", "Clear existing preferences values for specified value") do |v|
115
+ arr.clear
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ KiCommand.register_cmd("pref", UserPrefCommand)
122
+ end