social_snippet 0.0.9 → 0.0.10
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.
- checksums.yaml +8 -8
- data/.travis.yml +11 -4
- data/README.md +6 -6
- data/Rakefile +19 -1
- data/lib/social_snippet.rb +11 -0
- data/lib/social_snippet/api/install_repository_api.rb +23 -82
- data/lib/social_snippet/api/manifest_api.rb +3 -3
- data/lib/social_snippet/api/update_repository_api.rb +34 -35
- data/lib/social_snippet/command_line/sspm/sub_commands/install_command.rb +7 -7
- data/lib/social_snippet/config.rb +18 -8
- data/lib/social_snippet/core.rb +13 -0
- data/lib/social_snippet/document.rb +2 -0
- data/lib/social_snippet/document_backend.rb +2 -0
- data/lib/social_snippet/document_backend/yaml_document.rb +252 -0
- data/lib/social_snippet/document_backend/yaml_document/query.rb +45 -0
- data/lib/social_snippet/repository.rb +2 -2
- data/lib/social_snippet/repository/driver_factory.rb +42 -0
- data/lib/social_snippet/repository/drivers.rb +3 -2
- data/lib/social_snippet/repository/drivers/driver_base.rb +100 -0
- data/lib/social_snippet/repository/drivers/entry.rb +11 -0
- data/lib/social_snippet/repository/drivers/git_driver.rb +100 -0
- data/lib/social_snippet/repository/models.rb +15 -0
- data/lib/social_snippet/repository/models/package.rb +97 -0
- data/lib/social_snippet/repository/models/repository.rb +94 -0
- data/lib/social_snippet/repository/repository_manager.rb +79 -67
- data/lib/social_snippet/resolvers/base_resolver.rb +13 -17
- data/lib/social_snippet/rspec/test_document.rb +305 -0
- data/lib/social_snippet/rspec/test_driver.rb +76 -0
- data/lib/social_snippet/rspec/test_storage.rb +459 -0
- data/lib/social_snippet/storage.rb +1 -0
- data/lib/social_snippet/storage_backend.rb +3 -0
- data/lib/social_snippet/storage_backend/file_system_storage.rb +71 -0
- data/lib/social_snippet/storage_backend/storage_base.rb +35 -0
- data/lib/social_snippet/version.rb +8 -3
- data/spec/helpers/codeclimate_helper.rb +1 -1
- data/spec/helpers/fakefs_helper.rb +10 -0
- data/spec/helpers/social_snippet_helper.rb +117 -0
- data/spec/lib/api/insert_snippet_spec.rb +95 -2
- data/spec/lib/api/update_repository_spec.rb +196 -0
- data/spec/lib/command_line/sspm_install_spec.rb +169 -180
- data/spec/lib/command_line/sspm_update_spec.rb +56 -0
- data/spec/lib/config_spec.rb +6 -8
- data/spec/lib/core_spec.rb +21 -38
- data/spec/lib/file_system_storage_spec.rb +170 -0
- data/spec/lib/insert_resolver_spec.rb +15 -2
- data/spec/lib/registry_client_spec.rb +6 -9
- data/spec/lib/repository/driver_base_spec.rb +89 -0
- data/spec/lib/repository/git_driver_spec.rb +10 -0
- data/spec/lib/repository/package_spec.rb +172 -0
- data/spec/lib/repository/repository_factory_spec.rb +67 -22
- data/spec/lib/repository/repository_manager_spec.rb +71 -114
- data/spec/lib/repository/repository_spec.rb +191 -0
- data/spec/lib/yaml_document_spec.rb +14 -0
- data/spec/spec_helper.rb +8 -93
- data/test/config_test.rb +6 -7
- data/test/driver_base_test.rb +201 -0
- data/test/git_driver_test.rb +51 -0
- data/test/insert_snippet_test.rb +256 -349
- data/test/repository_manager_test.rb +7 -16
- data/test/yaml_document_test.rb +97 -0
- metadata +44 -16
- data/lib/social_snippet/repository/drivers/base_repository.rb +0 -189
- data/lib/social_snippet/repository/drivers/git_repository.rb +0 -74
- data/lib/social_snippet/repository/repository_factory.rb +0 -59
- data/lib/social_snippet/repository/repository_installer.rb +0 -85
- data/spec/lib/repository/base_repository_spec.rb +0 -104
- data/spec/lib/repository/git_repository_spec.rb +0 -83
- data/spec/lib/repository/repository_installer_spec.rb +0 -63
- data/test/base_repository_test.rb +0 -375
- data/test/git_repository_test.rb +0 -114
data/lib/social_snippet/core.rb
CHANGED
@@ -3,26 +3,39 @@ class SocialSnippet::Core
|
|
3
3
|
attr_reader :input_stream
|
4
4
|
attr_reader :output_stream
|
5
5
|
attr_reader :repo_manager
|
6
|
+
attr_reader :driver_factory
|
6
7
|
attr_reader :config
|
7
8
|
attr_reader :registry_client
|
8
9
|
attr_reader :logger
|
9
10
|
attr_reader :api
|
10
11
|
attr_reader :prompt
|
12
|
+
attr_reader :storage
|
11
13
|
|
12
14
|
# Constructor
|
13
15
|
def initialize(new_input_stream = STDIN, new_output_stream = STDOUT)
|
14
16
|
@input_stream = new_input_stream
|
15
17
|
@output_stream = new_output_stream
|
18
|
+
@storage = ::SocialSnippet::Storage.new
|
16
19
|
@config = ::SocialSnippet::Config.new(self)
|
17
20
|
@logger = ::SocialSnippet::Logger.new output_stream
|
18
21
|
@prompt = ::HighLine.new(input_stream, output_stream)
|
19
22
|
init_logger
|
20
23
|
|
24
|
+
init_yaml_document
|
25
|
+
::SocialSnippet::Repository::Models::Package.core = self
|
26
|
+
::SocialSnippet::Repository::Models::Repository.core = self
|
21
27
|
@repo_manager = ::SocialSnippet::Repository::RepositoryManager.new(self)
|
28
|
+
@driver_factory = ::SocialSnippet::Repository::DriverFactory.new(self)
|
22
29
|
@registry_client = ::SocialSnippet::Registry::RegistryClient.new(self)
|
23
30
|
@api = ::SocialSnippet::Api.new(self)
|
24
31
|
end
|
25
32
|
|
33
|
+
def init_yaml_document
|
34
|
+
if ::SocialSnippet::Document == ::SocialSnippet::DocumentBackend::YAMLDocument
|
35
|
+
::SocialSnippet::DocumentBackend::YAMLDocument.set_path config.document_path
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
26
39
|
def init_logger
|
27
40
|
logger.level = ::SocialSnippet::Logger::Severity::INFO
|
28
41
|
logger.level = ::SocialSnippet::Logger::Severity::DEBUG if config.debug?
|
@@ -0,0 +1,252 @@
|
|
1
|
+
module SocialSnippet::DocumentBackend
|
2
|
+
|
3
|
+
$yaml_document_hash = nil
|
4
|
+
|
5
|
+
class YAMLDocument
|
6
|
+
|
7
|
+
@@path = nil
|
8
|
+
|
9
|
+
require_relative "yaml_document/query"
|
10
|
+
|
11
|
+
attr_reader :path
|
12
|
+
attr_reader :fields
|
13
|
+
|
14
|
+
attr_accessor :id
|
15
|
+
|
16
|
+
def initialize(options = {}, new_id = nil)
|
17
|
+
@path = @@path
|
18
|
+
@fields = ::Hash.new
|
19
|
+
init_fields options
|
20
|
+
@id ||= new_id || self.class.uuid
|
21
|
+
end
|
22
|
+
|
23
|
+
def field_keys
|
24
|
+
self.class.field_keys
|
25
|
+
end
|
26
|
+
|
27
|
+
def field_type
|
28
|
+
self.class.field_type
|
29
|
+
end
|
30
|
+
|
31
|
+
def serialize
|
32
|
+
attrs = field_keys.inject(::Hash.new) do |attrs, key|
|
33
|
+
attrs[key] = fields[key]
|
34
|
+
attrs
|
35
|
+
end
|
36
|
+
attrs[:id] = id
|
37
|
+
attrs
|
38
|
+
end
|
39
|
+
|
40
|
+
def clone_value(val)
|
41
|
+
if val.nil?
|
42
|
+
nil
|
43
|
+
else
|
44
|
+
val.clone
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def init_fields(options = {})
|
49
|
+
field_keys.each do |k|
|
50
|
+
fields[k] = clone_value(self.class.default_field[k])
|
51
|
+
end
|
52
|
+
options.each do |k, v|
|
53
|
+
fields[k] = clone_value(v)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def remove
|
58
|
+
self.class.collection.delete id
|
59
|
+
self.class.update_file!
|
60
|
+
end
|
61
|
+
|
62
|
+
def update_attributes!(attrs)
|
63
|
+
attrs.each do |key, value|
|
64
|
+
fields[key] = clone_value(value)
|
65
|
+
end
|
66
|
+
save!
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Persistence Methods
|
71
|
+
#
|
72
|
+
def save!
|
73
|
+
self.class.collection[id] = serialize
|
74
|
+
self.class.update_file!
|
75
|
+
end
|
76
|
+
|
77
|
+
def add_to_set(attrs)
|
78
|
+
attrs.each do |key, value|
|
79
|
+
fields[key].push value
|
80
|
+
fields[key].uniq!
|
81
|
+
end
|
82
|
+
save!
|
83
|
+
end
|
84
|
+
|
85
|
+
def push(attrs)
|
86
|
+
attrs.each do |key, value|
|
87
|
+
case field_type[key].to_s
|
88
|
+
when "Array"
|
89
|
+
fields[key].push value
|
90
|
+
when "Hash"
|
91
|
+
fields[key].merge! value
|
92
|
+
end
|
93
|
+
end
|
94
|
+
save!
|
95
|
+
end
|
96
|
+
|
97
|
+
def pull(attrs)
|
98
|
+
attrs.each do |key, value|
|
99
|
+
fields[key].delete value
|
100
|
+
end
|
101
|
+
save!
|
102
|
+
end
|
103
|
+
|
104
|
+
class << self
|
105
|
+
|
106
|
+
# "Callback invoked whenever a subclass of the current class is created."
|
107
|
+
# http://docs.ruby-lang.org/en/2.2.0/Class.html#method-i-inherited
|
108
|
+
def inherited(child)
|
109
|
+
load_file!
|
110
|
+
end
|
111
|
+
|
112
|
+
def yaml_document_hash
|
113
|
+
$yaml_document_hash ||= ::Hash.new
|
114
|
+
end
|
115
|
+
|
116
|
+
def reset_yaml_document_hash!
|
117
|
+
$yaml_document_hash = nil
|
118
|
+
end
|
119
|
+
|
120
|
+
def load_file!
|
121
|
+
$yaml_document_hash = ::YAML.load(::File.read path) unless path.nil?
|
122
|
+
end
|
123
|
+
|
124
|
+
def set_path(new_path)
|
125
|
+
@@path = new_path
|
126
|
+
::FileUtils.touch(path) unless ::File.exists?(path)
|
127
|
+
end
|
128
|
+
|
129
|
+
def path
|
130
|
+
@@path
|
131
|
+
end
|
132
|
+
|
133
|
+
def update_file!
|
134
|
+
::File.write path, yaml_document_hash.to_yaml
|
135
|
+
reset_yaml_document_hash!
|
136
|
+
load_file!
|
137
|
+
end
|
138
|
+
|
139
|
+
#
|
140
|
+
# Queries
|
141
|
+
#
|
142
|
+
def all
|
143
|
+
Query.new self, collection
|
144
|
+
end
|
145
|
+
|
146
|
+
def exists?
|
147
|
+
all.exists?
|
148
|
+
end
|
149
|
+
|
150
|
+
def count
|
151
|
+
all.count
|
152
|
+
end
|
153
|
+
|
154
|
+
def find(id)
|
155
|
+
if collection.has_key?(id)
|
156
|
+
new collection[id], id
|
157
|
+
else
|
158
|
+
raise "ERROR: document not found"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def find_by(cond)
|
163
|
+
result = collection.select do |item_key|
|
164
|
+
item = collection[item_key]
|
165
|
+
cond.keys.all? do |key|
|
166
|
+
cond[key] === item[key]
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
if result.empty?
|
171
|
+
raise "ERROR: document not found"
|
172
|
+
else
|
173
|
+
key, item = result.first
|
174
|
+
new item, item[:id]
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def find_or_create_by(cond)
|
179
|
+
if where(cond).exists?
|
180
|
+
find_by cond
|
181
|
+
else
|
182
|
+
create cond
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def where(cond)
|
187
|
+
Query.new(self, collection).find cond
|
188
|
+
end
|
189
|
+
|
190
|
+
def collection
|
191
|
+
yaml_document_hash[self.name] ||= ::Hash.new
|
192
|
+
end
|
193
|
+
|
194
|
+
def field_keys
|
195
|
+
@field_keys
|
196
|
+
end
|
197
|
+
|
198
|
+
def default_field
|
199
|
+
@default_field
|
200
|
+
end
|
201
|
+
|
202
|
+
def field_type
|
203
|
+
@field_type
|
204
|
+
end
|
205
|
+
|
206
|
+
def field(sym, options = {})
|
207
|
+
@field_keys ||= ::Set.new
|
208
|
+
@default_field ||= ::Hash.new
|
209
|
+
@field_type ||= ::Hash.new
|
210
|
+
|
211
|
+
default_field[sym] = options[:default] unless options[:default].nil?
|
212
|
+
|
213
|
+
field_keys.add sym
|
214
|
+
field_type[sym] = options[:type] || :String
|
215
|
+
|
216
|
+
# define getter
|
217
|
+
define_method sym do
|
218
|
+
@fields[sym]
|
219
|
+
end
|
220
|
+
|
221
|
+
# define setter
|
222
|
+
define_method "#{sym}=" do |v|
|
223
|
+
@fields[sym] = v
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def uuid
|
228
|
+
::SecureRandom.uuid
|
229
|
+
end
|
230
|
+
|
231
|
+
def create(options = {})
|
232
|
+
doc = new
|
233
|
+
options.each {|k, v| doc.send "#{k}=", v }
|
234
|
+
doc.id = uuid if doc.id.nil?
|
235
|
+
collection[doc.id] = doc.serialize
|
236
|
+
update_file!
|
237
|
+
doc
|
238
|
+
end
|
239
|
+
|
240
|
+
# replace self with ::SocialSnippet::Document class
|
241
|
+
def activate!
|
242
|
+
::SocialSnippet.class_eval do
|
243
|
+
remove_const :Document
|
244
|
+
const_set :Document, YAMLDocument
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
end # class << self
|
249
|
+
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module SocialSnippet::DocumentBackend
|
2
|
+
|
3
|
+
class YAMLDocument::Query
|
4
|
+
|
5
|
+
attr_reader :document_class
|
6
|
+
attr_reader :collection
|
7
|
+
|
8
|
+
def initialize(new_document_class, new_collection)
|
9
|
+
@document_class = new_document_class
|
10
|
+
@collection = new_collection
|
11
|
+
end
|
12
|
+
|
13
|
+
def exists?
|
14
|
+
collection.size > 0
|
15
|
+
end
|
16
|
+
|
17
|
+
def find(cond)
|
18
|
+
new_collection = collection.select do |item_id, item|
|
19
|
+
cond.all? {|k, _| cond[k] === item[k] }
|
20
|
+
end
|
21
|
+
self.class.new document_class, new_collection
|
22
|
+
end
|
23
|
+
|
24
|
+
def count
|
25
|
+
collection.length
|
26
|
+
end
|
27
|
+
|
28
|
+
def enum
|
29
|
+
collection.map do |_, item|
|
30
|
+
document_class.new item
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def each(&block)
|
35
|
+
enum.each &block
|
36
|
+
end
|
37
|
+
|
38
|
+
def map(&block)
|
39
|
+
enum.map &block
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module SocialSnippet::Repository; end
|
2
2
|
require_relative "repository/drivers"
|
3
|
-
require_relative "repository/
|
3
|
+
require_relative "repository/driver_factory"
|
4
4
|
require_relative "repository/repository_manager"
|
5
5
|
require_relative "repository/repository_errors"
|
6
|
-
require_relative "repository/
|
6
|
+
require_relative "repository/models"
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module SocialSnippet::Repository
|
2
|
+
|
3
|
+
class DriverFactory
|
4
|
+
|
5
|
+
@@drivers = [Drivers::GitDriver]
|
6
|
+
|
7
|
+
attr_reader :core
|
8
|
+
|
9
|
+
def initialize(new_core)
|
10
|
+
@core = new_core
|
11
|
+
end
|
12
|
+
|
13
|
+
def reset_drivers
|
14
|
+
@@drivers = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_driver(driver_class)
|
18
|
+
@@drivers.push driver_class
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param url [String] The URL of repository
|
22
|
+
# @reutrn [::SocialSnippet::Repository::Drivers::DriverBase]
|
23
|
+
def clone(url)
|
24
|
+
driver = resolve_driver(url)
|
25
|
+
driver.fetch
|
26
|
+
driver
|
27
|
+
end
|
28
|
+
|
29
|
+
def resolve_driver(url)
|
30
|
+
driver_class = @@drivers.select do |driver_class|
|
31
|
+
driver_class.target? url
|
32
|
+
end.first
|
33
|
+
if driver_class.nil?
|
34
|
+
raise "ERROR: driver not found"
|
35
|
+
else
|
36
|
+
driver_class.new url
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end # class << self
|
41
|
+
|
42
|
+
end # DriverFactory
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module SocialSnippet::Repository
|
2
|
+
|
3
|
+
# Repository base class
|
4
|
+
# usage: class GitDriver < DriverBase
|
5
|
+
class Drivers::DriverBase
|
6
|
+
|
7
|
+
attr_reader :url
|
8
|
+
|
9
|
+
# @example
|
10
|
+
# driver = Driver.new(url, ref)
|
11
|
+
# driver.fetch
|
12
|
+
# driver.cache # => save data into storage
|
13
|
+
def initialize(new_url)
|
14
|
+
@url = new_url
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns latest version
|
18
|
+
#
|
19
|
+
# @param pattern [String] The pattern of version
|
20
|
+
# @return [String] The version
|
21
|
+
def latest_version(pattern = "")
|
22
|
+
pattern = "" if pattern.nil?
|
23
|
+
matched_versions = versions.select {|ref| ::SocialSnippet::Version.is_matched_version_pattern(pattern, ref)}
|
24
|
+
::VersionSorter.rsort(matched_versions).first
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns all versions
|
28
|
+
#
|
29
|
+
# @return [Array<String>] All versions of repository
|
30
|
+
def versions
|
31
|
+
refs.select {|ref| ::SocialSnippet::Version.is_version(ref) }
|
32
|
+
end
|
33
|
+
|
34
|
+
def each_ref(&block)
|
35
|
+
refs.each &block
|
36
|
+
end
|
37
|
+
|
38
|
+
def has_versions?
|
39
|
+
not versions.empty?
|
40
|
+
end
|
41
|
+
|
42
|
+
def refs
|
43
|
+
raise "not implemented"
|
44
|
+
end
|
45
|
+
|
46
|
+
def snippet_json
|
47
|
+
raise "not implemented"
|
48
|
+
end
|
49
|
+
|
50
|
+
def rev_hash(ref)
|
51
|
+
raise "not implemented"
|
52
|
+
end
|
53
|
+
|
54
|
+
def current_ref
|
55
|
+
raise "not implemented"
|
56
|
+
end
|
57
|
+
|
58
|
+
def fetch
|
59
|
+
raise "not implemented"
|
60
|
+
end
|
61
|
+
|
62
|
+
def each_directory(ref)
|
63
|
+
raise "not implemented"
|
64
|
+
end
|
65
|
+
|
66
|
+
def each_file(ref)
|
67
|
+
raise "not implemented"
|
68
|
+
end
|
69
|
+
|
70
|
+
class << self
|
71
|
+
|
72
|
+
def target?(url)
|
73
|
+
if is_local_path?(url)
|
74
|
+
target_local_path?(url)
|
75
|
+
elsif is_url?(url)
|
76
|
+
target_url?(url)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def target_url?(url)
|
81
|
+
raise "not implemented"
|
82
|
+
end
|
83
|
+
|
84
|
+
def target_path?(path)
|
85
|
+
raise "not implemented"
|
86
|
+
end
|
87
|
+
|
88
|
+
def is_local_path?(s)
|
89
|
+
not /^[^:]*:\/\// === s
|
90
|
+
end
|
91
|
+
|
92
|
+
def is_url?(s)
|
93
|
+
::URI.regexp === s
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end # DriverBase
|
99
|
+
|
100
|
+
end # SocialSnippet
|