ki-repo 0.1.0 → 0.1.1

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/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