teuton-get 0.1.0
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 +7 -0
- data/LICENSE +674 -0
- data/README.md +29 -0
- data/bin/teutonget +6 -0
- data/docs/commands.md +16 -0
- data/docs/get.md +50 -0
- data/docs/repo.md +68 -0
- data/docs/settings.md +40 -0
- data/lib/teuton-get/application/environment.rb +9 -0
- data/lib/teuton-get/application.rb +39 -0
- data/lib/teuton-get/cli.rb +89 -0
- data/lib/teuton-get/downloader.rb +71 -0
- data/lib/teuton-get/files/repos.ini +11 -0
- data/lib/teuton-get/files/tt-info.yaml +21 -0
- data/lib/teuton-get/reader/inifile_reader.rb +24 -0
- data/lib/teuton-get/reader/linux_environment_reader.rb +19 -0
- data/lib/teuton-get/reader/reader.rb +9 -0
- data/lib/teuton-get/reader/url_reader.rb +18 -0
- data/lib/teuton-get/reader/yaml_reader.rb +24 -0
- data/lib/teuton-get/repo/local_info.rb +71 -0
- data/lib/teuton-get/repo/local_repo.rb +70 -0
- data/lib/teuton-get/repo/repo_config.rb +92 -0
- data/lib/teuton-get/repo/repo_data.rb +126 -0
- data/lib/teuton-get/searcher/result.rb +21 -0
- data/lib/teuton-get/searcher.rb +142 -0
- data/lib/teuton-get/version.rb +6 -0
- data/lib/teuton-get/writer/file_writer.rb +19 -0
- data/lib/teuton-get/writer/null_writer.rb +15 -0
- data/lib/teuton-get/writer/terminal_writer.rb +20 -0
- data/lib/teuton-get/writer/writer.rb +9 -0
- data/lib/teuton-get.rb +45 -0
- metadata +149 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
require_relative "../application"
|
2
|
+
require_relative "../writer/file_writer"
|
3
|
+
require_relative "../writer/terminal_writer"
|
4
|
+
|
5
|
+
class LocalRepo
|
6
|
+
def initialize(args)
|
7
|
+
@repoindex_writer = args[:repoindex_writer]
|
8
|
+
@dev = args[:progress_writer]
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.new_by_default
|
12
|
+
LocalRepo.new(
|
13
|
+
repoindex_writer: FileWriter.new,
|
14
|
+
progress_writer: TerminalWriter.new
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create(dirpath)
|
19
|
+
infofilename = Application::INFOFILENAME
|
20
|
+
infofiles = Dir.glob(File.join(dirpath, "**", infofilename))
|
21
|
+
return if infofiles.size.zero?
|
22
|
+
|
23
|
+
@dev.writeln "\n==> Creating repository", color: :light_yellow
|
24
|
+
data = read_files(infofiles)
|
25
|
+
|
26
|
+
filepath = File.join(dirpath, Application::INDEXFILENAME)
|
27
|
+
@repoindex_writer.open(filepath)
|
28
|
+
@repoindex_writer.write data.to_yaml
|
29
|
+
@repoindex_writer.close
|
30
|
+
|
31
|
+
@dev.writeln " Created file #{filepath} with #{data.keys.size} tests.", color: :white
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def read_files(infofiles)
|
38
|
+
data = {}
|
39
|
+
infofiles.each do |filepath|
|
40
|
+
cleanpath = filepath
|
41
|
+
if cleanpath.start_with? "./"
|
42
|
+
# delete 2 chars at the begining. Example: "./"
|
43
|
+
cleanpath[0, 2] = ""
|
44
|
+
end
|
45
|
+
infodata = LocalInfo.new(@dev).read(cleanpath)
|
46
|
+
dirpath = File.dirname(cleanpath)
|
47
|
+
data[dirpath] = infodata
|
48
|
+
end
|
49
|
+
data
|
50
|
+
end
|
51
|
+
|
52
|
+
def copyfile(target, dest)
|
53
|
+
if File.exist? dest
|
54
|
+
@dev.write " WARN: exits file "
|
55
|
+
@dev.writeln dest, color: :light_yellow
|
56
|
+
return true
|
57
|
+
end
|
58
|
+
begin
|
59
|
+
FileUtils.cp(target, dest)
|
60
|
+
@dev.write "===> Created file "
|
61
|
+
@dev.writeln dest, color: :light_green
|
62
|
+
true
|
63
|
+
rescue => e
|
64
|
+
@dev.write " ERROR: Creating file "
|
65
|
+
@dev.writeln dest, color: :light_red
|
66
|
+
puts e
|
67
|
+
false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require_relative "../application"
|
3
|
+
require_relative "../reader/inifile_reader"
|
4
|
+
require_relative "../writer/terminal_writer"
|
5
|
+
|
6
|
+
class RepoConfig
|
7
|
+
attr_reader :data
|
8
|
+
|
9
|
+
def initialize(args)
|
10
|
+
@reader = args[:config_reader]
|
11
|
+
@data = @reader.read
|
12
|
+
@dev = args[:progress_writer]
|
13
|
+
|
14
|
+
@config_dirpath = args[:config_dirpath] || ""
|
15
|
+
@config_filepath = File.join(@config_dirpath, Application::CONFIGFILE)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.new_by_default
|
19
|
+
config_filepath = Application.instance.get(:config_filepath)
|
20
|
+
|
21
|
+
RepoConfig.new(
|
22
|
+
config_reader: IniFileReader.new(config_filepath),
|
23
|
+
progress_writer: TerminalWriter.new,
|
24
|
+
config_dirpath: Application.instance.get(:config_dirpath)
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def create
|
29
|
+
@dev.writeln "\n==> Creating configuration files", color: :light_yellow
|
30
|
+
create_dir
|
31
|
+
create_ini_file
|
32
|
+
end
|
33
|
+
|
34
|
+
def show_list
|
35
|
+
rows = []
|
36
|
+
rows << ["E", "NAME", "DESCRIPTION"]
|
37
|
+
rows << :separator
|
38
|
+
|
39
|
+
@data.each_pair do |key, value|
|
40
|
+
enable = "\u{2714}"
|
41
|
+
enable = " " unless value["enable"]
|
42
|
+
description = value["description"] || "?"
|
43
|
+
rows << [enable, key, description]
|
44
|
+
end
|
45
|
+
@dev.writeln "Repository list"
|
46
|
+
@dev.write_table(rows)
|
47
|
+
@dev.write "Config: "
|
48
|
+
@dev.writeln "#{@reader.source}\n", color: :white
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def create_dir
|
54
|
+
dirpath = @config_dirpath
|
55
|
+
if Dir.exist? dirpath
|
56
|
+
@dev.write " \u{2716} Exists dir! : "
|
57
|
+
@dev.writeln dirpath, color: :yellow
|
58
|
+
else
|
59
|
+
begin
|
60
|
+
FileUtils.mkdir_p(dirpath)
|
61
|
+
@dev.write " \u{2714} Create dir : "
|
62
|
+
@dev.writeln dirpath, color: :green
|
63
|
+
rescue => e
|
64
|
+
@dev.write " \u{2716} Create dir ERROR: "
|
65
|
+
@dev.writeln dirpath, color: :red
|
66
|
+
puts e
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_ini_file
|
72
|
+
src = File.join(File.dirname(__FILE__), "..", "files", Application::CONFIGFILE)
|
73
|
+
copyfile(src, @config_filepath)
|
74
|
+
end
|
75
|
+
|
76
|
+
def copyfile(target, dest)
|
77
|
+
if File.exist? dest
|
78
|
+
@dev.write " \u{2716} Exists file! : "
|
79
|
+
@dev.writeln dest, color: :yellow
|
80
|
+
return true
|
81
|
+
end
|
82
|
+
begin
|
83
|
+
FileUtils.cp(target, dest)
|
84
|
+
@dev.write " \u{2714} Create file : "
|
85
|
+
@dev.writeln dest, color: :green
|
86
|
+
rescue => e
|
87
|
+
@dev.write " \u{2716} Create file ERROR: "
|
88
|
+
@dev.writeln dest, color: :red
|
89
|
+
puts e
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require_relative "../application"
|
3
|
+
require_relative "../reader/url_reader"
|
4
|
+
require_relative "../reader/inifile_reader"
|
5
|
+
require_relative "../reader/yaml_reader"
|
6
|
+
|
7
|
+
class RepoData
|
8
|
+
attr_reader :data
|
9
|
+
|
10
|
+
def initialize(args)
|
11
|
+
@reader = args[:config_reader]
|
12
|
+
@data = @reader.read
|
13
|
+
@dev = args[:progress_writer]
|
14
|
+
@cache_dirpath = args[:cache_dirpath]
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.new_by_default
|
18
|
+
config_filepath = Application.instance.get(:config_filepath)
|
19
|
+
RepoData.new(
|
20
|
+
config_reader: IniFileReader.new(config_filepath),
|
21
|
+
progress_writer: TerminalWriter.new,
|
22
|
+
cache_dirpath: Application.instance.get(:cache_dirpath)
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def refresh
|
27
|
+
@database = {}
|
28
|
+
dirpath = @cache_dirpath
|
29
|
+
FileUtils.rm_r(dirpath) if Dir.exist? dirpath
|
30
|
+
|
31
|
+
@dev.writeln "\n==> Refreshing active repos", color: :light_yellow
|
32
|
+
@data.keys.sort.each do |key|
|
33
|
+
refresh_repo key
|
34
|
+
end
|
35
|
+
save_database
|
36
|
+
end
|
37
|
+
|
38
|
+
def get(test_id)
|
39
|
+
reponame, id = test_id.split(Application::SEPARATOR)
|
40
|
+
database = YamlReader.new.read(database_filename)
|
41
|
+
return {} if database[reponame].nil?
|
42
|
+
database[reponame][id]
|
43
|
+
end
|
44
|
+
|
45
|
+
def show_testinfo(item)
|
46
|
+
return unless item
|
47
|
+
@dev.writeln ""
|
48
|
+
["name", "author", "date", "desc"].each do |key|
|
49
|
+
@dev.write "#{key.ljust(7)} : ", color: :white
|
50
|
+
@dev.writeln item[key].to_s
|
51
|
+
end
|
52
|
+
["tags", "files"].each do |key|
|
53
|
+
next if item[key].nil?
|
54
|
+
@dev.write "#{key.ljust(7)} : ", color: :white
|
55
|
+
@dev.writeln item[key].join(", ")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def database_filename
|
60
|
+
# REVISE: Used by teutonget search... replace by #get()
|
61
|
+
File.join(@cache_dirpath, "database.yaml")
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def refresh_repo(reponame)
|
67
|
+
unless enabled? reponame
|
68
|
+
@dev.writeln " \u{2716} Skiping repo #{reponame}"
|
69
|
+
return false
|
70
|
+
end
|
71
|
+
dirpath = File.join(@cache_dirpath)
|
72
|
+
ok1 = create_dir(dirpath)
|
73
|
+
ok2 = get_database(reponame)
|
74
|
+
|
75
|
+
@dev.writeln " \u{2714} Repo #{reponame} (#{ok2.size} tests)"
|
76
|
+
|
77
|
+
true && ok1 && ok2
|
78
|
+
end
|
79
|
+
|
80
|
+
def enabled?(reponame)
|
81
|
+
@data[reponame]["enable"] == true
|
82
|
+
end
|
83
|
+
|
84
|
+
def create_dir(dirpath)
|
85
|
+
unless Dir.exist? dirpath
|
86
|
+
begin
|
87
|
+
FileUtils.mkdir_p(dirpath)
|
88
|
+
return true
|
89
|
+
rescue => e
|
90
|
+
@dev.write "* Create dir ERROR => "
|
91
|
+
@dev.writeln dirpath, color: :red
|
92
|
+
puts e
|
93
|
+
return false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
false
|
97
|
+
end
|
98
|
+
|
99
|
+
def get_database(reponame)
|
100
|
+
data = @data[reponame]
|
101
|
+
|
102
|
+
@database[reponame] = if data["URL"].start_with? "http"
|
103
|
+
get_remote_database(data["URL"])
|
104
|
+
else
|
105
|
+
get_local_database(data["URL"])
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def get_local_database(dirpath)
|
110
|
+
filepath = File.join(dirpath, Application::INDEXFILENAME)
|
111
|
+
@reader.read(filepath)
|
112
|
+
end
|
113
|
+
|
114
|
+
def get_remote_database(url_repo)
|
115
|
+
url_file = "#{url_repo}/#{Application::INDEXFILENAME}"
|
116
|
+
content_page = URLReader.new(url_file).read
|
117
|
+
YAML.safe_load(
|
118
|
+
content_page,
|
119
|
+
permitted_classes: [Array, Date, Hash, Symbol]
|
120
|
+
)
|
121
|
+
end
|
122
|
+
|
123
|
+
def save_database
|
124
|
+
File.write(database_filename, @database.to_yaml)
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative "../application"
|
2
|
+
|
3
|
+
class Result
|
4
|
+
attr_accessor :score
|
5
|
+
attr_reader :reponame
|
6
|
+
attr_reader :testname
|
7
|
+
|
8
|
+
def initialize(args)
|
9
|
+
@score = args[:score] || 0
|
10
|
+
@reponame = args[:reponame] || "???"
|
11
|
+
@testname = args[:testname] || "???"
|
12
|
+
end
|
13
|
+
|
14
|
+
def id
|
15
|
+
"#{reponame}#{Application::SEPARATOR}#{testname}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_h
|
19
|
+
{score: @score, id: id, reponame: @reponame, testname: @testname}
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require_relative "application"
|
2
|
+
require_relative "reader/yaml_reader"
|
3
|
+
require_relative "repo/repo_data"
|
4
|
+
require_relative "searcher/result"
|
5
|
+
require_relative "writer/terminal_writer"
|
6
|
+
|
7
|
+
class Searcher
|
8
|
+
def initialize(args)
|
9
|
+
@dev = args[:writer]
|
10
|
+
|
11
|
+
@repodata = args[:repodata]
|
12
|
+
filename = @repodata.database_filename
|
13
|
+
|
14
|
+
@reader = args[:reader]
|
15
|
+
@database = @reader.read(filename)
|
16
|
+
|
17
|
+
@results = {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.new_by_default
|
21
|
+
Searcher.new(
|
22
|
+
writer: TerminalWriter.new,
|
23
|
+
repodata: RepoData.new_by_default,
|
24
|
+
reader: YamlReader.new
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def get(input)
|
29
|
+
reponame_filter, filters = parse_input(input)
|
30
|
+
search_inside(reponame_filter, filters)
|
31
|
+
end
|
32
|
+
|
33
|
+
def show(result)
|
34
|
+
@results.each do |i|
|
35
|
+
@dev.write "(x#{i[:score]}) ", color: :white
|
36
|
+
@dev.writeln "#{i[:reponame]}#{Application::SEPARATOR}#{i[:testname]}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def parse_input(input)
|
43
|
+
reponame_filter = :all
|
44
|
+
filter = :all
|
45
|
+
options = input.split(Application::SEPARATOR)
|
46
|
+
if options.size == 1
|
47
|
+
reponame_filter = :all
|
48
|
+
filter = options[0]
|
49
|
+
elsif options[0] == ""
|
50
|
+
reponame_filter = :all
|
51
|
+
filter = options[1]
|
52
|
+
elsif options.size == 2
|
53
|
+
reponame_filter = options[0]
|
54
|
+
filter = options[1]
|
55
|
+
end
|
56
|
+
reponame_filter = :all if reponame_filter == "ALL"
|
57
|
+
filters = if filter == "ALL"
|
58
|
+
:all
|
59
|
+
else
|
60
|
+
filter.split(",")
|
61
|
+
end
|
62
|
+
[reponame_filter, filters]
|
63
|
+
end
|
64
|
+
|
65
|
+
def search_inside(reponame_filter, filters)
|
66
|
+
@results = {}
|
67
|
+
if reponame_filter == :all
|
68
|
+
@database.keys.each { |reponame| search_inside_repo(reponame, filters) }
|
69
|
+
else
|
70
|
+
@database.keys.each do |reponame|
|
71
|
+
search_inside_repo(reponame, filters) if reponame.include? reponame_filter
|
72
|
+
end
|
73
|
+
end
|
74
|
+
sort_results
|
75
|
+
end
|
76
|
+
|
77
|
+
def search_inside_repo(reponame, filters)
|
78
|
+
return if reponame != :all && @database[reponame].nil?
|
79
|
+
|
80
|
+
@database[reponame].each do |testname, data|
|
81
|
+
result = Result.new(
|
82
|
+
score: 0,
|
83
|
+
reponame: reponame,
|
84
|
+
testname: testname
|
85
|
+
)
|
86
|
+
if filters == :all
|
87
|
+
add_result(result)
|
88
|
+
next
|
89
|
+
end
|
90
|
+
score = 0
|
91
|
+
filters.each do |filter|
|
92
|
+
score += evaluate_test(
|
93
|
+
testname: testname,
|
94
|
+
data: data,
|
95
|
+
filter: filter
|
96
|
+
)
|
97
|
+
if score > 0
|
98
|
+
result.score = score
|
99
|
+
add_result result
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def evaluate_test(args)
|
106
|
+
testname = args[:testname]
|
107
|
+
data = args[:data]
|
108
|
+
filter = args[:filter]
|
109
|
+
|
110
|
+
score = 0
|
111
|
+
data.each_pair do |key, value|
|
112
|
+
if value.instance_of? String
|
113
|
+
score += 1 if value.downcase.include? filter
|
114
|
+
elsif value.instance_of? Date
|
115
|
+
score += 1 if value.to_s.include? filter
|
116
|
+
elsif value.instance_of? Array
|
117
|
+
score += 1 if value.include? filter
|
118
|
+
end
|
119
|
+
end
|
120
|
+
score += 1 if testname.include? filter
|
121
|
+
score
|
122
|
+
end
|
123
|
+
|
124
|
+
def add_result(result)
|
125
|
+
key = result.id
|
126
|
+
if @results[key].nil?
|
127
|
+
@results[key] = result
|
128
|
+
return
|
129
|
+
end
|
130
|
+
@results[key].score += result.score
|
131
|
+
end
|
132
|
+
|
133
|
+
def sort_results
|
134
|
+
results = []
|
135
|
+
@results.each_pair { |key, value| results += [value.to_h] }
|
136
|
+
|
137
|
+
results.sort_by! do |i|
|
138
|
+
[(Application::MAGICNUMBER - i[:score]), i[:id]]
|
139
|
+
end
|
140
|
+
@results = results
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative "writer"
|
2
|
+
|
3
|
+
class FileWriter < Writer
|
4
|
+
def open(filepath)
|
5
|
+
@file = File.open(filepath, "w")
|
6
|
+
end
|
7
|
+
|
8
|
+
def write(text)
|
9
|
+
@file.write text
|
10
|
+
end
|
11
|
+
|
12
|
+
def writeln(text)
|
13
|
+
@file.write text
|
14
|
+
end
|
15
|
+
|
16
|
+
def close
|
17
|
+
@file.close
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "colorize"
|
2
|
+
require "tty-table"
|
3
|
+
require_relative "writer"
|
4
|
+
|
5
|
+
class TerminalWriter < Writer
|
6
|
+
def write(text = "", args = {})
|
7
|
+
color = args[:color] || :silver
|
8
|
+
print text.colorize(color)
|
9
|
+
end
|
10
|
+
|
11
|
+
def writeln(text = "", args = {})
|
12
|
+
write("#{text}\n", args)
|
13
|
+
end
|
14
|
+
|
15
|
+
def write_table(rows)
|
16
|
+
table = TTY::Table.new(rows)
|
17
|
+
# puts table.render(:basic)
|
18
|
+
puts table.render(:ascii)
|
19
|
+
end
|
20
|
+
end
|
data/lib/teuton-get.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative "teuton-get/repo/local_info"
|
2
|
+
require_relative "teuton-get/repo/local_repo"
|
3
|
+
require_relative "teuton-get/repo/repo_config"
|
4
|
+
require_relative "teuton-get/repo/repo_data"
|
5
|
+
require_relative "teuton-get/searcher"
|
6
|
+
require_relative "teuton-get/downloader"
|
7
|
+
|
8
|
+
module TeutonGet
|
9
|
+
def self.create_info(testpath)
|
10
|
+
LocalInfo.new.user_create(testpath)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.create_repo(dirpath)
|
14
|
+
LocalRepo.new_by_default.create(dirpath)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.init
|
18
|
+
RepoConfig.new_by_default.create
|
19
|
+
refresh # Auto repo refresh
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.refresh
|
23
|
+
RepoData.new_by_default.refresh
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.show_repo_list
|
27
|
+
RepoConfig.new_by_default.show_list
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.show_info(test_id)
|
31
|
+
repo_data = RepoData.new_by_default
|
32
|
+
info = repo_data.get(test_id)
|
33
|
+
repo_data.show_testinfo(info) unless info == {}
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.search(filter)
|
37
|
+
searcher = Searcher.new_by_default
|
38
|
+
result = searcher.get(filter)
|
39
|
+
searcher.show(result)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.download(test_id)
|
43
|
+
Downloader.new.run(test_id)
|
44
|
+
end
|
45
|
+
end
|