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/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
@@ -0,0 +1,106 @@
|
|
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
|
+
module DirectoryBaseModule
|
19
|
+
attr_chain :parent, :require
|
20
|
+
|
21
|
+
def init_from_path(path)
|
22
|
+
@path = path
|
23
|
+
end
|
24
|
+
|
25
|
+
def name
|
26
|
+
File.basename(@path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def go(*path)
|
30
|
+
if path.empty?
|
31
|
+
self
|
32
|
+
else
|
33
|
+
path = File.join(path).split(File::Separator)
|
34
|
+
child = child(path.delete_at(0)).parent(self)
|
35
|
+
if path.empty?
|
36
|
+
child
|
37
|
+
else
|
38
|
+
child.go(*path)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def exists?(*sub_path)
|
44
|
+
File.exists?(go(*sub_path).path)
|
45
|
+
end
|
46
|
+
|
47
|
+
def mkdir(*path)
|
48
|
+
dest = go(*path)
|
49
|
+
if !dest.exists?
|
50
|
+
FileUtils.mkdir_p(dest.path)
|
51
|
+
end
|
52
|
+
dest
|
53
|
+
end
|
54
|
+
|
55
|
+
def path(*sub_paths)
|
56
|
+
new_path = [@path, sub_paths].flatten
|
57
|
+
if defined? @parent
|
58
|
+
new_path.unshift(@parent.path)
|
59
|
+
end
|
60
|
+
File.join(new_path)
|
61
|
+
end
|
62
|
+
|
63
|
+
def root
|
64
|
+
if defined? @parent
|
65
|
+
@parent.root
|
66
|
+
else
|
67
|
+
self
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def root?
|
72
|
+
!defined? @parent
|
73
|
+
end
|
74
|
+
|
75
|
+
def ki_path(*sub_paths)
|
76
|
+
if defined? @parent
|
77
|
+
paths = [@parent.ki_path, @path]
|
78
|
+
else
|
79
|
+
paths = ["/"]
|
80
|
+
end
|
81
|
+
File.join([paths, sub_paths].flatten)
|
82
|
+
end
|
83
|
+
|
84
|
+
def child(name)
|
85
|
+
DirectoryBase.new(name)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
class DirectoryBase
|
90
|
+
include DirectoryBaseModule
|
91
|
+
|
92
|
+
def initialize(path)
|
93
|
+
init_from_path(path)
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.find!(path, *locations)
|
97
|
+
locations.each do |loc|
|
98
|
+
dest = loc.go(path)
|
99
|
+
if dest.exists?
|
100
|
+
return dest
|
101
|
+
end
|
102
|
+
end
|
103
|
+
raise "Could not find '#{path}' from '#{locations.map { |l| l.path }.join("', '")}'"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,44 @@
|
|
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
|
+
module RepositoryMethods
|
19
|
+
DirectoryWithChildrenInListFile.add_list_file(self, Repository::Repository)
|
20
|
+
|
21
|
+
# repositories are stored under repositories directory
|
22
|
+
class RepositoryListFile
|
23
|
+
undef :create_list_item
|
24
|
+
def create_list_item(item)
|
25
|
+
Repository::Repository.new("repositories/" + item).parent(parent).repository_id(item)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def finder
|
30
|
+
RepositoryFinder.new(self)
|
31
|
+
end
|
32
|
+
|
33
|
+
def version(*args, &block)
|
34
|
+
finder.version(*args, &block)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class KiHome < DirectoryBase
|
39
|
+
include RepositoryMethods
|
40
|
+
def self.ki_version
|
41
|
+
IO.read(File.expand_path(File.join(File.dirname(__FILE__),"../..", 'VERSION')))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,153 @@
|
|
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
|
+
require 'json'
|
19
|
+
|
20
|
+
# Base implementation for json files.
|
21
|
+
# * DirectoryBase takes a path argument where file will exist
|
22
|
+
# * Classes inheriting this file should implement json_default() to define default data object
|
23
|
+
# * cached_data loads data from disk when first accessed and edit_data modifies it
|
24
|
+
# * helper methods should access data through cached_data
|
25
|
+
class KiJSONFile < DirectoryBase
|
26
|
+
attr_chain :cached_data, -> { load_data_from_file }
|
27
|
+
|
28
|
+
# Loads latest data from file path. Does not update cached_data
|
29
|
+
def load_data_from_file(default=json_default)
|
30
|
+
KiJSONFile.load_json(path, default)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Loads data from file path, makes it editable and saves data
|
34
|
+
def edit_data(&block)
|
35
|
+
@cached_data = load_data_from_file
|
36
|
+
block.call(self)
|
37
|
+
File.safe_write(path, JSON.pretty_generate(@cached_data))
|
38
|
+
@cached_data
|
39
|
+
end
|
40
|
+
|
41
|
+
# Saves data to file path. Does not update cached_data
|
42
|
+
def save(data=cached_data)
|
43
|
+
File.safe_write(path, JSON.pretty_generate(data))
|
44
|
+
end
|
45
|
+
|
46
|
+
def size
|
47
|
+
cached_data.size
|
48
|
+
end
|
49
|
+
|
50
|
+
def KiJSONFile.load_json(path, default=nil)
|
51
|
+
if File.exists?(path)
|
52
|
+
JSON.parse(IO.read(path))
|
53
|
+
else
|
54
|
+
default
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def reset_cached_data
|
59
|
+
remove_instance_variable(:@cached_data)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Base implementation for Json list file
|
64
|
+
class KiJSONListFile < KiJSONFile
|
65
|
+
include Enumerable
|
66
|
+
attr_chain :json_default, -> { Array.new }
|
67
|
+
|
68
|
+
def create_list_item(obj)
|
69
|
+
obj
|
70
|
+
end
|
71
|
+
|
72
|
+
def add_item(obj)
|
73
|
+
edit_data do
|
74
|
+
@cached_data << obj
|
75
|
+
end
|
76
|
+
create_list_item(obj)
|
77
|
+
end
|
78
|
+
|
79
|
+
def each(&block)
|
80
|
+
cached_data.each do |obj|
|
81
|
+
block.call(create_list_item(obj))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Base implementation Json hash file
|
87
|
+
#
|
88
|
+
# Inheriting classes should implement their values using CachedMapDataAccessor
|
89
|
+
# class VersionMetadataFile < KiJSONHashFile {
|
90
|
+
# attr_chain :source, -> { Hash.new }, :accessor => CachedData
|
91
|
+
class KiJSONHashFile < KiJSONFile
|
92
|
+
include Enumerable
|
93
|
+
attr_chain :json_default, -> { Hash.new }
|
94
|
+
|
95
|
+
class CachedMapDataAccessor
|
96
|
+
def get(object, name)
|
97
|
+
object.cached_data[name.to_s]
|
98
|
+
end
|
99
|
+
|
100
|
+
def set(object, name, value)
|
101
|
+
object.cached_data[name.to_s] = value
|
102
|
+
end
|
103
|
+
|
104
|
+
def defined?(object, name)
|
105
|
+
object.cached_data.include?(name.to_s)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
CachedData = CachedMapDataAccessor.new
|
110
|
+
end
|
111
|
+
|
112
|
+
# Helper method for creating list files.
|
113
|
+
class DirectoryWithChildrenInListFile
|
114
|
+
# Helper method for creating list files. When called on a class it extends the class with:
|
115
|
+
# * class extending KiJSONListFile which stores list items: class VersionListFile
|
116
|
+
# * method to load the file: versions()
|
117
|
+
# * method to load a specific item from list file: version(version_id, versions_list=versions)
|
118
|
+
def self.add_list_file(obj, clazz, name=nil)
|
119
|
+
stripped_class_name = clazz.name.split("::").last
|
120
|
+
class_name = clazz.name
|
121
|
+
list_class_name = "#{stripped_class_name}ListFile"
|
122
|
+
create_id_name = stripped_class_name.gsub(/.[A-Z]/) { |s| "#{s[0]}_#{s[1]}" }.downcase
|
123
|
+
if name.nil?
|
124
|
+
name = create_id_name
|
125
|
+
end
|
126
|
+
pluralized_name = "#{name}s".gsub(/ys$/, "ies")
|
127
|
+
new_methods = <<METHODS
|
128
|
+
class #{list_class_name} < KiJSONListFile
|
129
|
+
def create_list_item(#{name}_id)
|
130
|
+
i = #{class_name}.new(#{name}_id)
|
131
|
+
i.parent(parent)
|
132
|
+
i.#{create_id_name}_id(#{name}_id)
|
133
|
+
i
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def #{pluralized_name}
|
138
|
+
#{list_class_name}.new("ki-#{pluralized_name}.json").parent(self)
|
139
|
+
end
|
140
|
+
|
141
|
+
def #{name}(#{name}_id, #{pluralized_name}_list=#{pluralized_name})
|
142
|
+
#{pluralized_name}_list.each do |c|
|
143
|
+
if c.#{name}_id == #{name}_id
|
144
|
+
return c
|
145
|
+
end
|
146
|
+
end
|
147
|
+
raise "#{class_name} '\#{#{name}_id}' not found"
|
148
|
+
end
|
149
|
+
METHODS
|
150
|
+
obj.class_eval(new_methods, __FILE__, (__LINE__ - new_methods.split("\n").size - 1))
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,91 @@
|
|
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
|
+
module Repository
|
19
|
+
# Contains information about a version for one repository
|
20
|
+
# * Files: ki-version.json, ki-statuses.json, ki-reverse-dependencies.json
|
21
|
+
# @see Component
|
22
|
+
# @see VersionMetadataFile
|
23
|
+
# @see VersionStatusFile
|
24
|
+
# @see KiJSONListFile
|
25
|
+
class Version < DirectoryBase
|
26
|
+
attr_chain :version_id, :require
|
27
|
+
attr_chain :metadata, -> {VersionMetadataFile.new("ki-version.json").json_default("version_id" => version_id).parent(self)}
|
28
|
+
|
29
|
+
def statuses
|
30
|
+
VersionStatusFile.new("ki-statuses.json").parent(self)
|
31
|
+
end
|
32
|
+
|
33
|
+
def reverse_dependencies
|
34
|
+
KiJSONListFile.new("ki-reverse-dependencies.json").parent(self)
|
35
|
+
end
|
36
|
+
|
37
|
+
def action_usage
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Contains information about a component for one repository
|
43
|
+
# * Files: ki-versions.json, status_info.json
|
44
|
+
# @see Version
|
45
|
+
# @see Repository
|
46
|
+
class Component < DirectoryBase
|
47
|
+
attr_chain :component_id, :require
|
48
|
+
DirectoryWithChildrenInListFile.add_list_file(self, Version)
|
49
|
+
|
50
|
+
# Chronological list of versions in this component
|
51
|
+
class VersionListFile
|
52
|
+
undef create_list_item
|
53
|
+
def create_list_item(item)
|
54
|
+
id = item["id"]
|
55
|
+
Version.new(id).version_id(File.join(parent.component_id, id)).parent(parent)
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_version(id, time=Time.now)
|
59
|
+
obj = {"id" => id, "time" => time}
|
60
|
+
edit_data do
|
61
|
+
@cached_data.unshift obj
|
62
|
+
end
|
63
|
+
create_list_item(obj)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Status information file. Hash that defines information about status fields
|
68
|
+
# * list defines order of statuses {"maturity": ["alpha","beta","gamma"]}
|
69
|
+
def status_info
|
70
|
+
KiJSONHashFile.new("status_info.json").parent(self)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Repository root
|
75
|
+
# * Files: ki-components.json
|
76
|
+
# @see Component
|
77
|
+
class Repository < DirectoryBase
|
78
|
+
attr_chain :repository_id, :require
|
79
|
+
DirectoryWithChildrenInListFile.add_list_file(self, Component)
|
80
|
+
|
81
|
+
# finds version matching the last part of version string, for example: my/component/1 looks for version named 1
|
82
|
+
# @see Component#version
|
83
|
+
def version(str)
|
84
|
+
args = str.split("/")
|
85
|
+
args.delete_at(-1)
|
86
|
+
component(args.join("/")).version(str)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
@@ -0,0 +1,141 @@
|
|
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
|
+
# Metadata
|
19
|
+
# * version_id String
|
20
|
+
# * build_info Hash. keys: source, tag, commiter. values=Strings
|
21
|
+
# * filesets Hash. keys: Sorted array of tags. values: List of File info Hash.
|
22
|
+
# * File info Hash. keys: path, size, executable, sha-1
|
23
|
+
# * dependencies List. values: Dependency Hash. keys: dependency_id, path, internal, dependency_operations
|
24
|
+
# * fileoperations
|
25
|
+
class VersionMetadataFile < KiJSONHashFile
|
26
|
+
attr_chain :version_id, :require, :accessor => CachedData
|
27
|
+
attr_chain :source, -> { Hash.new }, :accessor => CachedData
|
28
|
+
attr_chain :files, -> { Array.new }, :accessor => CachedData
|
29
|
+
attr_chain :operations, -> { Array.new }, :accessor => CachedData
|
30
|
+
attr_chain :dependencies, -> { Array.new }, :accessor => CachedData
|
31
|
+
|
32
|
+
def add_file_info(name, size, *args)
|
33
|
+
extra = (args.select { |arg| arg.kind_of?(Hash) }.size!(0..1).first or {})
|
34
|
+
tags = (args - [extra]).flatten.uniq
|
35
|
+
file_hash = {"path" => name, "size" => size}.merge(extra)
|
36
|
+
if tags.size > 0
|
37
|
+
file_hash["tags"]=tags
|
38
|
+
end
|
39
|
+
files << file_hash
|
40
|
+
end
|
41
|
+
|
42
|
+
# Comma separated list of dependency arguments
|
43
|
+
# * dependency parameters can be given in the hash
|
44
|
+
# TODO: version_id should be resolved through Version
|
45
|
+
def add_dependency(param_str, args={})
|
46
|
+
params = param_str.split(",")
|
47
|
+
version_id = params.delete_at(0)
|
48
|
+
dep_hash = {"version_id" => version_id}.merge(params.to_h("=")).merge(args)
|
49
|
+
if dep_hash["internal"]
|
50
|
+
dep_hash["internal"]=true
|
51
|
+
end
|
52
|
+
dep_hash.extend(DependencyMethods)
|
53
|
+
dependencies << dep_hash
|
54
|
+
dep_hash
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_operation(args)
|
58
|
+
operations << args
|
59
|
+
end
|
60
|
+
|
61
|
+
def VersionMetadataFile.calculate_hashes(full_path, digester_ids)
|
62
|
+
digesters = {}
|
63
|
+
digester_ids.each do |h|
|
64
|
+
digesters[h] = KiCommand::KiExtensions.find!(File.join("/hashing", h)).digest
|
65
|
+
end
|
66
|
+
algos = digesters.values
|
67
|
+
File.open(full_path, "r") do |io|
|
68
|
+
while (!io.eof)
|
69
|
+
buf = io.readpartial(1024)
|
70
|
+
algos.each do |digester|
|
71
|
+
digester.update(buf)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
digesters.each_pair do |h, digester|
|
76
|
+
digesters[h]=digester.hexdigest
|
77
|
+
end
|
78
|
+
digesters
|
79
|
+
end
|
80
|
+
|
81
|
+
# Processes all files from source that match patterns and for each file calculates hashes and stores tags based on default_parameters
|
82
|
+
def add_files(source, patterns, default_parameters={})
|
83
|
+
files_or_dirs = Array.wrap(patterns).map do |pattern|
|
84
|
+
Dir.glob(File.join(source, pattern))
|
85
|
+
end.flatten
|
86
|
+
|
87
|
+
files = files_or_dirs.map do |file_or_dir|
|
88
|
+
if File.directory?(file_or_dir)
|
89
|
+
Dir.glob(File.join(file_or_dir, "**/*"))
|
90
|
+
else
|
91
|
+
file_or_dir
|
92
|
+
end
|
93
|
+
end.flatten.sort
|
94
|
+
|
95
|
+
files.each do |file|
|
96
|
+
add_file(source, file, default_parameters)
|
97
|
+
end
|
98
|
+
self
|
99
|
+
end
|
100
|
+
|
101
|
+
def add_file(root, full_path, parameters)
|
102
|
+
stat = File.stat(full_path)
|
103
|
+
size = stat.size
|
104
|
+
extra = {}
|
105
|
+
if stat.executable?
|
106
|
+
extra["executable"]=true
|
107
|
+
end
|
108
|
+
if parameters["tags"]
|
109
|
+
tags = Array.wrap(parameters["tags"])
|
110
|
+
if tags && tags.size > 0
|
111
|
+
extra["tags"]= tags
|
112
|
+
end
|
113
|
+
end
|
114
|
+
if parameters["hashes"].nil?
|
115
|
+
parameters["hashes"]=["sha1"]
|
116
|
+
end
|
117
|
+
if parameters["hashes"].size > 0
|
118
|
+
extra.merge!(VersionMetadataFile.calculate_hashes(full_path, parameters["hashes"]))
|
119
|
+
end
|
120
|
+
add_file_info(full_path[root.size+1..-1], size, extra)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
module DependencyMethods
|
125
|
+
attr_chain :operations, -> { Array.new }, :accessor => AttrChain::HashAccess
|
126
|
+
|
127
|
+
def add_operation(args)
|
128
|
+
operations << args
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class VersionStatusFile < KiJSONListFile
|
133
|
+
def add_status(key, value, flags={})
|
134
|
+
add_item({"key" => key, "value" => value}.merge(flags))
|
135
|
+
end
|
136
|
+
|
137
|
+
def matching_statuses(key)
|
138
|
+
cached_data.select { |hash| hash["key"].match(key) }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
data/lib/ki_repo_all.rb
ADDED
@@ -0,0 +1,42 @@
|
|
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 'bundler/setup'
|
18
|
+
|
19
|
+
require_relative 'util/attr_chain'
|
20
|
+
require_relative 'util/exception_catcher'
|
21
|
+
require_relative 'util/ruby_extensions'
|
22
|
+
require_relative 'util/test'
|
23
|
+
require_relative 'util/service_registry'
|
24
|
+
require_relative 'util/hash'
|
25
|
+
require_relative 'util/hash_cache'
|
26
|
+
require_relative 'util/simple_optparse'
|
27
|
+
|
28
|
+
require_relative 'data_storage/dir_base'
|
29
|
+
require_relative 'data_storage/ki_json'
|
30
|
+
require_relative 'data_storage/repository'
|
31
|
+
require_relative 'data_storage/version_metadata'
|
32
|
+
require_relative 'data_storage/ki_home'
|
33
|
+
|
34
|
+
require_relative 'data_access/repository_info'
|
35
|
+
require_relative 'data_access/repository_finder'
|
36
|
+
require_relative 'data_access/version_helpers'
|
37
|
+
require_relative 'data_access/version_operations'
|
38
|
+
require_relative 'data_access/version_iterators'
|
39
|
+
|
40
|
+
require_relative 'cmd/cmd'
|
41
|
+
require_relative 'cmd/version_cmd'
|
42
|
+
require_relative 'cmd/user_pref_cmd'
|