social_snippet 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.gitignore +2 -0
- data/.travis.yml +22 -3
- data/Gemfile +25 -2
- data/Guardfile +9 -0
- data/README.md +6 -1
- data/Rakefile +51 -1
- data/appveyor.yml +36 -0
- data/bin/ssnip +10 -0
- data/bin/sspm +10 -0
- data/lib/social_snippet.rb +15 -4
- data/lib/social_snippet/api.rb +238 -0
- data/lib/social_snippet/command_line.rb +4 -0
- data/lib/social_snippet/command_line/command.rb +158 -0
- data/lib/social_snippet/command_line/ssnip.rb +2 -0
- data/lib/social_snippet/command_line/ssnip/main_command.rb +26 -0
- data/lib/social_snippet/command_line/sspm.rb +3 -0
- data/lib/social_snippet/command_line/sspm/main_command.rb +63 -0
- data/lib/social_snippet/command_line/sspm/sub_commands.rb +16 -0
- data/lib/social_snippet/command_line/sspm/sub_commands/complete_command.rb +28 -0
- data/lib/social_snippet/command_line/sspm/sub_commands/info_command.rb +28 -0
- data/lib/social_snippet/command_line/sspm/sub_commands/install_command.rb +103 -0
- data/lib/social_snippet/command_line/sspm/sub_commands/publish_command.rb +51 -0
- data/lib/social_snippet/command_line/sspm/sub_commands/search_command.rb +32 -0
- data/lib/social_snippet/command_line/sspm/sub_commands/update_command.rb +37 -0
- data/lib/social_snippet/config.rb +92 -0
- data/lib/social_snippet/context.rb +89 -0
- data/lib/social_snippet/core.rb +40 -0
- data/lib/social_snippet/inserter.rb +64 -0
- data/lib/social_snippet/logger.rb +9 -0
- data/lib/social_snippet/registry.rb +3 -0
- data/lib/social_snippet/registry/registry_client.rb +15 -0
- data/lib/social_snippet/registry/registry_resources.rb +3 -0
- data/lib/social_snippet/registry/registry_resources/base.rb +80 -0
- data/lib/social_snippet/registry/registry_resources/repositories.rb +23 -0
- data/lib/social_snippet/repository.rb +6 -0
- data/lib/social_snippet/repository/drivers.rb +3 -0
- data/lib/social_snippet/repository/drivers/base_repository.rb +192 -0
- data/lib/social_snippet/repository/drivers/git_repository.rb +76 -0
- data/lib/social_snippet/repository/repository_errors.rb +5 -0
- data/lib/social_snippet/repository/repository_factory.rb +59 -0
- data/lib/social_snippet/repository/repository_installer.rb +86 -0
- data/lib/social_snippet/repository/repository_manager.rb +177 -0
- data/lib/social_snippet/resolvers.rb +4 -0
- data/lib/social_snippet/resolvers/base_resolver.rb +103 -0
- data/lib/social_snippet/resolvers/dep_resolver.rb +61 -0
- data/lib/social_snippet/resolvers/insert_resolver.rb +100 -0
- data/lib/social_snippet/snippet.rb +14 -0
- data/lib/social_snippet/tag.rb +198 -0
- data/lib/social_snippet/tag_parser.rb +61 -0
- data/lib/social_snippet/version.rb +26 -1
- data/social_snippet.gemspec +18 -3
- data/spec/helpers/codeclimate_helper.rb +4 -0
- data/spec/helpers/fakefs_helper.rb +15 -0
- data/spec/helpers/webmock_helper.rb +16 -0
- data/spec/lib/api_spec.rb +106 -0
- data/spec/lib/command_line/sspm_install_spec.rb +224 -0
- data/spec/lib/command_line/sspm_search_spec.rb +167 -0
- data/spec/lib/command_line/sspm_spec.rb +81 -0
- data/spec/lib/config_spec.rb +56 -0
- data/spec/lib/context_spec.rb +48 -0
- data/spec/lib/core_spec.rb +126 -0
- data/spec/lib/inserter_spec.rb +177 -0
- data/spec/lib/registry_client_spec.rb +173 -0
- data/spec/lib/repository/base_repository_spec.rb +104 -0
- data/spec/lib/repository/git_repository_spec.rb +83 -0
- data/spec/lib/repository/repository_factory_spec.rb +31 -0
- data/spec/lib/repository/repository_installer_spec.rb +63 -0
- data/spec/lib/repository/repository_manager_spec.rb +201 -0
- data/spec/lib/tag_parser_spec.rb +173 -0
- data/spec/lib/tag_spec.rb +93 -0
- data/spec/spec_helper.rb +106 -0
- data/test/base_repository_test.rb +375 -0
- data/test/command_test.rb +39 -0
- data/test/context_test.rb +31 -0
- data/test/core_test.rb +2091 -0
- data/test/git_repository_test.rb +114 -0
- data/test/install_command_test.rb +28 -0
- data/test/repository_manager_test.rb +109 -0
- data/test/tag_parser_test.rb +47 -0
- data/test/tag_test.rb +217 -0
- data/test/version_test.rb +56 -0
- metadata +271 -14
@@ -0,0 +1,86 @@
|
|
1
|
+
module SocialSnippet::Repository
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
class RepositoryInstaller
|
6
|
+
|
7
|
+
attr_reader :social_snippet
|
8
|
+
attr_reader :data
|
9
|
+
|
10
|
+
def initialize(new_social_snippet)
|
11
|
+
@social_snippet = new_social_snippet
|
12
|
+
init_data
|
13
|
+
end
|
14
|
+
|
15
|
+
def path
|
16
|
+
social_snippet.config.install_path
|
17
|
+
end
|
18
|
+
|
19
|
+
def data_file
|
20
|
+
social_snippet.config.installed_repos_file
|
21
|
+
end
|
22
|
+
|
23
|
+
def init_data
|
24
|
+
::FileUtils.touch data_file
|
25
|
+
load
|
26
|
+
reset unless data
|
27
|
+
end
|
28
|
+
|
29
|
+
def reset
|
30
|
+
@data = {}
|
31
|
+
save
|
32
|
+
end
|
33
|
+
|
34
|
+
def load
|
35
|
+
@data = ::YAML.load_file(data_file)
|
36
|
+
end
|
37
|
+
|
38
|
+
def save
|
39
|
+
::File.write data_file, data.to_yaml
|
40
|
+
end
|
41
|
+
|
42
|
+
def add(repo_name, repo_ref)
|
43
|
+
data[repo_name] ||= Set.new
|
44
|
+
data[repo_name].add repo_ref
|
45
|
+
save
|
46
|
+
end
|
47
|
+
|
48
|
+
def remove(repo_name, repo_ref)
|
49
|
+
data[repo_name] ||= Set.new
|
50
|
+
data[repo_name].delete repo_ref
|
51
|
+
save
|
52
|
+
end
|
53
|
+
|
54
|
+
def exists?(repo_name, repo_ref = nil)
|
55
|
+
data[repo_name] ||= Set.new
|
56
|
+
if repo_ref.nil?
|
57
|
+
data[repo_name].empty? === false
|
58
|
+
else
|
59
|
+
data[repo_name].include? repo_ref
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def copy_repository(repo, options = {})
|
64
|
+
social_snippet.logger.debug "repository_installer: repo.path = #{repo.path}"
|
65
|
+
::FileUtils.cp_r repo.path, repo_path(repo.name)
|
66
|
+
end
|
67
|
+
|
68
|
+
def fetch(repo_name, options)
|
69
|
+
repo = ::SocialSnippet::Repository::RepositoryFactory.create(repo_path(repo_name), options)
|
70
|
+
repo.update
|
71
|
+
end
|
72
|
+
|
73
|
+
def repo_path(name)
|
74
|
+
::File.join(path, name)
|
75
|
+
end
|
76
|
+
|
77
|
+
def each(&block)
|
78
|
+
data
|
79
|
+
.select {|repo_name, repo_refs| not repo_refs.empty? }
|
80
|
+
.keys
|
81
|
+
.each {|repo_name| block.call repo_name }
|
82
|
+
end
|
83
|
+
|
84
|
+
end # RepositoryInstaller
|
85
|
+
|
86
|
+
end # SocialSnippet
|
@@ -0,0 +1,177 @@
|
|
1
|
+
module SocialSnippet::Repository
|
2
|
+
|
3
|
+
class RepositoryManager
|
4
|
+
|
5
|
+
attr_reader :installer
|
6
|
+
attr_reader :repo_paths
|
7
|
+
attr_reader :repo_cache_path
|
8
|
+
attr_reader :social_snippet
|
9
|
+
|
10
|
+
# Constructor
|
11
|
+
#
|
12
|
+
# @param new_social_snippet [::SocialSnippet::Core]
|
13
|
+
def initialize(new_social_snippet)
|
14
|
+
@social_snippet = new_social_snippet
|
15
|
+
@installer = ::SocialSnippet::Repository::RepositoryInstaller.new(social_snippet)
|
16
|
+
@repo_cache_path = social_snippet.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
|
+
end
|
41
|
+
|
42
|
+
# Get snippet
|
43
|
+
#
|
44
|
+
# @param context [::SocialSnippet::Context] The context of snippet
|
45
|
+
# @param tag [::SocialSnippet::Tag] The tag of snippet
|
46
|
+
def get_snippet(context, tag)
|
47
|
+
return ::SocialSnippet::Snippet.new(resolve_snippet_path(context, tag))
|
48
|
+
end
|
49
|
+
|
50
|
+
# Resolve snippet path from tag
|
51
|
+
#
|
52
|
+
# @param context [::SocialSnippet::Context] The context of snippet
|
53
|
+
# @param tag [::SocialSnippet::Tag] The tag of snippet
|
54
|
+
def resolve_snippet_path(context, tag)
|
55
|
+
if tag.has_repo?
|
56
|
+
repo = find_repository_by_tag(tag)
|
57
|
+
return repo.real_path tag.path
|
58
|
+
end
|
59
|
+
|
60
|
+
new_context = context.clone
|
61
|
+
new_context.move tag.path
|
62
|
+
return new_context.path
|
63
|
+
end
|
64
|
+
|
65
|
+
# Find repository by tag
|
66
|
+
#
|
67
|
+
# @param tag [::SocialSnippet::Tag] The tag of repository
|
68
|
+
def find_repository_by_tag(tag)
|
69
|
+
if tag.has_ref?
|
70
|
+
find_repository(tag.repo, tag.ref)
|
71
|
+
else
|
72
|
+
find_repository(tag.repo)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Find repository by repo name
|
77
|
+
#
|
78
|
+
# @param name [String] The name of repository
|
79
|
+
def find_repository(name, ref = nil)
|
80
|
+
repo_paths.each do |repo_path|
|
81
|
+
path = "#{repo_path}/#{name}"
|
82
|
+
if ::Dir.exists?(path)
|
83
|
+
repo = RepositoryFactory.create(path, ref)
|
84
|
+
repo.load_cache repo_cache_path
|
85
|
+
return repo
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
return nil
|
90
|
+
end
|
91
|
+
|
92
|
+
def find_repositories_start_with(prefix)
|
93
|
+
glob_path = ::File.join(installer.path, "#{prefix}*")
|
94
|
+
::Dir.glob(glob_path).map do |repopath|
|
95
|
+
Pathname(repopath).basename.to_s
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def complete_repo_name(keyword)
|
100
|
+
repo_name = get_repo_name_prefix(keyword)
|
101
|
+
find_repositories_start_with(repo_name)
|
102
|
+
end
|
103
|
+
|
104
|
+
def complete_file_name(keyword)
|
105
|
+
repo_name = get_repo_name(keyword)
|
106
|
+
repo = find_repository(repo_name)
|
107
|
+
file_path = get_file_path_prefix(keyword)
|
108
|
+
glob_path = "#{file_path}*"
|
109
|
+
|
110
|
+
repo.glob(glob_path).map do |cand_file_path|
|
111
|
+
if ::File.directory?(cand_file_path)
|
112
|
+
Pathname(cand_file_path).basename.to_s + "/"
|
113
|
+
else
|
114
|
+
Pathname(cand_file_path).basename.to_s + ">"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def complete(keyword)
|
120
|
+
if is_completing_repo_name?(keyword)
|
121
|
+
complete_repo_name(keyword)
|
122
|
+
elsif is_completing_file_path?(keyword)
|
123
|
+
complete_file_name(keyword)
|
124
|
+
else
|
125
|
+
raise "completion error"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def get_repo_name(keyword)
|
130
|
+
/^[^@]*@[^<]+<([^:#>]*[^:#>])/.match(keyword)[1]
|
131
|
+
end
|
132
|
+
|
133
|
+
def get_repo_name_prefix(keyword)
|
134
|
+
/^[^@]*@[^<]+<([^:#>]*[^:#>])$/.match(keyword)[1]
|
135
|
+
end
|
136
|
+
|
137
|
+
def get_file_path_prefix(keyword)
|
138
|
+
/^[^@]*@[^<]+<[^#:]+:([^>]*)$/.match(keyword)[1]
|
139
|
+
end
|
140
|
+
|
141
|
+
def is_completing_repo_name?(keyword)
|
142
|
+
/^[^@]*@[^<]+<[^:#>]*$/ === keyword
|
143
|
+
end
|
144
|
+
|
145
|
+
def is_completing_file_path?(keyword)
|
146
|
+
/^[^@]*@[^<]+<[^#:]+:[^>]*$/ === keyword
|
147
|
+
end
|
148
|
+
|
149
|
+
def cache_installing_repo(repo, options = {})
|
150
|
+
repo.create_cache repo_cache_path
|
151
|
+
end
|
152
|
+
|
153
|
+
def fetch(repo_name, options)
|
154
|
+
installer.fetch repo_name, options
|
155
|
+
end
|
156
|
+
|
157
|
+
def update(repo_name, repo_ref, repo, options)
|
158
|
+
cache_installing_repo repo, options
|
159
|
+
installer.add repo_name, repo_ref
|
160
|
+
end
|
161
|
+
|
162
|
+
def install(repo_name, repo_ref, repo, options)
|
163
|
+
installer.copy_repository repo, options
|
164
|
+
update repo_name, repo_ref, repo, options
|
165
|
+
end
|
166
|
+
|
167
|
+
def exists?(repo_name, repo_ref = nil)
|
168
|
+
installer.exists? repo_name, repo_ref
|
169
|
+
end
|
170
|
+
|
171
|
+
def each_installed_repo(&block)
|
172
|
+
installer.each &block
|
173
|
+
end
|
174
|
+
|
175
|
+
end # RepositoryManager
|
176
|
+
|
177
|
+
end # SocialSnippet
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module SocialSnippet
|
2
|
+
|
3
|
+
class Resolvers::BaseResolver
|
4
|
+
|
5
|
+
attr_reader :social_snippet
|
6
|
+
attr_reader :visited
|
7
|
+
|
8
|
+
# Constructor
|
9
|
+
#
|
10
|
+
# @param new_social_snippet [::SocialSnippet::Core]
|
11
|
+
def initialize(new_social_snippet)
|
12
|
+
@social_snippet = new_social_snippet
|
13
|
+
@visited = Set.new
|
14
|
+
end
|
15
|
+
|
16
|
+
# Call block each snip tags
|
17
|
+
#
|
18
|
+
# @param src [Array<String>] The text of source code
|
19
|
+
# @param context [SocialSnippet::Context] The context of current code
|
20
|
+
# @param base_tag [SocialSnippet::Tag]
|
21
|
+
def each_snip_tags(src, context, base_tag)
|
22
|
+
TagParser.find_snip_tags(src).each do |tag_info|
|
23
|
+
t = tag_info[:tag].set_by_tag(base_tag)
|
24
|
+
new_context = context.clone
|
25
|
+
|
26
|
+
move_context_by_tag! new_context, t
|
27
|
+
overwrite_tag_in_same_repository! context, t
|
28
|
+
update_tag_path_by_context! new_context, t
|
29
|
+
resolve_tag_repo_ref! t
|
30
|
+
|
31
|
+
snippet = social_snippet.repo_manager.get_snippet(context, t)
|
32
|
+
|
33
|
+
if block_given?
|
34
|
+
yield(
|
35
|
+
tag_info[:tag],
|
36
|
+
tag_info[:line_no],
|
37
|
+
snippet,
|
38
|
+
new_context
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def move_context_by_tag!(context, tag)
|
47
|
+
if tag.has_repo?
|
48
|
+
if tag.has_ref?
|
49
|
+
context.move tag.path, tag.repo, tag.ref
|
50
|
+
else
|
51
|
+
context.move tag.path, tag.repo
|
52
|
+
end
|
53
|
+
else
|
54
|
+
context.move tag.path
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Overwrite tag
|
59
|
+
def overwrite_tag_in_same_repository!(context, tag)
|
60
|
+
if context.is_in_repository? && tag.has_repo? === false
|
61
|
+
tag.set_repo context.repo
|
62
|
+
tag.set_ref context.ref
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Update tag path by context
|
67
|
+
def update_tag_path_by_context!(context, tag)
|
68
|
+
if tag.has_repo?
|
69
|
+
tag.set_path context.path
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Resolve tag's ref
|
74
|
+
def resolve_tag_repo_ref!(tag)
|
75
|
+
repo = social_snippet.repo_manager.find_repository_by_tag(tag)
|
76
|
+
|
77
|
+
# not found
|
78
|
+
return if repo.nil?
|
79
|
+
|
80
|
+
if tag.has_ref? === false || tag.ref != repo.latest_version(tag.ref)
|
81
|
+
if repo.has_versions?
|
82
|
+
tag.set_ref repo.latest_version(tag.ref)
|
83
|
+
else
|
84
|
+
tag.set_ref repo.short_commit_id
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def visit(tag)
|
90
|
+
visited.add tag.to_path
|
91
|
+
end
|
92
|
+
|
93
|
+
def is_visited(tag)
|
94
|
+
visited.include? tag.to_path
|
95
|
+
end
|
96
|
+
|
97
|
+
def is_self(tag, context)
|
98
|
+
tag.repo === context.repo && tag.path === context.path
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module SocialSnippet
|
2
|
+
|
3
|
+
class Resolvers::DepResolver < Resolvers::BaseResolver
|
4
|
+
|
5
|
+
attr_reader :dep_to
|
6
|
+
|
7
|
+
# Constructor
|
8
|
+
#
|
9
|
+
# @param social_snippet [::SocialSnippet::Core]
|
10
|
+
def initialize(social_snippet)
|
11
|
+
@dep_to = {} # dep_to[tag_from] = tag_to
|
12
|
+
super(social_snippet)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Find all missing depended snippets
|
16
|
+
#
|
17
|
+
# @param src [Array<String>] The text of source code
|
18
|
+
# @param context_from [SocialSnippet::Context] The context of previous code
|
19
|
+
# @param tag_from [SocialSnippet::Tag] The previous tag
|
20
|
+
def find(src, context_from, tag_from)
|
21
|
+
found_tags = find_func src, context_from, tag_from
|
22
|
+
found_tags.each do |tag_info|
|
23
|
+
# remove self from deps graph
|
24
|
+
tag = tag_info[:tag]
|
25
|
+
dep_to[tag.to_path] ||= ::Set.new
|
26
|
+
dep_to[tag.to_path].delete tag_from.to_path
|
27
|
+
end
|
28
|
+
found_tags
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def set_snippet_dep(tag_from, tag_to)
|
34
|
+
dep_to[tag_from.to_path] ||= ::Set.new
|
35
|
+
dep_to[tag_from.to_path].add tag_to.to_path
|
36
|
+
end
|
37
|
+
|
38
|
+
def find_func(src, context_from, tag_from)
|
39
|
+
found_tags = []
|
40
|
+
context = context_from.clone
|
41
|
+
|
42
|
+
each_snip_tags(src, context_from, tag_from) do |tag, line_no, snippet, new_context|
|
43
|
+
next if is_visited(tag)
|
44
|
+
visit tag
|
45
|
+
|
46
|
+
set_snippet_dep tag_from, tag
|
47
|
+
found_tags.push({
|
48
|
+
:tag => tag,
|
49
|
+
:context => new_context,
|
50
|
+
})
|
51
|
+
# find more deps
|
52
|
+
found_tags.push *find_func(snippet.lines, new_context, tag)
|
53
|
+
end
|
54
|
+
|
55
|
+
return found_tags
|
56
|
+
end
|
57
|
+
|
58
|
+
end # DepResolver
|
59
|
+
|
60
|
+
end # SocialSnippet
|
61
|
+
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module SocialSnippet
|
2
|
+
|
3
|
+
class Resolvers::InsertResolver < Resolvers::BaseResolver
|
4
|
+
|
5
|
+
attr_reader :deps_resolver
|
6
|
+
|
7
|
+
# Constructor
|
8
|
+
#
|
9
|
+
# @param social_snippet [::SocialSnippet::Core]
|
10
|
+
def initialize(social_snippet)
|
11
|
+
@deps_resolver = Resolvers::DepResolver.new(social_snippet)
|
12
|
+
super(social_snippet)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Insert snippets to given text
|
16
|
+
#
|
17
|
+
# @param src [Array<String>] The text of source code
|
18
|
+
def insert(src)
|
19
|
+
context = Context.new("")
|
20
|
+
lines = src.split("\n")
|
21
|
+
|
22
|
+
TagParser.find_snippet_tags(lines).each do |tag_info|
|
23
|
+
visit tag_info[:tag]
|
24
|
+
end
|
25
|
+
|
26
|
+
dest = insert_func(lines, context)
|
27
|
+
return dest.join("\n")
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def insert_func(code, context_from, base_tag = nil)
|
33
|
+
inserter = Inserter.new(code)
|
34
|
+
context = context_from.clone
|
35
|
+
|
36
|
+
# replace each @snip tags
|
37
|
+
each_snip_tags(code, context, base_tag) do |tag, line_no, snippet, new_context|
|
38
|
+
inserter.set_index line_no
|
39
|
+
inserter.ignore
|
40
|
+
|
41
|
+
visit(tag) if is_self(tag, context)
|
42
|
+
next if is_visited(tag)
|
43
|
+
|
44
|
+
insert_depended_snippets! inserter, snippet, new_context, tag
|
45
|
+
insert_by_tag_and_context! inserter, snippet, new_context, tag
|
46
|
+
end
|
47
|
+
|
48
|
+
inserter.set_index_last
|
49
|
+
return inserter.dest
|
50
|
+
end
|
51
|
+
|
52
|
+
# Insert snippet by tag and context
|
53
|
+
def insert_by_tag_and_context!(inserter, snippet, context, tag)
|
54
|
+
src = insert_func(snippet.lines, context, tag)
|
55
|
+
inserter.insert tag.to_snippet_tag # @snip -> @snippet
|
56
|
+
inserter.insert src
|
57
|
+
visit tag
|
58
|
+
end
|
59
|
+
|
60
|
+
# Insert depended snippet
|
61
|
+
def insert_depended_snippets!(inserter, snippet, context, tag)
|
62
|
+
dep_tags = deps_resolver.find(snippet.lines, context, tag)
|
63
|
+
dep_tags = sort_dep_tags_by_dep(dep_tags)
|
64
|
+
|
65
|
+
dep_tags.each do |tag_info|
|
66
|
+
sub_t = tag_info[:tag]
|
67
|
+
sub_c = tag_info[:context]
|
68
|
+
|
69
|
+
visit(tag) if is_self(tag, context)
|
70
|
+
next if is_visited(sub_t)
|
71
|
+
|
72
|
+
sub_snippet = social_snippet.repo_manager.get_snippet(sub_c, sub_t)
|
73
|
+
insert_by_tag_and_context! inserter, sub_snippet, sub_c, sub_t
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Sort by dependency
|
78
|
+
def sort_dep_tags_by_dep(dep_tags)
|
79
|
+
dep_tags_index = {}
|
80
|
+
|
81
|
+
# map tag to index
|
82
|
+
dep_tags.each.with_index do |tag_info, k|
|
83
|
+
tag = tag_info[:tag]
|
84
|
+
dep_tags_index[tag.to_path] = k
|
85
|
+
end
|
86
|
+
|
87
|
+
# generate dependency graph
|
88
|
+
dep_tags_hash = {}
|
89
|
+
dep_tags.each do |tag_info|
|
90
|
+
tag = tag_info[:tag].to_path
|
91
|
+
dep_ind = dep_tags_index[tag]
|
92
|
+
dep_tags_hash[dep_ind] = deps_resolver.dep_to[tag].to_a.map {|tag| dep_tags_index[tag] }
|
93
|
+
end
|
94
|
+
|
95
|
+
dep_tags_hash.tsort.map {|k| dep_tags[k]}
|
96
|
+
end
|
97
|
+
|
98
|
+
end # BaseResolver
|
99
|
+
|
100
|
+
end # SocialSnippet
|