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,158 @@
|
|
1
|
+
#
|
2
|
+
# Usage:
|
3
|
+
#
|
4
|
+
# class SomeCommand < Command; end
|
5
|
+
# cli = SomeCommand.new [arg1, arg2, ...], stream_opts
|
6
|
+
# cli.init
|
7
|
+
# cli.run
|
8
|
+
#
|
9
|
+
class SocialSnippet::CommandLine::Command
|
10
|
+
|
11
|
+
require "optparse"
|
12
|
+
|
13
|
+
attr_reader :args
|
14
|
+
attr_reader :tokens
|
15
|
+
attr_reader :options
|
16
|
+
attr_reader :opt_parser
|
17
|
+
attr_reader :streams
|
18
|
+
attr_reader :input_stream
|
19
|
+
attr_reader :output_stream
|
20
|
+
|
21
|
+
def initialize(new_args, new_streams = {})
|
22
|
+
@streams = new_streams
|
23
|
+
@input_stream = streams[:input_stream] || STDIN
|
24
|
+
@output_stream = streams[:output_stream] || STDOUT
|
25
|
+
@args = new_args.clone
|
26
|
+
@options = {}
|
27
|
+
@tokens = [] # init after parse options
|
28
|
+
@opt_parser = ::OptionParser.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def social_snippet
|
32
|
+
@social_snippet ||= ::SocialSnippet::Core.new(input_stream, output_stream)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Define an option
|
36
|
+
#
|
37
|
+
# @param name [Symbol] :hello_world => "--hello-world"
|
38
|
+
# @param info[:type] :flag or :string
|
39
|
+
# @param info[:default] [Any] default value
|
40
|
+
# @param info[:short] [Boolean] enable short flag
|
41
|
+
def define_option(name, info = {})
|
42
|
+
info[:type] ||= :string
|
43
|
+
info[:default] ||= nil
|
44
|
+
info[:short] ||= false
|
45
|
+
long_opt = to_long_option(name, info)
|
46
|
+
options[name] = info[:default]
|
47
|
+
if info[:short]
|
48
|
+
opt_parser.on to_short_option(name, info), long_opt do |v|
|
49
|
+
options[name] = v
|
50
|
+
end
|
51
|
+
else
|
52
|
+
opt_parser.on long_opt do |v|
|
53
|
+
options[name] = v
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def define_options
|
59
|
+
raise "not implement"
|
60
|
+
end
|
61
|
+
|
62
|
+
def init
|
63
|
+
init_version
|
64
|
+
init_banner
|
65
|
+
define_options
|
66
|
+
parse_line_options
|
67
|
+
@tokens = args
|
68
|
+
end
|
69
|
+
|
70
|
+
def run
|
71
|
+
raise "not implement"
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def help
|
77
|
+
opt_parser.parse ["--help"]
|
78
|
+
end
|
79
|
+
|
80
|
+
def init_banner
|
81
|
+
opt_parser.banner = usage
|
82
|
+
end
|
83
|
+
|
84
|
+
def usage
|
85
|
+
raise "not implement"
|
86
|
+
end
|
87
|
+
|
88
|
+
def init_version
|
89
|
+
opt_parser.version = ::SocialSnippet::VERSION
|
90
|
+
end
|
91
|
+
|
92
|
+
def to_long_option(sym, info = {})
|
93
|
+
if info[:type] == :flag
|
94
|
+
"--[no-]#{sym.to_s.gsub("_", "-")}"
|
95
|
+
elsif info[:type] == :string
|
96
|
+
"--#{sym.to_s.gsub("_", "-")} value"
|
97
|
+
else
|
98
|
+
"--#{sym.to_s.gsub("_", "-")}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def to_short_option(sym, info = {})
|
103
|
+
"-#{sym.to_s[0]}"
|
104
|
+
end
|
105
|
+
|
106
|
+
def parse_line_options
|
107
|
+
return if args.empty?
|
108
|
+
last_ind = last_line_option_index
|
109
|
+
if last_ind.nil?
|
110
|
+
parsed = args.clone
|
111
|
+
else
|
112
|
+
parsed = args[0 .. last_ind]
|
113
|
+
end
|
114
|
+
@args = opt_parser.parse(parsed).concat(args[last_ind + 1..-1])
|
115
|
+
end
|
116
|
+
|
117
|
+
def last_line_option_index
|
118
|
+
args.index do |arg|
|
119
|
+
is_not_line_option?(arg)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# hello -> HelloCommand
|
124
|
+
def to_command_class_sym(s)
|
125
|
+
"#{s.capitalize}Command".to_sym
|
126
|
+
end
|
127
|
+
|
128
|
+
# :HelloCommand -> hello
|
129
|
+
def to_command_name(sym)
|
130
|
+
sym.to_s.gsub(/Command$/, '').downcase
|
131
|
+
end
|
132
|
+
|
133
|
+
def is_line_option?(s)
|
134
|
+
return true if /^-[a-zA-Z0-9]$/ === s
|
135
|
+
return true if /^--/ === s
|
136
|
+
return false
|
137
|
+
end
|
138
|
+
|
139
|
+
def is_not_line_option?(s)
|
140
|
+
is_line_option?(s) === false
|
141
|
+
end
|
142
|
+
|
143
|
+
def has_subcommand?
|
144
|
+
return false if args.empty?
|
145
|
+
return false if args[0].start_with?("-")
|
146
|
+
return true
|
147
|
+
end
|
148
|
+
|
149
|
+
# [--opt1, --opt2, token1, token2] => token1
|
150
|
+
def next_token
|
151
|
+
tokens.shift
|
152
|
+
end
|
153
|
+
|
154
|
+
def has_next_token?
|
155
|
+
not tokens.empty?
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module SocialSnippet::CommandLine
|
2
|
+
|
3
|
+
class SSnip::MainCommand < Command
|
4
|
+
|
5
|
+
attr_reader :sub_commands
|
6
|
+
|
7
|
+
def usage
|
8
|
+
<<EOF
|
9
|
+
Usage: ssnip [options]
|
10
|
+
|
11
|
+
Example:
|
12
|
+
$ cat target_file | ssnip > snipped_file
|
13
|
+
|
14
|
+
EOF
|
15
|
+
end
|
16
|
+
|
17
|
+
def define_options
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
social_snippet.api.insert_snippet(input_stream.read)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module SocialSnippet::CommandLine
|
2
|
+
|
3
|
+
class SSpm::MainCommand < Command
|
4
|
+
|
5
|
+
attr_reader :sub_commands
|
6
|
+
|
7
|
+
def initialize(new_args, new_streams = {})
|
8
|
+
super
|
9
|
+
@sub_commands = SSpm::SubCommands.all
|
10
|
+
end
|
11
|
+
|
12
|
+
def define_options
|
13
|
+
end
|
14
|
+
|
15
|
+
def usage
|
16
|
+
<<EOF
|
17
|
+
Usage: sspm <command> [options] [--]
|
18
|
+
|
19
|
+
Commands:
|
20
|
+
#{usage_subcommands}
|
21
|
+
EOF
|
22
|
+
end
|
23
|
+
|
24
|
+
def run
|
25
|
+
if has_subcommand?
|
26
|
+
command_name = args.shift
|
27
|
+
find_subcommand command_name
|
28
|
+
else
|
29
|
+
help
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def usage_subcommands
|
36
|
+
sub_commands.sort.map do |sub_command_sym|
|
37
|
+
{
|
38
|
+
:sym => sub_command_sym,
|
39
|
+
:instance => SSpm::SubCommands.const_get(sub_command_sym).new(args),
|
40
|
+
}
|
41
|
+
end.map do |sub_command|
|
42
|
+
" #{to_command_name(sub_command[:sym])}\t#{sub_command[:instance].desc}"
|
43
|
+
end.join("\n")
|
44
|
+
end
|
45
|
+
|
46
|
+
def find_subcommand(command_name)
|
47
|
+
sub_command_sym = to_command_class_sym(command_name)
|
48
|
+
if sub_commands.include?(sub_command_sym)
|
49
|
+
call_subcommand(sub_command_sym)
|
50
|
+
else
|
51
|
+
help
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def call_subcommand(sym)
|
56
|
+
cli = SSpm::SubCommands.const_get(sym).new(args)
|
57
|
+
cli.init
|
58
|
+
cli.run
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module SocialSnippet::CommandLine::SSpm::SubCommands
|
2
|
+
|
3
|
+
def self.all
|
4
|
+
constants.select do |name|
|
5
|
+
/.+Command$/ === name
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
require_relative "sub_commands/search_command"
|
12
|
+
require_relative "sub_commands/install_command"
|
13
|
+
require_relative "sub_commands/complete_command"
|
14
|
+
require_relative "sub_commands/info_command"
|
15
|
+
require_relative "sub_commands/update_command"
|
16
|
+
require_relative "sub_commands/publish_command"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SocialSnippet::CommandLine
|
2
|
+
|
3
|
+
class SSpm::SubCommands::CompleteCommand < Command
|
4
|
+
|
5
|
+
def usage
|
6
|
+
<<EOF
|
7
|
+
Usage: sspm complete [options] [--] <keyword>
|
8
|
+
EOF
|
9
|
+
end
|
10
|
+
|
11
|
+
def desc
|
12
|
+
"Complete snippet paths (for editor plugins)"
|
13
|
+
end
|
14
|
+
|
15
|
+
def define_options
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
if has_next_token?
|
20
|
+
social_snippet.api.cli_complete_snippet_path next_token
|
21
|
+
else
|
22
|
+
help
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SocialSnippet::CommandLine
|
2
|
+
|
3
|
+
class SSpm::SubCommands::InfoCommand < Command
|
4
|
+
|
5
|
+
def usage
|
6
|
+
<<EOF
|
7
|
+
Usage: sspm info [options] [--] <repo>
|
8
|
+
EOF
|
9
|
+
end
|
10
|
+
|
11
|
+
def desc
|
12
|
+
"Show information of a repository"
|
13
|
+
end
|
14
|
+
|
15
|
+
def define_options
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
if has_next_token?
|
20
|
+
social_snippet.api.show_info next_token
|
21
|
+
else
|
22
|
+
help
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module SocialSnippet::CommandLine
|
2
|
+
|
3
|
+
require "uri"
|
4
|
+
require "pathname"
|
5
|
+
require "json"
|
6
|
+
|
7
|
+
class SSpm::SubCommands::InstallCommand < Command
|
8
|
+
|
9
|
+
def usage
|
10
|
+
<<EOF
|
11
|
+
Usage: sspm install [options] [--] <repo> [<repo> ...]
|
12
|
+
|
13
|
+
<repo>'s format:
|
14
|
+
<name> (e.g. "example-repo")
|
15
|
+
<name>#<version> (e.g. "example-repo#0.0.1")
|
16
|
+
|
17
|
+
Example:
|
18
|
+
$ sspm install example-repo
|
19
|
+
-> Installed latest version (or remote's current ref)
|
20
|
+
|
21
|
+
$ sspm install example-repo#0.0.1
|
22
|
+
-> Installed as the specified version
|
23
|
+
EOF
|
24
|
+
end
|
25
|
+
|
26
|
+
def desc
|
27
|
+
"Install snippet repository"
|
28
|
+
end
|
29
|
+
|
30
|
+
def define_options
|
31
|
+
define_option :dry_run, :type => :flag, :short => true, :default => false
|
32
|
+
define_option :name, :short => true, :default => nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def run
|
36
|
+
if has_next_token?
|
37
|
+
install_by_names
|
38
|
+
else
|
39
|
+
install_by_snippet_json
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def install_by_snippet_json
|
44
|
+
snippet_json = ::JSON.parse(File.read("snippet.json"))
|
45
|
+
snippet_json["dependencies"].each do |name, ref|
|
46
|
+
social_snippet.api.install_repository_by_name name, ref, options
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def install_by_names
|
51
|
+
while has_next_token?
|
52
|
+
token_str = next_token
|
53
|
+
if is_name?(token_str)
|
54
|
+
repo_info = parse_repo_token(token_str)
|
55
|
+
social_snippet.api.install_repository_by_name repo_info[:name], repo_info[:ref], options
|
56
|
+
elsif is_url?(token_str)
|
57
|
+
repo_info = parse_repo_token(token_str)
|
58
|
+
repo_url = repo_info[:name]
|
59
|
+
social_snippet.api.install_repository_by_url repo_url, repo_info[:ref], options
|
60
|
+
elsif is_path?(token_str)
|
61
|
+
repo_info = parse_repo_token(token_str)
|
62
|
+
repo_path = repo_info[:name]
|
63
|
+
social_snippet.api.install_repository_by_path repo_path, repo_info[:ref], options
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def is_name?(s)
|
71
|
+
not /\// === s
|
72
|
+
end
|
73
|
+
|
74
|
+
def is_path?(s)
|
75
|
+
pathname = ::Pathname.new(s)
|
76
|
+
pathname.absolute? || pathname.relative?
|
77
|
+
end
|
78
|
+
|
79
|
+
def is_url?(s)
|
80
|
+
::URI::regexp === s
|
81
|
+
end
|
82
|
+
|
83
|
+
def parse_repo_token(token_str)
|
84
|
+
if has_ref?(token_str)
|
85
|
+
words = token_str.split("#", 2)
|
86
|
+
{
|
87
|
+
:name => words.shift,
|
88
|
+
:ref => words.shift,
|
89
|
+
}
|
90
|
+
else
|
91
|
+
{
|
92
|
+
:name => token_str,
|
93
|
+
}
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def has_ref?(token_str)
|
98
|
+
/#/ === token_str
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|