logaling-command 0.0.6 → 0.0.7
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.
- data/lib/logaling.rb +1 -0
- data/lib/logaling/command.rb +61 -42
- data/lib/logaling/glossary.rb +64 -105
- data/lib/logaling/repository.rb +87 -0
- data/logaling-command.gemspec +1 -0
- data/spec/logaling/command_spec.rb +39 -6
- data/spec/logaling/glossary_spec.rb +50 -151
- data/spec/logaling/repository_spec.rb +121 -0
- metadata +24 -10
data/lib/logaling.rb
CHANGED
@@ -6,6 +6,7 @@ module Logaling
|
|
6
6
|
class LogalingError < RuntimeError; end
|
7
7
|
class TermError < LogalingError; end
|
8
8
|
class CommandFailed < LogalingError; end
|
9
|
+
class GlossaryAlreadyRegistered < LogalingError; end
|
9
10
|
class GlossaryNotFound < LogalingError; end
|
10
11
|
class GlossaryDBNotFound < LogalingError; end
|
11
12
|
end
|
data/lib/logaling/command.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
require 'thor'
|
4
|
+
require "logaling/repository"
|
4
5
|
require "logaling/glossary"
|
5
6
|
|
6
7
|
class Logaling::Command < Thor
|
7
|
-
VERSION = "0.0.
|
8
|
+
VERSION = "0.0.7"
|
8
9
|
LOGALING_CONFIG = '.logaling'
|
9
10
|
|
10
11
|
map '-a' => :add,
|
@@ -41,34 +42,30 @@ class Logaling::Command < Thor
|
|
41
42
|
desc 'register', 'Register .logaling'
|
42
43
|
def register
|
43
44
|
logaling_path = find_dotfile
|
44
|
-
FileUtils.mkdir_p(logaling_projects_path) unless File.exist?(logaling_projects_path)
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
else
|
52
|
-
say "#{config['glossary']} is already registered."
|
53
|
-
end
|
46
|
+
required_options = {"glossary" => "input glossary name '-g <glossary name>'"}
|
47
|
+
config = load_config_and_merge_options(required_options)
|
48
|
+
|
49
|
+
repository.register(logaling_path, config["glossary"])
|
50
|
+
say "#{config['glossary']} is now registered to logaling."
|
54
51
|
rescue Logaling::CommandFailed => e
|
55
52
|
say e.message
|
56
53
|
say "Try 'loga new' first."
|
54
|
+
rescue Logaling::GlossaryAlreadyRegistered => e
|
55
|
+
say "#{config['glossary']} is already registered."
|
57
56
|
end
|
58
57
|
|
59
58
|
desc 'unregister', 'Unregister .logaling'
|
60
59
|
def unregister
|
61
|
-
|
62
|
-
config =
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
say "#{config['glossary']} is now unregistered."
|
67
|
-
else
|
68
|
-
say "#{config['glossary']} is not yet registered."
|
69
|
-
end
|
60
|
+
required_options = {"glossary" => "input glossary name '-g <glossary name>'"}
|
61
|
+
config = load_config_and_merge_options(required_options)
|
62
|
+
|
63
|
+
repository.unregister(config["glossary"])
|
64
|
+
say "#{config['glossary']} is now unregistered."
|
70
65
|
rescue Logaling::CommandFailed => e
|
71
66
|
say e.message
|
67
|
+
rescue Logaling::GlossaryNotFound => e
|
68
|
+
say "#{config['glossary']} is not yet registered."
|
72
69
|
end
|
73
70
|
|
74
71
|
desc 'add [SOURCE TERM] [TARGET TERM] [NOTE(optional)]', 'Add term to glossary.'
|
@@ -80,8 +77,12 @@ class Logaling::Command < Thor
|
|
80
77
|
|
81
78
|
desc 'delete [SOURCE TERM] [TARGET TERM(optional)] [--force(optional)]', 'Delete term.'
|
82
79
|
method_option "force", type: :boolean, default: false
|
83
|
-
def delete(source_term, target_term=
|
84
|
-
|
80
|
+
def delete(source_term, target_term=nil)
|
81
|
+
if target_term
|
82
|
+
glossary.delete(source_term, target_term)
|
83
|
+
else
|
84
|
+
glossary.delete_all(source_term, options["force"])
|
85
|
+
end
|
85
86
|
rescue Logaling::CommandFailed, Logaling::TermError => e
|
86
87
|
say e.message
|
87
88
|
rescue Logaling::GlossaryNotFound => e
|
@@ -99,16 +100,16 @@ class Logaling::Command < Thor
|
|
99
100
|
|
100
101
|
desc 'lookup [TERM]', 'Lookup terms.'
|
101
102
|
def lookup(source_term)
|
102
|
-
|
103
|
-
|
103
|
+
config = load_config_and_merge_options
|
104
|
+
repository.index
|
105
|
+
terms = repository.lookup(source_term, config["source_language"], config["target_language"], config["glossary"])
|
104
106
|
|
105
107
|
unless terms.empty?
|
106
|
-
is_glossary_name_print = terms.map{|t| t[:name]}.uniq.size > 1 ? true : false
|
107
108
|
terms.each do |term|
|
108
109
|
str_term = "#{term[:source_term]} : #{term[:target_term]}"
|
109
110
|
str_term << " # #{term[:note]}" unless term[:note].empty?
|
110
111
|
puts str_term
|
111
|
-
puts "(#{term[:name]})" if
|
112
|
+
puts "(#{term[:name]})" if repository.registered_project_counts > 1
|
112
113
|
end
|
113
114
|
else
|
114
115
|
"source-term <#{source_term}> not found"
|
@@ -123,23 +124,22 @@ class Logaling::Command < Thor
|
|
123
124
|
end
|
124
125
|
|
125
126
|
private
|
126
|
-
def
|
127
|
-
|
128
|
-
|
129
|
-
glossary = options["glossary"] || config["glossary"]
|
130
|
-
raise(Logaling::CommandFailed, "input glossary name '-g <glossary name>'") unless glossary
|
131
|
-
|
132
|
-
source_language = options["source-language"] || config["source-language"]
|
133
|
-
raise(Logaling::CommandFailed, "input source-language code '-S <source-language code>'") unless source_language
|
134
|
-
|
135
|
-
target_language = options["target-language"] || config["target-language"]
|
136
|
-
raise(Logaling::CommandFailed, "input target-language code '-T <target-language code>'") unless target_language
|
137
|
-
|
138
|
-
Logaling::Glossary.new(glossary, source_language, target_language)
|
127
|
+
def repository
|
128
|
+
@repository ||= Logaling::Repository.new(LOGALING_HOME)
|
139
129
|
end
|
140
130
|
|
141
|
-
def
|
142
|
-
|
131
|
+
def glossary
|
132
|
+
if @glossary
|
133
|
+
@glossary
|
134
|
+
else
|
135
|
+
required_options = {
|
136
|
+
"glossary" => "input glossary name '-g <glossary name>'",
|
137
|
+
"source-language" => "input source-language code '-S <source-language code>'",
|
138
|
+
"target-language" => "input target-language code '-T <target-language code>'"
|
139
|
+
}
|
140
|
+
config = load_config_and_merge_options(required_options)
|
141
|
+
@glossary = Logaling::Glossary.new(config["glossary"], config["source-language"], config["target-language"])
|
142
|
+
end
|
143
143
|
end
|
144
144
|
|
145
145
|
def error(msg)
|
@@ -147,10 +147,29 @@ class Logaling::Command < Thor
|
|
147
147
|
exit 1
|
148
148
|
end
|
149
149
|
|
150
|
+
def load_config_and_merge_options(required={})
|
151
|
+
config = load_config
|
152
|
+
config["glossary"] = options["glossary"] ? options["glossary"] : config["glossary"]
|
153
|
+
config["source-language"] = options["source-language"] ? options["source-language"] : config["source-language"]
|
154
|
+
config["target-language"] = options["target-language"] ? options["target-language"] : config["target-language"]
|
155
|
+
|
156
|
+
required.each do |required_option, message|
|
157
|
+
raise(Logaling::CommandFailed, message) unless config[required_option]
|
158
|
+
end
|
159
|
+
|
160
|
+
config
|
161
|
+
end
|
162
|
+
|
163
|
+
def find_config
|
164
|
+
File.join(find_dotfile, 'config')
|
165
|
+
rescue Logaling::CommandFailed
|
166
|
+
repository.config_path
|
167
|
+
end
|
168
|
+
|
150
169
|
def load_config
|
151
170
|
config ||= {}
|
152
|
-
if
|
153
|
-
File.readlines(
|
171
|
+
if config_path = find_config
|
172
|
+
File.readlines(config_path).map{|l| l.chomp.split " "}.each do |option|
|
154
173
|
key = option[0].sub(/^[\-]{2}/, "")
|
155
174
|
value = option[1]
|
156
175
|
config[key] = value
|
data/lib/logaling/glossary.rb
CHANGED
@@ -2,13 +2,47 @@
|
|
2
2
|
require 'psych'
|
3
3
|
require "yaml"
|
4
4
|
require "fileutils"
|
5
|
-
require "logaling/glossary_db"
|
6
5
|
|
7
6
|
module Logaling
|
8
7
|
class Glossary
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
class << self
|
9
|
+
def load(file)
|
10
|
+
load_glossary(file)
|
11
|
+
end
|
12
|
+
|
13
|
+
def load_glossary(file)
|
14
|
+
case File.extname(file)
|
15
|
+
when ".csv"
|
16
|
+
load_glossary_csv(file)
|
17
|
+
when ".tsv"
|
18
|
+
load_glossary_tsv(file)
|
19
|
+
when ".yml"
|
20
|
+
load_glossary_yml(file)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def load_glossary_yml(path)
|
25
|
+
YAML::load_file(path) || []
|
26
|
+
end
|
27
|
+
|
28
|
+
def load_glossary_tsv(path)
|
29
|
+
load_glossary_csv(path, "\t")
|
30
|
+
end
|
31
|
+
|
32
|
+
def load_glossary_csv(path, sep=",")
|
33
|
+
glossary = []
|
34
|
+
CSV.open(path, "r", {:col_sep => sep}) do |csv|
|
35
|
+
csv.each do |row|
|
36
|
+
glossary << {"source_term" => row[0], "target_term" => row[1], "note" => ""} if row.size >= 2
|
37
|
+
end
|
38
|
+
end
|
39
|
+
glossary
|
40
|
+
end
|
41
|
+
|
42
|
+
def build_path(glossary, source_language, target_language)
|
43
|
+
fname = [glossary, source_language, target_language].join(".")
|
44
|
+
File.join(LOGALING_HOME, "projects", glossary, "glossary", "#{fname}.yml")
|
45
|
+
end
|
12
46
|
end
|
13
47
|
|
14
48
|
def initialize(glossary, source_language, target_language)
|
@@ -19,9 +53,9 @@ module Logaling
|
|
19
53
|
end
|
20
54
|
|
21
55
|
def add(source_term, target_term, note)
|
22
|
-
FileUtils.touch(@path) unless File.
|
56
|
+
FileUtils.touch(@path) unless File.exist?(@path)
|
23
57
|
|
24
|
-
glossary = load_glossary(@path)
|
58
|
+
glossary = Glossary.load_glossary(@path)
|
25
59
|
if bilingual_pair_exists?(glossary, source_term, target_term)
|
26
60
|
raise TermError, "term '#{source_term}: #{target_term}' already exists in '#{@glossary}'"
|
27
61
|
end
|
@@ -31,9 +65,9 @@ module Logaling
|
|
31
65
|
end
|
32
66
|
|
33
67
|
def update(source_term, target_term, new_target_term, note)
|
34
|
-
raise GlossaryNotFound unless File.
|
68
|
+
raise GlossaryNotFound unless File.exist?(@path)
|
35
69
|
|
36
|
-
glossary = load_glossary(@path)
|
70
|
+
glossary = Glossary.load_glossary(@path)
|
37
71
|
if bilingual_pair_exists?(glossary, source_term, new_target_term)
|
38
72
|
raise TermError, "term '#{source_term}: #{target_term}' already exists in '#{@glossary}'"
|
39
73
|
end
|
@@ -47,106 +81,39 @@ module Logaling
|
|
47
81
|
end
|
48
82
|
end
|
49
83
|
|
50
|
-
def delete(source_term, target_term
|
51
|
-
raise GlossaryNotFound unless File.
|
84
|
+
def delete(source_term, target_term)
|
85
|
+
raise GlossaryNotFound unless File.exist?(@path)
|
52
86
|
|
53
|
-
glossary = load_glossary(@path)
|
54
|
-
|
55
|
-
|
56
|
-
raise TermError, "Can't found term '#{source_term} #{target_term}' in '#{@glossary}'"
|
57
|
-
elsif !target_term.empty? || target_num == 1
|
58
|
-
target_index = find_term_index(glossary, source_term, target_term)
|
87
|
+
glossary = Glossary.load_glossary(@path)
|
88
|
+
target_index = find_term_index(glossary, source_term, target_term)
|
89
|
+
unless target_index
|
59
90
|
raise TermError, "Can't found term '#{source_term} #{target_term}' in '#{@glossary}'" unless target_index
|
60
|
-
glossary.delete_at(target_index)
|
61
|
-
dump_glossary(glossary)
|
62
|
-
else
|
63
|
-
if force
|
64
|
-
while target_index = find_term_index(glossary, source_term) do
|
65
|
-
glossary.delete_at(target_index)
|
66
|
-
dump_glossary(glossary)
|
67
|
-
end
|
68
|
-
else
|
69
|
-
raise TermError, "There are duplicate terms in glossary.\n" +
|
70
|
-
"If you really want to delete, please put `loga delete [SOURCE_TERM] --force`\n" +
|
71
|
-
" or `loga delete [SOURCE_TERM] [TARGET_TERM]`"
|
72
|
-
end
|
73
91
|
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def lookup(source_term)
|
77
|
-
raise GlossaryDBNotFound unless File.exists?(logaling_db_home)
|
78
92
|
|
79
|
-
|
80
|
-
|
81
|
-
terms = db.lookup(source_term)
|
82
|
-
terms.reject! do |term|
|
83
|
-
term[:source_language] != @source_language || term[:target_language] != @target_language
|
84
|
-
end
|
85
|
-
unless terms.empty?
|
86
|
-
# order by glossary
|
87
|
-
specified = terms.select{|term| term[:name] == @glossary}
|
88
|
-
other = terms.select{|term| term[:name] != @glossary}
|
89
|
-
terms = specified.concat(other)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
terms
|
93
|
-
end
|
94
|
-
|
95
|
-
def index
|
96
|
-
projects = Dir.glob(File.join(LOGALING_HOME, "projects", "*"))
|
97
|
-
|
98
|
-
Logaling::GlossaryDB.open(logaling_db_home, "utf8") do |db|
|
99
|
-
db.recreate_table
|
100
|
-
projects.each do |project|
|
101
|
-
get_glossaries(project).each do |glossary, name, source_language, target_language|
|
102
|
-
db.index_glossary(glossary, name, source_language, target_language)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
93
|
+
glossary.delete_at(target_index)
|
94
|
+
dump_glossary(glossary)
|
106
95
|
end
|
107
96
|
|
108
|
-
|
109
|
-
|
110
|
-
case File.extname(file)
|
111
|
-
when ".csv"
|
112
|
-
load_glossary_csv(file)
|
113
|
-
when ".tsv"
|
114
|
-
load_glossary_tsv(file)
|
115
|
-
when ".yml"
|
116
|
-
load_glossary_yml(file)
|
117
|
-
end
|
118
|
-
end
|
97
|
+
def delete_all(source_term, force=false)
|
98
|
+
raise GlossaryNotFound unless File.exist?(@path)
|
119
99
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
[load_glossary(file), name, source_language, target_language]
|
100
|
+
glossary = Glossary.load_glossary(@path)
|
101
|
+
delete_candidates = target_terms(glossary, source_term)
|
102
|
+
if delete_candidates.empty?
|
103
|
+
raise TermError, "Can't found term '#{source_term} in '#{@glossary}'"
|
125
104
|
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def load_glossary_yml(path)
|
129
|
-
YAML::load_file(path) || []
|
130
|
-
end
|
131
|
-
|
132
|
-
def load_glossary_tsv(path)
|
133
|
-
load_glossary_csv(path, "\t")
|
134
|
-
end
|
135
105
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
106
|
+
if delete_candidates.size == 1 || force
|
107
|
+
glossary.delete_if{|term| term['source_term'] == source_term }
|
108
|
+
dump_glossary(glossary)
|
109
|
+
else
|
110
|
+
raise TermError, "There are duplicate terms in glossary.\n" +
|
111
|
+
"If you really want to delete, please put `loga delete [SOURCE_TERM] --force`\n" +
|
112
|
+
" or `loga delete [SOURCE_TERM] [TARGET_TERM]`"
|
142
113
|
end
|
143
|
-
glossary
|
144
|
-
end
|
145
|
-
|
146
|
-
def logaling_db_home
|
147
|
-
File.join(LOGALING_HOME, "db")
|
148
114
|
end
|
149
115
|
|
116
|
+
private
|
150
117
|
def build_term(source_term, target_term, note)
|
151
118
|
note ||= ''
|
152
119
|
{'source_term' => source_term, 'target_term' => target_term, 'note' => note}
|
@@ -168,20 +135,12 @@ module Logaling
|
|
168
135
|
end
|
169
136
|
end
|
170
137
|
|
171
|
-
def find_term_num(glossary, source_term)
|
172
|
-
glossary.select{|term| term["source_term"] == source_term}.size
|
173
|
-
end
|
174
|
-
|
175
138
|
def bilingual_pair_exists?(glossary, source_term, target_term)
|
176
139
|
target_terms(glossary, source_term).any?{|data| data['target_term'] == target_term }
|
177
140
|
end
|
178
141
|
|
179
142
|
def target_terms(glossary, source_term)
|
180
|
-
|
181
|
-
glossary.each do |term|
|
182
|
-
target_terms << term if term['source_term'] == source_term
|
183
|
-
end
|
184
|
-
target_terms
|
143
|
+
glossary.select {|term| term['source_term'] == source_term }
|
185
144
|
end
|
186
145
|
|
187
146
|
def dump_glossary(glossary)
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require "fileutils"
|
3
|
+
require "logaling/glossary_db"
|
4
|
+
|
5
|
+
module Logaling
|
6
|
+
class Repository
|
7
|
+
def initialize(path)
|
8
|
+
@path = path
|
9
|
+
end
|
10
|
+
|
11
|
+
def register(dot_logaling_path, register_name)
|
12
|
+
FileUtils.mkdir_p(logaling_projects_path) unless File.exist?(logaling_projects_path)
|
13
|
+
symlink_path = File.join(logaling_projects_path, register_name)
|
14
|
+
unless File.exist?(symlink_path)
|
15
|
+
FileUtils.ln_s(dot_logaling_path, symlink_path)
|
16
|
+
else
|
17
|
+
raise GlossaryAlreadyRegistered, register_name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def unregister(register_name)
|
22
|
+
symlink_path = File.join(logaling_projects_path, register_name)
|
23
|
+
if File.exist?(symlink_path)
|
24
|
+
FileUtils.remove_entry_secure(symlink_path, true)
|
25
|
+
else
|
26
|
+
raise GlossaryNotFound, register_name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def lookup(source_term, source_language, target_language, glossary)
|
31
|
+
raise GlossaryDBNotFound unless File.exist?(logaling_db_home)
|
32
|
+
|
33
|
+
terms = []
|
34
|
+
Logaling::GlossaryDB.open(logaling_db_home, "utf8") do |db|
|
35
|
+
terms = db.lookup(source_term)
|
36
|
+
terms.delete_if{|term| term[:source_language] != source_language } if source_language
|
37
|
+
terms.delete_if{|term| term[:target_language] != target_language } if target_language
|
38
|
+
if glossary && !terms.empty?
|
39
|
+
# order by glossary
|
40
|
+
specified = terms.select{|term| term[:name] == glossary}
|
41
|
+
other = terms.select{|term| term[:name] != glossary}
|
42
|
+
terms = specified.concat(other)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
terms
|
46
|
+
end
|
47
|
+
|
48
|
+
def index
|
49
|
+
projects = Dir.glob(File.join(@path, "projects", "*"))
|
50
|
+
|
51
|
+
Logaling::GlossaryDB.open(logaling_db_home, "utf8") do |db|
|
52
|
+
db.recreate_table
|
53
|
+
projects.each do |project|
|
54
|
+
get_glossaries(project).each do |glossary, name, source_language, target_language|
|
55
|
+
db.index_glossary(glossary, name, source_language, target_language)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def registered_project_counts
|
62
|
+
Dir.entries(logaling_projects_path).reject{|dir| dir.sub(/[\.]+/, '').empty?}.size
|
63
|
+
end
|
64
|
+
|
65
|
+
def config_path
|
66
|
+
path = File.join(@path, "config")
|
67
|
+
File.exist?(path) ? path : nil
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
def get_glossaries(path)
|
72
|
+
glob_list = %w(yml tsv csv).map{|type| File.join(path, "glossary", "*.#{type}") }
|
73
|
+
Dir.glob(glob_list).map do |file|
|
74
|
+
name, source_language, target_language = File::basename(file, ".*").split(".")
|
75
|
+
[Glossary.load(file), name, source_language, target_language]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def logaling_db_home
|
80
|
+
File.join(@path, "db")
|
81
|
+
end
|
82
|
+
|
83
|
+
def logaling_projects_path
|
84
|
+
File.join(@path, "projects")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/logaling-command.gemspec
CHANGED
@@ -105,17 +105,29 @@ describe Logaling::Command do
|
|
105
105
|
end
|
106
106
|
|
107
107
|
context "when can not find .logaling" do
|
108
|
-
before
|
108
|
+
before do
|
109
109
|
FileUtils.remove_entry_secure(Logaling::Command::LOGALING_CONFIG, true)
|
110
|
-
@stdout = capture(:stdout) {command.unregister}
|
111
110
|
end
|
112
111
|
|
113
|
-
|
114
|
-
|
112
|
+
context "and call without option" do
|
113
|
+
before do
|
114
|
+
command.options = base_options.merge("glossary" => nil)
|
115
|
+
@stdout = capture(:stdout) {command.unregister}
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should print message 'input glossary name ...'" do
|
119
|
+
@stdout.should be_include "input glossary name"
|
120
|
+
end
|
115
121
|
end
|
116
122
|
|
117
|
-
|
118
|
-
|
123
|
+
context "and call with option" do
|
124
|
+
before do
|
125
|
+
command.new('spec', 'en', 'ja')
|
126
|
+
@stdout = capture(:stdout) {command.unregister}
|
127
|
+
end
|
128
|
+
it 'should unregister symlink' do
|
129
|
+
Dir[File.join(LOGALING_HOME, "projects", "*")].size.should == @project_counts
|
130
|
+
end
|
119
131
|
end
|
120
132
|
end
|
121
133
|
|
@@ -233,9 +245,30 @@ describe Logaling::Command do
|
|
233
245
|
|
234
246
|
it 'succeed at find by term without command.index' do
|
235
247
|
@stdout.should include "spec : スペック # 備考"
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
context 'only one project exist in LOGALING_HOME/projects' do
|
252
|
+
before do
|
253
|
+
Dir.should_receive(:entries).with(File.join(LOGALING_HOME, "projects")).and_return([".", "..", "spec"])
|
254
|
+
@stdout = capture(:stdout) {command.lookup("spec")}
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'should not show glossary name' do
|
236
258
|
@stdout.should_not include "(spec)"
|
237
259
|
end
|
238
260
|
end
|
261
|
+
|
262
|
+
context 'some projects exist in LOGALING_HOME/projects' do
|
263
|
+
before do
|
264
|
+
Dir.should_receive(:entries).with(File.join(LOGALING_HOME, "projects")).and_return([".", "..", "spec", "spec2"])
|
265
|
+
@stdout = capture(:stdout) {command.lookup("spec")}
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'should show glossary name' do
|
269
|
+
@stdout.should include "(spec)"
|
270
|
+
end
|
271
|
+
end
|
239
272
|
end
|
240
273
|
|
241
274
|
describe "#delete" do
|
@@ -7,6 +7,7 @@ module Logaling
|
|
7
7
|
let(:project) { "spec" }
|
8
8
|
let(:glossary) { Glossary.new(project, 'en', 'ja') }
|
9
9
|
let(:glossary_path) { Glossary.build_path(project, 'en', 'ja') }
|
10
|
+
let(:repository) { Logaling::Repository.new(LOGALING_HOME) }
|
10
11
|
|
11
12
|
before do
|
12
13
|
FileUtils.remove_entry_secure(File.join(LOGALING_HOME, 'projects', 'spec'), true)
|
@@ -74,178 +75,76 @@ module Logaling
|
|
74
75
|
end
|
75
76
|
|
76
77
|
describe '#delete' do
|
77
|
-
context '
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
@result = glossary.lookup("delete")
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'should delete the bilingual pair' do
|
88
|
-
@result.should include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"delete", :target_term=>"てすと2", :note=>"備考"})
|
89
|
-
@result.should_not include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"delete", :target_term=>"てすと1", :note=>"備考"})
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
context 'bilingual pair does not exist' do
|
94
|
-
before do
|
95
|
-
glossary.add("user", "ユーザ", "ユーザーではない")
|
96
|
-
end
|
97
|
-
|
98
|
-
it {
|
99
|
-
-> { glossary.delete("user", "ユーザー") }.should raise_error(Logaling::TermError)
|
100
|
-
}
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
context 'not given target_term' do
|
105
|
-
context 'source_term not found' do
|
106
|
-
before do
|
107
|
-
glossary.add("user", "ユーザ", "備考")
|
108
|
-
end
|
109
|
-
|
110
|
-
it {
|
111
|
-
-> { glossary.delete("usr") }.should raise_error(Logaling::TermError)
|
112
|
-
}
|
78
|
+
context 'bilingual pair exists' do
|
79
|
+
before do
|
80
|
+
glossary.add("delete", "てすと1", "備考")
|
81
|
+
glossary.add("delete", "てすと2", "備考")
|
82
|
+
glossary.delete("delete", "てすと1")
|
83
|
+
repository.index
|
84
|
+
@result = repository.lookup("delete", "en", "ja", project)
|
113
85
|
end
|
114
86
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
glossary.add("user", "ユーザ", "備考")
|
119
|
-
glossary.delete("user")
|
120
|
-
glossary.index
|
121
|
-
@result = glossary.lookup("user")
|
122
|
-
end
|
123
|
-
|
124
|
-
it 'should delete the term' do
|
125
|
-
@result.should_not include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"user", :target_term=>"ユーザ", :note=>"備考"})
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
context 'there are more than 1 bilingual pair' do
|
130
|
-
before do
|
131
|
-
glossary.add("user", "ユーザ1", "備考")
|
132
|
-
glossary.add("user", "ユーザ2", "備考")
|
133
|
-
glossary.add("delete", "てすと1", "備考")
|
134
|
-
glossary.add("delete", "てすと2", "備考")
|
135
|
-
glossary.delete("delete", "", true)
|
136
|
-
glossary.index
|
137
|
-
@result = glossary.lookup("delete")
|
138
|
-
end
|
139
|
-
|
140
|
-
it {
|
141
|
-
-> { glossary.delete("user") }.should raise_error(Logaling::TermError)
|
142
|
-
}
|
143
|
-
|
144
|
-
it "should delete terms when force option is true" do
|
145
|
-
@result.should_not include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"delete", :target_term=>"てすと1", :note=>"備考"})
|
146
|
-
@result.should_not include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"delete", :target_term=>"てすと2", :note=>"備考"})
|
147
|
-
end
|
148
|
-
end
|
87
|
+
it 'should delete the bilingual pair' do
|
88
|
+
@result.should include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"delete", :target_term=>"てすと2", :note=>"備考"})
|
89
|
+
@result.should_not include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"delete", :target_term=>"てすと1", :note=>"備考"})
|
149
90
|
end
|
150
91
|
end
|
151
|
-
end
|
152
|
-
|
153
|
-
describe '#lookup' do
|
154
|
-
before do
|
155
|
-
glossary.add("user", "ユーザ", "ユーザーではない")
|
156
|
-
glossary.index
|
157
|
-
end
|
158
|
-
|
159
|
-
context 'with arguments show existing bilingual pair' do
|
160
|
-
subject {glossary.lookup("user")}
|
161
|
-
|
162
|
-
it 'succeed at find by term' do
|
163
|
-
should be_include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"user", :target_term=>"ユーザ", :note=>"ユーザーではない"})
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
context 'when tsv file as glossary exists' do
|
168
|
-
let(:tsv_path) { File.join(File.dirname(glossary_path), "spec.en.ja.tsv") }
|
169
92
|
|
93
|
+
context 'bilingual pair does not exist' do
|
170
94
|
before do
|
171
|
-
|
172
|
-
FileUtils.touch(tsv_path)
|
173
|
-
File.open(tsv_path, "w"){|f| f.puts "user\tユーザー"}
|
174
|
-
glossary.index
|
175
|
-
end
|
176
|
-
|
177
|
-
subject {glossary.lookup("user")}
|
178
|
-
|
179
|
-
it 'succeed at find by term' do
|
180
|
-
should be_include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"user", :target_term=>"ユーザー", :note=>''})
|
95
|
+
glossary.add("user", "ユーザ", "ユーザーではない")
|
181
96
|
end
|
182
97
|
|
183
|
-
|
184
|
-
|
185
|
-
|
98
|
+
it {
|
99
|
+
-> { glossary.delete("user", "ユーザー") }.should raise_error(Logaling::TermError)
|
100
|
+
}
|
186
101
|
end
|
187
102
|
end
|
188
103
|
|
189
|
-
describe '#
|
190
|
-
|
191
|
-
let(:logaling_db) { Logaling::GlossaryDB.new }
|
192
|
-
let(:tsv_path) { File.join(File.dirname(glossary_path), "spec.en.ja.tsv") }
|
193
|
-
let(:csv_path) { File.join(File.dirname(glossary_path), "spec.en.ja.csv") }
|
194
|
-
|
195
|
-
context 'when yml file as glossary exists' do
|
104
|
+
describe '#delete_all' do
|
105
|
+
context 'source_term not found' do
|
196
106
|
before do
|
197
|
-
|
198
|
-
FileUtils.touch(glossary_path)
|
199
|
-
glossary.add("spec", "スペック", "備考")
|
200
|
-
glossary.index
|
107
|
+
glossary.add("user", "ユーザ", "備考")
|
201
108
|
end
|
202
109
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
should be_include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"spec", :target_term=>"スペック", :note=>"備考"})
|
207
|
-
end
|
208
|
-
|
209
|
-
after do
|
210
|
-
FileUtils.remove_entry_secure(glossary_path, true)
|
211
|
-
end
|
110
|
+
it {
|
111
|
+
-> { glossary.delete_all("usr") }.should raise_error(Logaling::TermError)
|
112
|
+
}
|
212
113
|
end
|
213
114
|
|
214
|
-
context '
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
subject { logaling_db.open(db_home, "utf8"){|db| logaling_db.lookup("user")} }
|
223
|
-
|
224
|
-
it 'glossaries should be indexed' do
|
225
|
-
should == [{:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"user", :target_term=>"ユーザ", :note=>''}]
|
226
|
-
end
|
227
|
-
|
228
|
-
after do
|
229
|
-
FileUtils.remove_entry_secure(tsv_path, true)
|
230
|
-
end
|
231
|
-
end
|
115
|
+
context 'source_term found' do
|
116
|
+
context 'there is only 1 bilingual pair' do
|
117
|
+
before do
|
118
|
+
glossary.add("user", "ユーザ", "備考")
|
119
|
+
glossary.delete_all("user")
|
120
|
+
repository.index
|
121
|
+
@result = repository.lookup("user", "en", "ja", project)
|
122
|
+
end
|
232
123
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
FileUtils.touch(csv_path)
|
237
|
-
File.open(csv_path, "w"){|f| f.puts "test,テスト"}
|
238
|
-
glossary.index
|
124
|
+
it 'should delete the term' do
|
125
|
+
@result.should_not include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"user", :target_term=>"ユーザ", :note=>"備考"})
|
126
|
+
end
|
239
127
|
end
|
240
128
|
|
241
|
-
|
129
|
+
context 'there are more than 1 bilingual pair' do
|
130
|
+
before do
|
131
|
+
glossary.add("user", "ユーザ1", "備考")
|
132
|
+
glossary.add("user", "ユーザ2", "備考")
|
133
|
+
glossary.add("delete", "てすと1", "備考")
|
134
|
+
glossary.add("delete", "てすと2", "備考")
|
135
|
+
glossary.delete_all("delete", true)
|
136
|
+
repository.index
|
137
|
+
@result = repository.lookup("delete", "en", "ja", project)
|
138
|
+
end
|
242
139
|
|
243
|
-
|
244
|
-
|
245
|
-
|
140
|
+
it {
|
141
|
+
-> { glossary.delete_all("user") }.should raise_error(Logaling::TermError)
|
142
|
+
}
|
246
143
|
|
247
|
-
|
248
|
-
|
144
|
+
it "should delete terms when force option is true" do
|
145
|
+
@result.should_not include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"delete", :target_term=>"てすと1", :note=>"備考"})
|
146
|
+
@result.should_not include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"delete", :target_term=>"てすと2", :note=>"備考"})
|
147
|
+
end
|
249
148
|
end
|
250
149
|
end
|
251
150
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), "..", "spec_helper")
|
3
|
+
require "fileutils"
|
4
|
+
|
5
|
+
module Logaling
|
6
|
+
describe Repository do
|
7
|
+
let(:project) { "spec" }
|
8
|
+
let(:glossary) { Glossary.new(project, 'en', 'ja') }
|
9
|
+
let(:glossary_path) { Glossary.build_path(project, 'en', 'ja') }
|
10
|
+
let(:repository) { Logaling::Repository.new(LOGALING_HOME) }
|
11
|
+
|
12
|
+
before do
|
13
|
+
FileUtils.remove_entry_secure(File.join(LOGALING_HOME, 'projects', 'spec'), true)
|
14
|
+
FileUtils.mkdir_p(File.dirname(glossary_path))
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#lookup' do
|
18
|
+
before do
|
19
|
+
glossary.add("user", "ユーザ", "ユーザーではない")
|
20
|
+
repository.index
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'with arguments show existing bilingual pair' do
|
24
|
+
subject {repository.lookup("user", "en", "ja", project)}
|
25
|
+
|
26
|
+
it 'succeed at find by term' do
|
27
|
+
should be_include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"user", :target_term=>"ユーザ", :note=>"ユーザーではない"})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when tsv file as glossary exists' do
|
32
|
+
let(:tsv_path) { glossary_path.sub(/yml$/, 'tsv') }
|
33
|
+
|
34
|
+
before do
|
35
|
+
FileUtils.mkdir_p(File.dirname(tsv_path))
|
36
|
+
FileUtils.touch(tsv_path)
|
37
|
+
File.open(tsv_path, "w"){|f| f.puts "user\tユーザー"}
|
38
|
+
repository.index
|
39
|
+
end
|
40
|
+
|
41
|
+
subject {repository.lookup("user", "en", "ja", project)}
|
42
|
+
|
43
|
+
it 'succeed at find by term' do
|
44
|
+
should be_include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"user", :target_term=>"ユーザー", :note=>''})
|
45
|
+
end
|
46
|
+
|
47
|
+
after do
|
48
|
+
FileUtils.remove_entry_secure(tsv_path, true)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#index' do
|
54
|
+
let(:db_home) { File.join(LOGALING_HOME, "db") }
|
55
|
+
let(:logaling_db) { Logaling::GlossaryDB.new }
|
56
|
+
let(:tsv_path) { File.join(File.dirname(glossary_path), "spec.en.ja.tsv") }
|
57
|
+
let(:csv_path) { File.join(File.dirname(glossary_path), "spec.en.ja.csv") }
|
58
|
+
|
59
|
+
context 'when yml file as glossary exists' do
|
60
|
+
before do
|
61
|
+
FileUtils.mkdir_p(File.dirname(glossary_path))
|
62
|
+
FileUtils.touch(glossary_path)
|
63
|
+
glossary.add("spec", "スペック", "備考")
|
64
|
+
repository.index
|
65
|
+
end
|
66
|
+
|
67
|
+
subject { logaling_db.open(db_home, "utf8"){|db| logaling_db.lookup("spec")} }
|
68
|
+
|
69
|
+
it 'glossaries should be indexed' do
|
70
|
+
should be_include({:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"spec", :target_term=>"スペック", :note=>"備考"})
|
71
|
+
end
|
72
|
+
|
73
|
+
after do
|
74
|
+
FileUtils.remove_entry_secure(glossary_path, true)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'when tsv file as glossary exists' do
|
79
|
+
before do
|
80
|
+
FileUtils.mkdir_p(File.dirname(glossary_path))
|
81
|
+
FileUtils.touch(tsv_path)
|
82
|
+
File.open(tsv_path, "w"){|f| f.puts "user\tユーザ"}
|
83
|
+
repository.index
|
84
|
+
end
|
85
|
+
|
86
|
+
subject { logaling_db.open(db_home, "utf8"){|db| logaling_db.lookup("user")} }
|
87
|
+
|
88
|
+
it 'glossaries should be indexed' do
|
89
|
+
should == [{:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"user", :target_term=>"ユーザ", :note=>''}]
|
90
|
+
end
|
91
|
+
|
92
|
+
after do
|
93
|
+
FileUtils.remove_entry_secure(tsv_path, true)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'when csv file as glosary exists' do
|
98
|
+
before do
|
99
|
+
FileUtils.mkdir_p(File.dirname(glossary_path))
|
100
|
+
FileUtils.touch(csv_path)
|
101
|
+
File.open(csv_path, "w"){|f| f.puts "test,テスト"}
|
102
|
+
repository.index
|
103
|
+
end
|
104
|
+
|
105
|
+
subject { logaling_db.open(db_home, "utf8"){|db| logaling_db.lookup("test")} }
|
106
|
+
|
107
|
+
it 'glossaries should be indexed' do
|
108
|
+
should == [{:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"test", :target_term=>"テスト", :note=>''}]
|
109
|
+
end
|
110
|
+
|
111
|
+
after do
|
112
|
+
FileUtils.remove_entry_secure(csv_path, true)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
after do
|
118
|
+
FileUtils.remove_entry_secure(File.join(LOGALING_HOME, 'projects', 'spec'), true)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logaling-command
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,11 +13,11 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2011-12-
|
16
|
+
date: 2011-12-09 00:00:00.000000000Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: thor
|
20
|
-
requirement: &
|
20
|
+
requirement: &2153169540 !ruby/object:Gem::Requirement
|
21
21
|
none: false
|
22
22
|
requirements:
|
23
23
|
- - ! '>='
|
@@ -25,10 +25,10 @@ dependencies:
|
|
25
25
|
version: 0.14.6
|
26
26
|
type: :runtime
|
27
27
|
prerelease: false
|
28
|
-
version_requirements: *
|
28
|
+
version_requirements: *2153169540
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: bundler
|
31
|
-
requirement: &
|
31
|
+
requirement: &2153168180 !ruby/object:Gem::Requirement
|
32
32
|
none: false
|
33
33
|
requirements:
|
34
34
|
- - ! '>='
|
@@ -36,10 +36,10 @@ dependencies:
|
|
36
36
|
version: '1.0'
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
|
-
version_requirements: *
|
39
|
+
version_requirements: *2153168180
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: rake
|
42
|
-
requirement: &
|
42
|
+
requirement: &2153167720 !ruby/object:Gem::Requirement
|
43
43
|
none: false
|
44
44
|
requirements:
|
45
45
|
- - ! '>='
|
@@ -47,10 +47,10 @@ dependencies:
|
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
|
-
version_requirements: *
|
50
|
+
version_requirements: *2153167720
|
51
51
|
- !ruby/object:Gem::Dependency
|
52
52
|
name: rspec
|
53
|
-
requirement: &
|
53
|
+
requirement: &2153166260 !ruby/object:Gem::Requirement
|
54
54
|
none: false
|
55
55
|
requirements:
|
56
56
|
- - ! '>='
|
@@ -58,7 +58,18 @@ dependencies:
|
|
58
58
|
version: '0'
|
59
59
|
type: :development
|
60
60
|
prerelease: false
|
61
|
-
version_requirements: *
|
61
|
+
version_requirements: *2153166260
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rroonga
|
64
|
+
requirement: &2153165060 !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: *2153165060
|
62
73
|
description: A command line interface for logaling.
|
63
74
|
email:
|
64
75
|
- koji.shimada@enishi-tech.com
|
@@ -80,9 +91,11 @@ files:
|
|
80
91
|
- lib/logaling/command.rb
|
81
92
|
- lib/logaling/glossary.rb
|
82
93
|
- lib/logaling/glossary_db.rb
|
94
|
+
- lib/logaling/repository.rb
|
83
95
|
- logaling-command.gemspec
|
84
96
|
- spec/logaling/command_spec.rb
|
85
97
|
- spec/logaling/glossary_spec.rb
|
98
|
+
- spec/logaling/repository_spec.rb
|
86
99
|
- spec/spec_helper.rb
|
87
100
|
homepage: http://logaling.github.com/
|
88
101
|
licenses: []
|
@@ -111,4 +124,5 @@ summary: A command line interface for logaling.
|
|
111
124
|
test_files:
|
112
125
|
- spec/logaling/command_spec.rb
|
113
126
|
- spec/logaling/glossary_spec.rb
|
127
|
+
- spec/logaling/repository_spec.rb
|
114
128
|
- spec/spec_helper.rb
|