chit 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest.txt +9 -0
- data/README.txt +130 -0
- data/Rakefile +19 -0
- data/bin/chit +4 -0
- data/lib/chit.rb +252 -0
- data/lib/wrap.rb +42 -0
- data/resources/chitrc +8 -0
- data/test/test_chit.rb +0 -0
- metadata +84 -0
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
= Chit
|
2
|
+
|
3
|
+
http://github.com/robin/chit
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Chit is a command line cheat sheet utility based on git.
|
8
|
+
|
9
|
+
== FEATURES:
|
10
|
+
|
11
|
+
Chit was inspired by 'cheat' (http://cheat.errtheblog.com/) by Chris Wanstrath. You can use chit to access and manage cheat sheets easily.
|
12
|
+
|
13
|
+
There are several differences between ‘cheat’ and ‘chit’. By using chit, besides the wonderful features of ‘cheat’, you get:
|
14
|
+
|
15
|
+
1. Git powered cheat sheet repository. You can specify where you get the sheets and where to share them.
|
16
|
+
2. Your own private cheat sheets. Everybody has some project related or smoe cheat sheets which are not mean to public. You can also put them into chit
|
17
|
+
3. Directory support. You can group cheat sheets by directory now.
|
18
|
+
4. One less letter to type.
|
19
|
+
|
20
|
+
== SYNOPSIS:
|
21
|
+
|
22
|
+
To initialize chit repositories
|
23
|
+
|
24
|
+
$ chit --init
|
25
|
+
|
26
|
+
This will be run automatically when you run chit for the first time.
|
27
|
+
|
28
|
+
To get a cheat sheet:
|
29
|
+
|
30
|
+
$ chit [cheatsheet]
|
31
|
+
|
32
|
+
To edit a cheat sheet, use the --edit/-e switch.
|
33
|
+
|
34
|
+
$ cheat [cheatsheet] --edit
|
35
|
+
|
36
|
+
To add a cheat sheet, use the --add/-a switch.
|
37
|
+
|
38
|
+
$ cheat [cheatsheet] --add
|
39
|
+
|
40
|
+
During editing a cheat sheet, empty the content will get the cheat sheet removed.
|
41
|
+
|
42
|
+
A prefix '@' indicates the cheat sheet is in private mode. A private cheat sheet is kept in another repository.
|
43
|
+
|
44
|
+
To get your private cheat sheet:
|
45
|
+
|
46
|
+
$ chit @[cheatsheet]
|
47
|
+
|
48
|
+
The prefix '@' works the same for both --edit/-e and --add/-a.
|
49
|
+
|
50
|
+
The cheat sheet can be in a path. For example:
|
51
|
+
|
52
|
+
$ chit mysql/select
|
53
|
+
|
54
|
+
will get the cheat sheet 'select' under mysql.
|
55
|
+
|
56
|
+
To show all the cheat sheets:
|
57
|
+
|
58
|
+
$ chit [all|sheets]
|
59
|
+
|
60
|
+
To show all the private cheat sheets:
|
61
|
+
|
62
|
+
$ chit @[all|sheets]
|
63
|
+
|
64
|
+
To find cheat sheets begin with 'name', use the --find/-f switch
|
65
|
+
|
66
|
+
$ chit name --find
|
67
|
+
|
68
|
+
To search cheat sheets content with 'text', use the --search/-s switch
|
69
|
+
|
70
|
+
$ chit text --search
|
71
|
+
|
72
|
+
To move or rename a sheet, use '--mv/-m' switch
|
73
|
+
|
74
|
+
$ chit zsh_if zsh/if -m
|
75
|
+
|
76
|
+
== INSTALL:
|
77
|
+
|
78
|
+
sudo gem install robin-chit -s http://gems.github.com
|
79
|
+
|
80
|
+
chit --init
|
81
|
+
|
82
|
+
== CONFIGURATION:
|
83
|
+
|
84
|
+
Before run 'chit', you may want to config ~/.chitrc which is a YAML file.
|
85
|
+
|
86
|
+
* root: local path to store the cheat sheet. By default, it is ~/.chit
|
87
|
+
* add_if_not_exist: when set as 'true', if no sheets found, a new one will be created and waiting for editing. Leave it blank and quit the editor if you don't
|
88
|
+
want to add a new one.
|
89
|
+
* main:
|
90
|
+
* clone-from: where to get the public cheat sheets. You can use git://github.com/robin/chitsheet.git, which is a snap shoot of http://cheat.errtheblog.com/.
|
91
|
+
* private:
|
92
|
+
* clone-from: where to get the private cheat sheets. If not specified, a new git repository will be init for private cheat sheets.
|
93
|
+
|
94
|
+
== REQUIREMENTS:
|
95
|
+
|
96
|
+
* rubygems
|
97
|
+
* git
|
98
|
+
|
99
|
+
== LICENSE:
|
100
|
+
|
101
|
+
This software is shared by MIT License
|
102
|
+
|
103
|
+
Copyright (c) 2008 Robin Lu
|
104
|
+
|
105
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
106
|
+
a copy of this software and associated documentation files (the
|
107
|
+
'Software'), to deal in the Software without restriction, including
|
108
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
109
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
110
|
+
permit persons to whom the Software is furnished to do so, subject to
|
111
|
+
the following conditions:
|
112
|
+
|
113
|
+
The above copyright notice and this permission notice shall be
|
114
|
+
included in all copies or substantial portions of the Software.
|
115
|
+
|
116
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
117
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
118
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
119
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
120
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
121
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
122
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
123
|
+
|
124
|
+
== BY:
|
125
|
+
|
126
|
+
Robin Lu
|
127
|
+
|
128
|
+
http://www.robinlu.com
|
129
|
+
|
130
|
+
iamawalrus[at]gmail[dot]com
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require './lib/chit.rb'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |gemspec|
|
9
|
+
gemspec.name = "chit"
|
10
|
+
gemspec.summary = "A command line cheat sheet utility based on git"
|
11
|
+
gemspec.description = "A command line cheat sheet utility based on git"
|
12
|
+
gemspec.email = "iamawalrus@gmail.com"
|
13
|
+
gemspec.homepage = "http://github.com/robin/chit"
|
14
|
+
gemspec.authors = ["Robin Lu"]
|
15
|
+
end
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
18
|
+
end
|
19
|
+
# vim: syntax=Ruby
|
data/bin/chit
ADDED
data/lib/chit.rb
ADDED
@@ -0,0 +1,252 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
%w(rubygems git tempfile fileutils yaml wrap).each {|f| require f}
|
3
|
+
|
4
|
+
module Chit
|
5
|
+
extend self
|
6
|
+
VERSION = '0.0.6'
|
7
|
+
|
8
|
+
defaults = {
|
9
|
+
'root' => File.join("#{ENV['HOME']}",".chit")
|
10
|
+
}
|
11
|
+
|
12
|
+
CHITRC = File.join("#{ENV['HOME']}",".chitrc")
|
13
|
+
|
14
|
+
FileUtils.cp(File.join(File.dirname(__FILE__), "..","resources","chitrc"), CHITRC) unless File.exist?(CHITRC)
|
15
|
+
|
16
|
+
CONFIG = defaults.merge(YAML.load_file(CHITRC))
|
17
|
+
|
18
|
+
def run(args)
|
19
|
+
unless File.exist?(main_path) && File.exist?(private_path)
|
20
|
+
return unless init_chit
|
21
|
+
end
|
22
|
+
args = args.dup
|
23
|
+
|
24
|
+
return unless parse_args(args)
|
25
|
+
|
26
|
+
if %w[sheets all].include? @sheet
|
27
|
+
return list_all()
|
28
|
+
end
|
29
|
+
|
30
|
+
unless File.exist?(sheet_file)
|
31
|
+
update
|
32
|
+
end
|
33
|
+
|
34
|
+
unless File.exist?(sheet_file)
|
35
|
+
if args.delete('--no-add').nil? && CONFIG['add_if_not_exist']
|
36
|
+
add(sheet_file)
|
37
|
+
else
|
38
|
+
puts "Error!:\n #{@sheet} not found"
|
39
|
+
puts "Possible sheets:"
|
40
|
+
search_title
|
41
|
+
end
|
42
|
+
else
|
43
|
+
format = 'html' if args.delete('--html')
|
44
|
+
show(sheet_file,format)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def parse_args(args)
|
49
|
+
init_chit and return if args.delete('--init')
|
50
|
+
update and return if args.delete('--update')
|
51
|
+
|
52
|
+
@sheet = args.shift || 'chit'
|
53
|
+
is_private = (@sheet =~ /^@(.*)/)
|
54
|
+
@sheet = is_private ? $1 : @sheet
|
55
|
+
|
56
|
+
@working_dir = is_private ? private_path : main_path
|
57
|
+
@git = Git.open(@working_dir)
|
58
|
+
|
59
|
+
@fullpath = File.join(@working_dir, "#{@sheet}.yml")
|
60
|
+
|
61
|
+
add(sheet_file) and return if (args.delete('--add')||args.delete('-a'))
|
62
|
+
edit(sheet_file) and return if (args.delete('--edit')||args.delete('-e'))
|
63
|
+
search_title and return if (args.delete('--find')||args.delete('-f'))
|
64
|
+
search_content and return if (args.delete('--search')||args.delete('-s'))
|
65
|
+
|
66
|
+
if (args.delete('--mv') || args.delete('-m'))
|
67
|
+
target = args.shift
|
68
|
+
mv_to(target) and return if target
|
69
|
+
puts "Target not specified!"
|
70
|
+
return
|
71
|
+
end
|
72
|
+
true
|
73
|
+
end
|
74
|
+
|
75
|
+
def list_all
|
76
|
+
puts all_sheets.sort.join("\n")
|
77
|
+
end
|
78
|
+
|
79
|
+
def mv_to(target)
|
80
|
+
if target =~ /^@(.*)/
|
81
|
+
target = $1
|
82
|
+
end
|
83
|
+
target_path = File.join(@working_dir, "#{target}.yml")
|
84
|
+
prepare_dir(target_path)
|
85
|
+
@git.lib.mv(sheet_file, target_path)
|
86
|
+
sheet = YAML.load(IO.read(target_path)).to_a.first
|
87
|
+
body = sheet[-1]
|
88
|
+
title = parse_title(target)
|
89
|
+
open(target_path,'w') {|f| f << {title => body}.to_yaml}
|
90
|
+
@git.add
|
91
|
+
@git.commit_all(" #{@sheet} moved to #{target}")
|
92
|
+
end
|
93
|
+
|
94
|
+
def search_content
|
95
|
+
@git.grep(@sheet).each {|file, lines|
|
96
|
+
title = title_of_file(file.split(':')[1])
|
97
|
+
lines.each {|l|
|
98
|
+
puts "#{title}:#{l[0]}: #{l[1]}"
|
99
|
+
}
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
def search_title
|
104
|
+
reg = Regexp.compile("^#{@sheet}")
|
105
|
+
files = all_sheets.select {|sheet| sheet =~ reg }
|
106
|
+
puts " " + files.sort.join("\n ")
|
107
|
+
true
|
108
|
+
end
|
109
|
+
|
110
|
+
def sheet_file
|
111
|
+
@fullpath
|
112
|
+
end
|
113
|
+
|
114
|
+
def init_chit
|
115
|
+
FileUtils.mkdir_p(CONFIG['root'])
|
116
|
+
if CONFIG['main']['clone-from']
|
117
|
+
if File.exist?(main_path)
|
118
|
+
puts "Main chit has already been initialized."
|
119
|
+
else
|
120
|
+
puts "Initialize main chit from #{CONFIG['main']['clone-from']} to #{CONFIG['root']}/main"
|
121
|
+
Git.clone(CONFIG['main']['clone-from'], 'main', :path => CONFIG['root'])
|
122
|
+
puts "Main chit initialized."
|
123
|
+
end
|
124
|
+
else
|
125
|
+
puts "ERROR: configuration for main chit repository is missing!"
|
126
|
+
return
|
127
|
+
end
|
128
|
+
|
129
|
+
unless File.exist?(private_path)
|
130
|
+
if CONFIG['private'] && CONFIG['private']['clone-from']
|
131
|
+
puts "Initialize private chit from #{CONFIG['private']['clone-from']} to #{CONFIG['root']}/private"
|
132
|
+
Git.clone(CONFIG['private']['clone-from'], 'private', :path => CONFIG['root'])
|
133
|
+
puts "Private chit initialized."
|
134
|
+
else
|
135
|
+
puts "Initialize private chit from scratch to #{CONFIG['root']}/private"
|
136
|
+
git = Git.init(private_path)
|
137
|
+
FileUtils.touch(File.join(CONFIG['root'],'private','.gitignore'))
|
138
|
+
git.add
|
139
|
+
git.commit_all("init private repository")
|
140
|
+
puts "Private chit initialized."
|
141
|
+
end
|
142
|
+
else
|
143
|
+
puts "Private chit has already been initialized."
|
144
|
+
end
|
145
|
+
puts "Chit init done."
|
146
|
+
true
|
147
|
+
end
|
148
|
+
|
149
|
+
def update
|
150
|
+
if CONFIG['main']['clone-from']
|
151
|
+
g = Git.open(main_path)
|
152
|
+
g.pull
|
153
|
+
end
|
154
|
+
rescue
|
155
|
+
puts "ERROR: can not update main chit."
|
156
|
+
puts $!
|
157
|
+
end
|
158
|
+
|
159
|
+
def main_path
|
160
|
+
File.join(CONFIG['root'], 'main')
|
161
|
+
end
|
162
|
+
|
163
|
+
def private_path
|
164
|
+
File.join(CONFIG['root'], 'private')
|
165
|
+
end
|
166
|
+
|
167
|
+
def show(file,format=nil)
|
168
|
+
sheet = YAML.load(IO.read(file)).to_a.first
|
169
|
+
sheet[-1] = sheet.last.join("\n") if sheet[-1].is_a?(Array)
|
170
|
+
case format
|
171
|
+
when 'html'
|
172
|
+
puts "<h1>#{sheet.first}</h1>"
|
173
|
+
puts "<pre>#{sheet.last.gsub("\r",'').gsub("\n", "\n ").wrap}</pre>"
|
174
|
+
else
|
175
|
+
puts sheet.first + ':'
|
176
|
+
puts ' ' + sheet.last.gsub("\r",'').gsub("\n", "\n ").wrap
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def rm(file)
|
181
|
+
@git.remove(file)
|
182
|
+
@git.commit_all("#{@sheet} removed")
|
183
|
+
rescue Git::GitExecuteError
|
184
|
+
FileUtils.rm_rf(file)
|
185
|
+
end
|
186
|
+
|
187
|
+
def add(file)
|
188
|
+
unless File.exist?(file)
|
189
|
+
prepare_dir(file)
|
190
|
+
title = parse_title(@sheet)
|
191
|
+
yml = {"#{title}" => ''}.to_yaml
|
192
|
+
open(file, 'w') {|f| f << yml}
|
193
|
+
end
|
194
|
+
edit(file)
|
195
|
+
end
|
196
|
+
|
197
|
+
def edit(file)
|
198
|
+
sheet = YAML.load(IO.read(file)).to_a.first
|
199
|
+
sheet[-1] = sheet.last.gsub("\r", '')
|
200
|
+
body, title = write_to_tempfile(*sheet), sheet.first
|
201
|
+
if body.strip.empty?
|
202
|
+
rm(file)
|
203
|
+
else
|
204
|
+
open(file,'w') {|f| f << {title => body}.to_yaml}
|
205
|
+
@git.add
|
206
|
+
st = @git.status
|
207
|
+
unless st.added.empty? && st.changed.empty? && st.deleted.empty? && st.untracked.empty?
|
208
|
+
@git.commit_all(" #{@sheet} updated")
|
209
|
+
end
|
210
|
+
end
|
211
|
+
true
|
212
|
+
end
|
213
|
+
|
214
|
+
private
|
215
|
+
def parse_title(sheet_name)
|
216
|
+
sheet_name.split(File::Separator).join('::')
|
217
|
+
end
|
218
|
+
|
219
|
+
def prepare_dir(file)
|
220
|
+
breaker = file.rindex(File::Separator)+1
|
221
|
+
path = file[0,breaker]
|
222
|
+
FileUtils.mkdir_p(path)
|
223
|
+
end
|
224
|
+
|
225
|
+
def editor
|
226
|
+
ENV['VISUAL'] || ENV['EDITOR'] || "vim"
|
227
|
+
end
|
228
|
+
|
229
|
+
def write_to_tempfile(title, body = nil)
|
230
|
+
title = title.gsub(/\/|::/, '-')
|
231
|
+
# god dammit i hate tempfile, this is so messy but i think it's
|
232
|
+
# the only way.
|
233
|
+
tempfile = Tempfile.new(title + '.cheat')
|
234
|
+
tempfile.write(body) if body
|
235
|
+
tempfile.close
|
236
|
+
system "#{editor} #{tempfile.path}"
|
237
|
+
tempfile.open
|
238
|
+
body = tempfile.read
|
239
|
+
tempfile.close
|
240
|
+
body
|
241
|
+
end
|
242
|
+
|
243
|
+
def all_sheets
|
244
|
+
@git.ls_files.to_a.map {|f|
|
245
|
+
title_of_file(f[0])}
|
246
|
+
end
|
247
|
+
|
248
|
+
def title_of_file(f)
|
249
|
+
f[0..((f.rindex('.')||0) - 1)]
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
data/lib/wrap.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# >> Evan Weaver
|
2
|
+
# => http://blog.evanweaver.com/articles/2006/09/03/smart-plaintext-wrapping
|
3
|
+
class String
|
4
|
+
def wrap(width = 80, hanging_indent = 0, magic_lists = false)
|
5
|
+
lines = self.split(/\n/)
|
6
|
+
|
7
|
+
lines.collect! do |line|
|
8
|
+
|
9
|
+
if magic_lists
|
10
|
+
line =~ /^([\s\-\d\.\:]*\s)/
|
11
|
+
else
|
12
|
+
line =~ /^([\s]*\s)/
|
13
|
+
end
|
14
|
+
|
15
|
+
indent = $1.length + hanging_indent rescue hanging_indent
|
16
|
+
|
17
|
+
buffer = ""
|
18
|
+
first = true
|
19
|
+
|
20
|
+
while line.length > 0
|
21
|
+
first ? (i, first = 0, false) : i = indent
|
22
|
+
pos = width - i
|
23
|
+
|
24
|
+
if line.length > pos and line[0..pos] =~ /^(.+)\s/
|
25
|
+
subline = $1
|
26
|
+
else
|
27
|
+
subline = line[0..pos]
|
28
|
+
end
|
29
|
+
buffer += " " * i + subline + "\n"
|
30
|
+
line.tail!(subline.length)
|
31
|
+
end
|
32
|
+
buffer[0..-2]
|
33
|
+
end
|
34
|
+
|
35
|
+
lines.join("\n")
|
36
|
+
end
|
37
|
+
|
38
|
+
def tail!(pos)
|
39
|
+
self[0..pos] = ""
|
40
|
+
strip!
|
41
|
+
end
|
42
|
+
end
|
data/resources/chitrc
ADDED
data/test/test_chit.rb
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: chit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.6
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Robin Lu
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-06-19 00:00:00 +08:00
|
13
|
+
default_executable: chit
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: schacon-git
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "1.0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: hoe
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.5.3
|
34
|
+
version:
|
35
|
+
description: Chit is A command line tool for cheat sheet utility based on git.
|
36
|
+
email:
|
37
|
+
- iamawalrus@gmail.com
|
38
|
+
executables:
|
39
|
+
- chit
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files:
|
43
|
+
- Manifest.txt
|
44
|
+
- README.txt
|
45
|
+
files:
|
46
|
+
- Manifest.txt
|
47
|
+
- README.txt
|
48
|
+
- Rakefile
|
49
|
+
- bin/chit
|
50
|
+
- lib/chit.rb
|
51
|
+
- lib/wrap.rb
|
52
|
+
- resources/chitrc
|
53
|
+
- test/test_chit.rb
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: http://github.com/robin/chit
|
56
|
+
licenses: []
|
57
|
+
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options:
|
60
|
+
- --main
|
61
|
+
- README.txt
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
version:
|
76
|
+
requirements: []
|
77
|
+
|
78
|
+
rubyforge_project: chit
|
79
|
+
rubygems_version: 1.3.5
|
80
|
+
signing_key:
|
81
|
+
specification_version: 2
|
82
|
+
summary: Chit is A command line tool for cheat sheet utility based on git.
|
83
|
+
test_files:
|
84
|
+
- test/test_chit.rb
|