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.
Files changed (70) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +11 -4
  3. data/README.md +6 -6
  4. data/Rakefile +19 -1
  5. data/lib/social_snippet.rb +11 -0
  6. data/lib/social_snippet/api/install_repository_api.rb +23 -82
  7. data/lib/social_snippet/api/manifest_api.rb +3 -3
  8. data/lib/social_snippet/api/update_repository_api.rb +34 -35
  9. data/lib/social_snippet/command_line/sspm/sub_commands/install_command.rb +7 -7
  10. data/lib/social_snippet/config.rb +18 -8
  11. data/lib/social_snippet/core.rb +13 -0
  12. data/lib/social_snippet/document.rb +2 -0
  13. data/lib/social_snippet/document_backend.rb +2 -0
  14. data/lib/social_snippet/document_backend/yaml_document.rb +252 -0
  15. data/lib/social_snippet/document_backend/yaml_document/query.rb +45 -0
  16. data/lib/social_snippet/repository.rb +2 -2
  17. data/lib/social_snippet/repository/driver_factory.rb +42 -0
  18. data/lib/social_snippet/repository/drivers.rb +3 -2
  19. data/lib/social_snippet/repository/drivers/driver_base.rb +100 -0
  20. data/lib/social_snippet/repository/drivers/entry.rb +11 -0
  21. data/lib/social_snippet/repository/drivers/git_driver.rb +100 -0
  22. data/lib/social_snippet/repository/models.rb +15 -0
  23. data/lib/social_snippet/repository/models/package.rb +97 -0
  24. data/lib/social_snippet/repository/models/repository.rb +94 -0
  25. data/lib/social_snippet/repository/repository_manager.rb +79 -67
  26. data/lib/social_snippet/resolvers/base_resolver.rb +13 -17
  27. data/lib/social_snippet/rspec/test_document.rb +305 -0
  28. data/lib/social_snippet/rspec/test_driver.rb +76 -0
  29. data/lib/social_snippet/rspec/test_storage.rb +459 -0
  30. data/lib/social_snippet/storage.rb +1 -0
  31. data/lib/social_snippet/storage_backend.rb +3 -0
  32. data/lib/social_snippet/storage_backend/file_system_storage.rb +71 -0
  33. data/lib/social_snippet/storage_backend/storage_base.rb +35 -0
  34. data/lib/social_snippet/version.rb +8 -3
  35. data/spec/helpers/codeclimate_helper.rb +1 -1
  36. data/spec/helpers/fakefs_helper.rb +10 -0
  37. data/spec/helpers/social_snippet_helper.rb +117 -0
  38. data/spec/lib/api/insert_snippet_spec.rb +95 -2
  39. data/spec/lib/api/update_repository_spec.rb +196 -0
  40. data/spec/lib/command_line/sspm_install_spec.rb +169 -180
  41. data/spec/lib/command_line/sspm_update_spec.rb +56 -0
  42. data/spec/lib/config_spec.rb +6 -8
  43. data/spec/lib/core_spec.rb +21 -38
  44. data/spec/lib/file_system_storage_spec.rb +170 -0
  45. data/spec/lib/insert_resolver_spec.rb +15 -2
  46. data/spec/lib/registry_client_spec.rb +6 -9
  47. data/spec/lib/repository/driver_base_spec.rb +89 -0
  48. data/spec/lib/repository/git_driver_spec.rb +10 -0
  49. data/spec/lib/repository/package_spec.rb +172 -0
  50. data/spec/lib/repository/repository_factory_spec.rb +67 -22
  51. data/spec/lib/repository/repository_manager_spec.rb +71 -114
  52. data/spec/lib/repository/repository_spec.rb +191 -0
  53. data/spec/lib/yaml_document_spec.rb +14 -0
  54. data/spec/spec_helper.rb +8 -93
  55. data/test/config_test.rb +6 -7
  56. data/test/driver_base_test.rb +201 -0
  57. data/test/git_driver_test.rb +51 -0
  58. data/test/insert_snippet_test.rb +256 -349
  59. data/test/repository_manager_test.rb +7 -16
  60. data/test/yaml_document_test.rb +97 -0
  61. metadata +44 -16
  62. data/lib/social_snippet/repository/drivers/base_repository.rb +0 -189
  63. data/lib/social_snippet/repository/drivers/git_repository.rb +0 -74
  64. data/lib/social_snippet/repository/repository_factory.rb +0 -59
  65. data/lib/social_snippet/repository/repository_installer.rb +0 -85
  66. data/spec/lib/repository/base_repository_spec.rb +0 -104
  67. data/spec/lib/repository/git_repository_spec.rb +0 -83
  68. data/spec/lib/repository/repository_installer_spec.rb +0 -63
  69. data/test/base_repository_test.rb +0 -375
  70. data/test/git_repository_test.rb +0 -114
@@ -0,0 +1,11 @@
1
+ class ::SocialSnippet::Repository::Drivers::Entry
2
+
3
+ attr_reader :path
4
+ attr_reader :data
5
+
6
+ def initialize(new_path, new_data = nil)
7
+ @path = new_path
8
+ @data = new_data
9
+ end
10
+
11
+ end
@@ -0,0 +1,100 @@
1
+ module SocialSnippet::Repository::Drivers
2
+
3
+ class GitDriver < DriverBase
4
+
5
+ attr_reader :rugged_repo
6
+
7
+ def fetch
8
+ dest_dir = ::Dir.mktmpdir
9
+ @rugged_repo = ::Rugged::Repository.clone_at(url, dest_dir)
10
+ end
11
+
12
+ def snippet_json
13
+ @snippet_json ||= read_snippet_json
14
+ end
15
+
16
+ def read_snippet_json
17
+ oid = rugged_repo.head.target.tree["snippet.json"][:oid]
18
+ @snippet_json ||= ::JSON.parse rugged_repo.lookup(oid).read_raw.data
19
+ end
20
+
21
+ def read_file(oid)
22
+ rugged_repo.lookup(oid).read_raw.data
23
+ end
24
+
25
+ def each_directory(ref)
26
+ rugged_ref(ref).target.tree.each do |c|
27
+ next unless c[:type] == :tree
28
+ yield ::SocialSnippet::Repository::Drivers::Entry.new(c[:name])
29
+ end
30
+ end
31
+
32
+ def each_file(ref, &block)
33
+ walk_tree rugged_ref(ref).target.tree, ::Array.new, &block
34
+ end
35
+
36
+ def walk_tree(tree, parents)
37
+ tree.each_blob do |c|
38
+ path = ::File.join(*parents, c[:name])
39
+ yield ::SocialSnippet::Repository::Drivers::Entry.new(path, read_file(c[:oid]))
40
+ end
41
+ tree.each_tree do |t|
42
+ parents.push t[:name]
43
+ walk_tree(rugged_repo.lookup(t[:oid]), parents) do |content|
44
+ yield content
45
+ end
46
+ parents.pop
47
+ end
48
+ end
49
+
50
+ def current_ref
51
+ rugged_repo.head.name.gsub /^refs\/heads\//, ""
52
+ end
53
+
54
+ def rugged_ref(ref_name)
55
+ rugged_repo.references.each("refs/*/#{ref_name}").first
56
+ end
57
+
58
+ def rev_hash(ref)
59
+ rugged_ref(ref).target_id
60
+ end
61
+
62
+ def refs
63
+ all_refs = []
64
+ all_refs.concat remote_refs
65
+ all_refs.concat tags
66
+ all_refs
67
+ end
68
+
69
+ def remote_refs
70
+ rugged_repo.references.each("refs/remotes/origin/**/*").map do |r|
71
+ r.name.match(/^refs\/remotes\/origin\/(.*)/)[1]
72
+ end
73
+ end
74
+
75
+ def tags
76
+ rugged_repo.references.each("refs/tags/**/*").map do |r|
77
+ r.name.match(/^refs\/tags\/(.*)/)[1]
78
+ end
79
+ end
80
+
81
+ class << self
82
+
83
+ def target_url?(url)
84
+ uri = ::URI.parse(url)
85
+ is_git_uri(uri)
86
+ end
87
+
88
+ def is_git_uri(uri)
89
+ /git|https?/ === uri.scheme
90
+ end
91
+
92
+ def target_path?(path)
93
+ ::File.directory?(path) && ::File.directory?(::File.join path, ".git")
94
+ end
95
+
96
+ end # class << self
97
+
98
+ end # GitDriver
99
+
100
+ end # SocialSnippet
@@ -0,0 +1,15 @@
1
+ module SocialSnippet::Repository::Models
2
+
3
+ def self.const_missing(name)
4
+ if name === :Package
5
+ require_relative "models/package"
6
+ ::SocialSnippet::Repository::Models::Package
7
+ elsif name === :Repository
8
+ require_relative "models/repository"
9
+ ::SocialSnippet::Repository::Models::Repository
10
+ else
11
+ super
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,97 @@
1
+ module SocialSnippet::Repository::Models
2
+
3
+ class Package < ::SocialSnippet::Document
4
+
5
+ @@core = nil
6
+
7
+ field :repo_name, :type => String # key
8
+ field :rev_hash, :type => String # key
9
+ field :name, :type => String
10
+ field :paths, :type => Array, :default => ::Array.new
11
+ field :dependencies, :type => Hash, :default => ::Hash.new
12
+
13
+ def display_name
14
+ name || "#{repo_name}@#{rev_hash}"
15
+ end
16
+
17
+ def normalize_path(path)
18
+ ::Pathname.new(path).cleanpath.to_s
19
+ end
20
+
21
+ def add_path(path)
22
+ push :paths => path
23
+ end
24
+
25
+ def add_directory(path)
26
+ path = normalize_path(path)
27
+ add_path path + "/"
28
+ dir_path = real_path(path)
29
+ core.storage.mkdir_p dir_path
30
+ end
31
+
32
+ def add_file(path, data)
33
+ path = normalize_path(path)
34
+ add_path path
35
+ file_path = real_path(path)
36
+ core.storage.mkdir_p ::File.dirname(file_path)
37
+ core.storage.write file_path, data
38
+ end
39
+
40
+ def add_dependency(name, ref)
41
+ modifier = {}
42
+ modifier[name] = ref
43
+ push :dependencies => modifier
44
+ end
45
+
46
+ def has_dependencies?
47
+ not dependencies.empty?
48
+ end
49
+
50
+ def snippet_json_text
51
+ json_path = real_path("snippet.json")
52
+ core.storage.read json_path
53
+ end
54
+
55
+ def snippet_json
56
+ @snippet_json ||= parse_snippet_json
57
+ end
58
+
59
+ def parse_snippet_json
60
+ ::JSON.parse(snippet_json_text)
61
+ end
62
+
63
+ def glob(glob_pattern)
64
+ paths.select do |path|
65
+ ::File.fnmatch glob_pattern, path, ::File::FNM_PATHNAME
66
+ end
67
+ end
68
+
69
+ def real_path(path = nil)
70
+ core.config.package_path repo_name, rev_hash, path
71
+ end
72
+
73
+ # path from snippet_json["main"]
74
+ def snippet_path(path = nil)
75
+ if snippet_json["main"].nil?
76
+ real_path path
77
+ else
78
+ real_path ::File.join(snippet_json["main"], path)
79
+ end
80
+ end
81
+
82
+ def core
83
+ @@core
84
+ end
85
+
86
+ def self.core
87
+ @@core
88
+ end
89
+
90
+ def self.core=(new_core)
91
+ @@core = new_core
92
+ end
93
+
94
+ end # Package
95
+
96
+ end # ::SocialSnippet::Repository::Models
97
+
@@ -0,0 +1,94 @@
1
+ module SocialSnippet::Repository::Models
2
+
3
+ class Repository < ::SocialSnippet::Document
4
+
5
+ @@core = nil
6
+
7
+ field :url, :type => String
8
+ field :name, :type => String
9
+ field :current_ref, :type => String
10
+ field :refs, :type => Array, :default => ::Array.new
11
+ # rev_hash[ref] => Commit ID
12
+ field :rev_hash, :type => Hash, :default => ::Hash.new
13
+ # package_refs[ref] => rev_hash
14
+ field :package_refs, :type => Hash, :default => ::Hash.new
15
+
16
+ def add_package(ref)
17
+ modifier = ::Hash.new
18
+ modifier[ref] = rev_hash[ref]
19
+ push :package_refs => modifier
20
+ end
21
+
22
+ def add_ref(ref, rev_hash)
23
+ add_to_set :refs => ref
24
+ modifier = ::Hash.new
25
+ modifier[ref] = rev_hash
26
+ push :rev_hash => modifier
27
+ end
28
+
29
+ def has_ref?(ref)
30
+ refs.include? ref
31
+ end
32
+
33
+ def package_ref_keys
34
+ package_refs.map {|k, _| k }
35
+ end
36
+
37
+ def package_minor_versions
38
+ package_versions.map do |v|
39
+ ::SocialSnippet::Version.minor v
40
+ end.uniq
41
+ end
42
+
43
+ def latest_package_version(pattern = "")
44
+ find_latest_version package_versions, pattern
45
+ end
46
+
47
+ def package_versions
48
+ select_versions package_ref_keys
49
+ end
50
+
51
+ # Returns latest version
52
+ def latest_version(pattern = "")
53
+ find_latest_version versions, pattern
54
+ end
55
+
56
+ # Returns all versions
57
+ def versions
58
+ select_versions refs
59
+ end
60
+
61
+ def find_latest_version(versions, pattern = "")
62
+ matches = versions.select {|ref| ::SocialSnippet::Version.is_matched_version_pattern(pattern, ref)}
63
+ ::VersionSorter.rsort(matches).first
64
+ end
65
+
66
+ def select_versions(refs)
67
+ refs.select {|ref| ::SocialSnippet::Version.is_version(ref) }
68
+ end
69
+
70
+ def has_package_versions?
71
+ not package_versions.empty?
72
+ end
73
+
74
+ # Check repository has version ref
75
+ def has_versions?
76
+ not versions.empty?
77
+ end
78
+
79
+ def core
80
+ @@core
81
+ end
82
+
83
+ def self.core
84
+ @@core
85
+ end
86
+
87
+ def self.core=(new_core)
88
+ @@core = new_core
89
+ end
90
+
91
+ end
92
+
93
+ end
94
+
@@ -2,9 +2,6 @@ module SocialSnippet::Repository
2
2
 
3
3
  class RepositoryManager
4
4
 
5
- attr_reader :installer
6
- attr_reader :repo_paths
7
- attr_reader :repo_cache_path
8
5
  attr_reader :core
9
6
 
10
7
  # Constructor
@@ -12,31 +9,6 @@ module SocialSnippet::Repository
12
9
  # @param new_core [::SocialSnippet::Core]
13
10
  def initialize(new_core)
14
11
  @core = new_core
15
- @installer = ::SocialSnippet::Repository::RepositoryInstaller.new(core)
16
- @repo_cache_path = core.config.repository_cache_path
17
- @repo_paths = []
18
-
19
- init_repo_paths
20
- init_repo_cache_path
21
- end
22
-
23
- def init_repo_cache_path
24
- ::FileUtils.mkdir_p repo_cache_path
25
- end
26
-
27
- def init_repo_paths
28
- repo_paths.push installer.path
29
- repo_paths.each {|path| ::FileUtils.mkdir_p path }
30
- end
31
-
32
- def deps(repo_name, repo_ref = nil)
33
- repo = find_repository(repo_name)
34
- repo.checkout(repo_ref) unless repo_ref.nil?
35
- repo.dependencies
36
- end
37
-
38
- def has_deps?(repo_name, repo_ref = nil)
39
- not deps(repo_name, repo_ref).empty?
40
12
  end
41
13
 
42
14
  # Get snippet by context and tag
@@ -53,8 +25,8 @@ module SocialSnippet::Repository
53
25
  # @param tag [::SocialSnippet::Tag] The tag of snippet
54
26
  def resolve_snippet_path(context, tag)
55
27
  if tag.has_repo?
56
- repo = find_repository_by_tag(tag)
57
- repo.real_path tag.path
28
+ pkg = find_package_by_tag(tag)
29
+ pkg.snippet_path tag.path
58
30
  else
59
31
  new_context = context.clone
60
32
  new_context.dirname + "/" + tag.filename
@@ -64,36 +36,38 @@ module SocialSnippet::Repository
64
36
  # Find repository by tag
65
37
  #
66
38
  # @param tag [::SocialSnippet::Tag] The tag of repository
67
- def find_repository_by_tag(tag)
39
+ def find_package_by_tag(tag)
68
40
  if tag.has_ref?
69
- find_repository(tag.repo, tag.ref)
41
+ find_package(tag.repo, tag.ref)
70
42
  else
71
- find_repository(tag.repo)
43
+ find_package(tag.repo)
72
44
  end
73
45
  end
74
46
 
75
47
  # Find repository by repo name
76
48
  #
77
49
  # @param name [String] The name of repository
78
- def find_repository(name, ref = nil)
79
- return nil if name.nil? || name.empty?
80
-
81
- repo_paths.each do |repo_path|
82
- path = "#{repo_path}/#{name}"
83
- if ::Dir.exists?(path)
84
- repo = RepositoryFactory.create(path, ref)
85
- repo.load_cache repo_cache_path
86
- return repo
87
- end
88
- end
50
+ def find_package(name, ref = nil)
51
+ repo = find_repository(name)
52
+ ref ||= repo.latest_package_version || repo.current_ref
53
+ raise "invalid references" unless repo.has_ref?(ref)
54
+ Models::Package.find_by(
55
+ :repo_name => name,
56
+ :rev_hash => repo.rev_hash[ref],
57
+ )
58
+ end
89
59
 
90
- nil
60
+ def find_repository(name)
61
+ Models::Repository.find_by(:name => name)
62
+ end
63
+
64
+ def find_repository_by_url(url)
65
+ Models::Repository.find_by(:url => url)
91
66
  end
92
67
 
93
68
  def find_repositories_start_with(prefix)
94
- glob_path = ::File.join(installer.path, "#{prefix}*")
95
- ::Dir.glob(glob_path).map do |repopath|
96
- Pathname(repopath).basename.to_s
69
+ Models::Repository.where(:name => /^#{prefix}.*/).map do |repo|
70
+ repo.name
97
71
  end
98
72
  end
99
73
 
@@ -103,12 +77,12 @@ module SocialSnippet::Repository
103
77
  end
104
78
 
105
79
  def complete_file_name(keyword)
106
- repo_name = get_repo_name(keyword)
107
- repo = find_repository(repo_name)
108
- file_path = get_file_path_prefix(keyword)
109
- glob_path = "#{file_path}*"
80
+ repo_name = get_repo_name(keyword)
81
+ package = find_package(repo_name)
82
+ file_path = keyword_filepath(keyword)
83
+ glob_path = "#{file_path}*"
110
84
 
111
- repo.glob(glob_path).map do |cand_file_path|
85
+ package.glob(glob_path).map do |cand_file_path|
112
86
  if ::File.directory?(cand_file_path)
113
87
  Pathname(cand_file_path).basename.to_s + "/"
114
88
  else
@@ -135,7 +109,7 @@ module SocialSnippet::Repository
135
109
  /^[^@]*@[^<]+<([^:#>]*[^:#>])$/.match(keyword)[1]
136
110
  end
137
111
 
138
- def get_file_path_prefix(keyword)
112
+ def keyword_filepath(keyword)
139
113
  /^[^@]*@[^<]+<[^#:]+:([^>]*)$/.match(keyword)[1]
140
114
  end
141
115
 
@@ -147,30 +121,68 @@ module SocialSnippet::Repository
147
121
  /^[^@]*@[^<]+<[^#:]+:[^>]*$/ === keyword
148
122
  end
149
123
 
150
- def cache_installing_repo(repo, options = {})
151
- repo.create_cache repo_cache_path
124
+ def install(url, ref, options = ::Hash.new)
125
+ driver = core.driver_factory.clone(url)
126
+ ref ||= resolve_ref_by_driver(driver)
127
+ repo = update_repository(driver, url)
128
+ create_package driver, ref
152
129
  end
153
130
 
154
- def fetch(repo_name, options)
155
- installer.fetch repo_name, options
131
+ def resolve_ref_by_driver(driver)
132
+ driver.latest_version || driver.current_ref
156
133
  end
157
134
 
158
- def update(repo_name, repo_ref, repo, options)
159
- cache_installing_repo repo, options
160
- installer.add repo_name, repo_ref
135
+ def update_repository(driver, url)
136
+ repo = Models::Repository.find_or_create_by(:url => url)
137
+ repo.update_attributes! :name => driver.snippet_json["name"]
138
+ driver.each_ref {|ref| repo.add_ref ref, driver.rev_hash(ref) }
139
+ repo
161
140
  end
162
141
 
163
- def install(repo_name, repo_ref, repo, options)
164
- installer.copy_repository repo, options
165
- update repo_name, repo_ref, repo, options
142
+ def create_package(driver, ref)
143
+ repo_name = driver.snippet_json["name"]
144
+ package = Models::Package.create(
145
+ :repo_name => repo_name,
146
+ :rev_hash => driver.rev_hash(ref),
147
+ :name => "#{driver.snippet_json["name"]}##{ref}",
148
+ )
149
+
150
+ repo = find_repository(repo_name)
151
+ repo.add_package ref
152
+
153
+ driver.each_directory(ref) do |dir|
154
+ package.add_directory dir.path
155
+ end
156
+ driver.each_file(ref) do |content|
157
+ package.add_file content.path, content.data
158
+ end
159
+
160
+ unless package.snippet_json["dependencies"].nil?
161
+ package.snippet_json["dependencies"].each do |dep_name, dep_ref|
162
+ package.add_dependency dep_name, dep_ref
163
+ end
164
+ end
165
+
166
+ package
166
167
  end
167
168
 
168
169
  def exists?(repo_name, repo_ref = nil)
169
- installer.exists? repo_name, repo_ref
170
+ # not found repo
171
+ return false unless Models::Repository.where(:name => repo_name).exists?
172
+
173
+ repo = Models::Repository.find_by(:name => repo_name)
174
+ if repo_ref.nil?
175
+ true
176
+ else
177
+ Models::Package.where(
178
+ :repo_name => repo_name,
179
+ :rev_hash => repo.rev_hash[repo_ref],
180
+ ).exists?
181
+ end
170
182
  end
171
183
 
172
- def each_installed_repo(&block)
173
- installer.each &block
184
+ def each_repo(&block)
185
+ Models::Repository.all.each &block
174
186
  end
175
187
 
176
188
  end # RepositoryManager