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/README.md +26 -12
- data/VERSION +1 -1
- data/bin/ki +21 -0
- data/docs/backlog.md +35 -0
- data/docs/development.md +45 -0
- data/docs/development_setup.md +49 -0
- data/{lib/ki-repo.rb → docs/images/for_git.txt} +0 -0
- data/docs/ki_commands.md +202 -0
- data/docs/repository_basics.md +171 -0
- data/docs/writing_extensions.md +50 -0
- data/lib/cmd/cmd.rb +224 -0
- data/lib/cmd/user_pref_cmd.rb +122 -0
- data/lib/cmd/version_cmd.rb +483 -0
- data/lib/data_access/repository_finder.rb +200 -0
- data/lib/data_access/repository_info.rb +153 -0
- data/lib/data_access/version_helpers.rb +242 -0
- data/lib/data_access/version_iterators.rb +145 -0
- data/lib/data_access/version_operations.rb +80 -0
- data/lib/data_storage/dir_base.rb +106 -0
- data/lib/data_storage/ki_home.rb +44 -0
- data/lib/data_storage/ki_json.rb +153 -0
- data/lib/data_storage/repository.rb +91 -0
- data/lib/data_storage/version_metadata.rb +141 -0
- data/lib/ki_repo_all.rb +42 -0
- data/lib/util/attr_chain.rb +258 -0
- data/lib/util/exception_catcher.rb +118 -0
- data/lib/util/hash.rb +46 -0
- data/lib/util/hash_cache.rb +31 -0
- data/lib/util/ruby_extensions.rb +137 -0
- data/lib/util/service_registry.rb +88 -0
- data/lib/util/simple_optparse.rb +103 -0
- data/lib/util/test.rb +323 -0
- metadata +69 -13
- data/.document +0 -5
- data/.rspec +0 -1
- data/Gemfile +0 -14
- data/Gemfile.lock +0 -38
- data/Rakefile +0 -42
- data/spec/ki-repo_spec.rb +0 -6
- data/spec/spec_helper.rb +0 -12
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
|