defcli 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/defcli.rb +44 -0
- data/lib/defcli/formatting.rb +114 -0
- data/tests/formatting_tests.rb +96 -0
- data/tests/tests.rb +54 -0
- metadata +157 -0
- metadata.gz.sig +2 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 671ad3b060e2945f7eeda6802e5327565596986a2934c85635efcb7678ad065e
|
4
|
+
data.tar.gz: 22927817e5e29dc4845b44575af9ca1d061b81ff7f8bd4cae047d4aba86c11bc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5be8378f87f339c13a49c660d01dca507b59467ffd5ae033f487f562b22cd2210ab2bf65d36a96bb346625a6110b2f1169406515caef9e97ea2206fedd112eb4
|
7
|
+
data.tar.gz: 43fdb3e659694db3b5a34c5fedbe3d56f40ba0f0ba0a8089c9bca9c0446d30209dd2f9210d7c815d57a6f0565f3e4e9c826f32c72e6b5929afdde325e6c612e6
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
Binary file
|
data/lib/defcli.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
|
3
|
+
require "uri"
|
4
|
+
require "json"
|
5
|
+
require "open-uri"
|
6
|
+
|
7
|
+
require_relative "./defcli/formatting"
|
8
|
+
|
9
|
+
module Defcli
|
10
|
+
class << self
|
11
|
+
def version
|
12
|
+
"0.0.1"
|
13
|
+
end
|
14
|
+
|
15
|
+
# Format results for output
|
16
|
+
# @param results [Array] array of results
|
17
|
+
# @param color [Boolean] colored output
|
18
|
+
# @return [String]
|
19
|
+
def format_results(results, color = true)
|
20
|
+
Defcli::Formatting.format_results(results, color)
|
21
|
+
end
|
22
|
+
|
23
|
+
def read_url(url)
|
24
|
+
OpenURI.open_uri(url).read
|
25
|
+
end
|
26
|
+
|
27
|
+
def open_in_browser(url)
|
28
|
+
system open_cmd, url
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def open_cmd
|
34
|
+
case RbConfig::CONFIG["host_os"]
|
35
|
+
when /darwin/
|
36
|
+
"open"
|
37
|
+
when /bsd|linux/
|
38
|
+
"xdg-open"
|
39
|
+
when /cygwin|mingw|mswin/
|
40
|
+
"start"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
|
3
|
+
module Defcli
|
4
|
+
module Formatting
|
5
|
+
class << self
|
6
|
+
# Fit a text in a given width (number of chars).
|
7
|
+
# @param txt [String]
|
8
|
+
# @param width [Integer] maximum width
|
9
|
+
# @return [Array] list of lines of text
|
10
|
+
def fit(txt, width = 79)
|
11
|
+
return [] if width < 1
|
12
|
+
|
13
|
+
# from https://stackoverflow.com/a/7567210/735926
|
14
|
+
r = /(.{1,#{width}})(?:\s|$)/m
|
15
|
+
txt.split("\n").map { |l| l.scan(r) }.flatten
|
16
|
+
end
|
17
|
+
|
18
|
+
# Add a tab at the beginning of a text. If it's a list, add a tab at
|
19
|
+
# the beginning of each element.
|
20
|
+
# @param txt [String] The text to tab, may be a string or a list of
|
21
|
+
# strings
|
22
|
+
# @param width [Integer] tab width
|
23
|
+
# @return [String]
|
24
|
+
def tab(txt, width = 4)
|
25
|
+
return txt if width <= 0
|
26
|
+
|
27
|
+
tab = " " * width
|
28
|
+
|
29
|
+
return tab + txt if txt.is_a? String
|
30
|
+
|
31
|
+
txt.map { |l| tab + l }
|
32
|
+
end
|
33
|
+
|
34
|
+
# Format results for text output (e.g. in the terminal)
|
35
|
+
# @param results [Array<Hash>] array of results
|
36
|
+
# @param color [Boolean] colored output
|
37
|
+
# @return [String]
|
38
|
+
def format_results(results, color = true)
|
39
|
+
results.map { |r| format_result(r, color) }.join "\n"
|
40
|
+
end
|
41
|
+
|
42
|
+
def format_result(r, color = true)
|
43
|
+
require "colored" if color
|
44
|
+
|
45
|
+
word = r[:word]
|
46
|
+
word = word.bold if color
|
47
|
+
|
48
|
+
rating = format_result_rating(r, color)
|
49
|
+
|
50
|
+
definition = tab(fit(r[:definition], 75)).join "\n"
|
51
|
+
|
52
|
+
text = "* #{word}"
|
53
|
+
text << " (#{rating})" if rating
|
54
|
+
text << ":\n\n#{definition}\n"
|
55
|
+
|
56
|
+
text << "(📍 #{r[:location]})\n" if r[:location]
|
57
|
+
|
58
|
+
text << (format_result_examples(r, color) or "")
|
59
|
+
|
60
|
+
text + "\n\n"
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def format_result_examples(r, color = true)
|
66
|
+
examples = if r[:example]
|
67
|
+
[r[:example]]
|
68
|
+
elsif r[:examples]
|
69
|
+
r[:examples]
|
70
|
+
else
|
71
|
+
[]
|
72
|
+
end
|
73
|
+
|
74
|
+
if examples.count == 1
|
75
|
+
example = tab(fit(examples.first, 75)).join "\n"
|
76
|
+
"\n Example:\n#{example}\n"
|
77
|
+
|
78
|
+
elsif examples.count > 1
|
79
|
+
examples = examples.map do |e|
|
80
|
+
tab(fit(e, 75)).join "\n"
|
81
|
+
end.join "\n"
|
82
|
+
"\n Examples:\n#{examples}\n"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def format_result_rating(r, color = true)
|
87
|
+
if r[:upvotes]
|
88
|
+
# upvotes/downvotes
|
89
|
+
upvotes = r[:upvotes]
|
90
|
+
downvotes = r[:downvotes]
|
91
|
+
if color
|
92
|
+
upvotes = upvotes.to_s.green
|
93
|
+
downvotes = downvotes.to_s.red
|
94
|
+
end
|
95
|
+
|
96
|
+
"#{upvotes}/#{downvotes}"
|
97
|
+
elsif r[:ratio]
|
98
|
+
percentage = r[:ratio] * 100.0
|
99
|
+
rating = format("%2d%%", percentage)
|
100
|
+
|
101
|
+
if color
|
102
|
+
if percentage > 60
|
103
|
+
rating = rating.green
|
104
|
+
else
|
105
|
+
rating = rating.red
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
rating
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
class DefcliFormattingTest < Test::Unit::TestCase
|
2
|
+
|
3
|
+
# == Defcli::Formatting.format_results == #
|
4
|
+
|
5
|
+
def test_format_results_empty_list
|
6
|
+
assert_equal('', Defcli.format_results([]))
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_format_results_one_element_no_color
|
10
|
+
res = {
|
11
|
+
:word => 'XYZ',
|
12
|
+
:upvotes => 42,
|
13
|
+
:downvotes => 78,
|
14
|
+
:definition => 'xyz',
|
15
|
+
:example => 'zyx'
|
16
|
+
}
|
17
|
+
|
18
|
+
output = Defcli.format_results([res], false).strip
|
19
|
+
expected = <<EOS
|
20
|
+
* XYZ (42/78):
|
21
|
+
|
22
|
+
xyz
|
23
|
+
|
24
|
+
Example:
|
25
|
+
zyx
|
26
|
+
EOS
|
27
|
+
|
28
|
+
assert_equal(expected.strip, output)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_format_results_one_element_color
|
32
|
+
green = "\e[32m"
|
33
|
+
bold = "\e[1m"
|
34
|
+
red = "\e[31m"
|
35
|
+
reset = "\e[0m"
|
36
|
+
res = {
|
37
|
+
:word => 'XYZ',
|
38
|
+
:upvotes => 42,
|
39
|
+
:downvotes => 78,
|
40
|
+
:definition => 'xyz',
|
41
|
+
:example => 'zyx'
|
42
|
+
}
|
43
|
+
|
44
|
+
output = Defcli.format_results([res], true).strip
|
45
|
+
expected = <<EOS
|
46
|
+
* #{bold}XYZ#{reset} (#{green}42#{reset}/#{red}78#{reset}):
|
47
|
+
|
48
|
+
xyz
|
49
|
+
|
50
|
+
Example:
|
51
|
+
zyx
|
52
|
+
EOS
|
53
|
+
|
54
|
+
assert_equal(expected.strip, output)
|
55
|
+
end
|
56
|
+
|
57
|
+
# == Defcli::Formatting.fit == #
|
58
|
+
|
59
|
+
def test_fit_0_width
|
60
|
+
assert_equal([], Defcli::Formatting.fit('foo', 0))
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_fit_negative_width
|
64
|
+
assert_equal([], Defcli::Formatting.fit('foo', -1))
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_fit_right_width
|
68
|
+
assert_equal(['foo'], Defcli::Formatting.fit('foo', 3))
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_fit_larger_width
|
72
|
+
assert_equal(['foo'], Defcli::Formatting.fit('foo', 4))
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_fit_smaller_width
|
76
|
+
assert_equal(['a', 'b'], Defcli::Formatting.fit('a b', 2))
|
77
|
+
end
|
78
|
+
|
79
|
+
# == Defcli::Formatting.tab == #
|
80
|
+
|
81
|
+
def test_tab_0_width
|
82
|
+
assert_equal('foo', Defcli::Formatting.tab('foo', 0))
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_tab_negative_width
|
86
|
+
assert_equal('foo', Defcli::Formatting.tab('foo', -1))
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_tab_2_width
|
90
|
+
assert_equal(' foo', Defcli::Formatting.tab('foo', 2))
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_tab_array
|
94
|
+
assert_equal([' a', ' b'], Defcli::Formatting.tab(['a', 'b'], 1))
|
95
|
+
end
|
96
|
+
end
|
data/tests/tests.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
ci = ENV["CI"] || ENV["CONTINUOUS_INTEGRATION"]
|
4
|
+
|
5
|
+
if ci
|
6
|
+
require 'coveralls'
|
7
|
+
Coveralls.wear!
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require 'simplecov'
|
12
|
+
|
13
|
+
test_dir = File.expand_path( File.dirname(__FILE__) )
|
14
|
+
|
15
|
+
SimpleCov.formatter = Coveralls::SimpleCov::Formatter if ci
|
16
|
+
SimpleCov.start { add_filter '/tests/' }
|
17
|
+
|
18
|
+
require 'defcli'
|
19
|
+
|
20
|
+
for t in Dir.glob( File.join( test_dir, '*_tests.rb' ) )
|
21
|
+
require t
|
22
|
+
end
|
23
|
+
|
24
|
+
class DefcliTests < Test::Unit::TestCase
|
25
|
+
|
26
|
+
# == Defcli.version == #
|
27
|
+
|
28
|
+
def test_version
|
29
|
+
assert(Defcli.version =~ /^\d+\.\d+\.\d+/)
|
30
|
+
end
|
31
|
+
|
32
|
+
# == Defcli.open_cmd (private) == #
|
33
|
+
|
34
|
+
def test_open_cmd
|
35
|
+
os = RbConfig::CONFIG["host_os"]
|
36
|
+
|
37
|
+
RbConfig::CONFIG["host_os"] = "darwin"
|
38
|
+
assert_equal "open", Defcli.send(:open_cmd)
|
39
|
+
|
40
|
+
RbConfig::CONFIG["host_os"] = "linux"
|
41
|
+
assert_equal "xdg-open", Defcli.send(:open_cmd)
|
42
|
+
|
43
|
+
RbConfig::CONFIG["host_os"] = "bsd"
|
44
|
+
assert_equal "xdg-open", Defcli.send(:open_cmd)
|
45
|
+
|
46
|
+
RbConfig::CONFIG["host_os"] = "cygwin"
|
47
|
+
assert_equal "start", Defcli.send(:open_cmd)
|
48
|
+
ensure
|
49
|
+
RbConfig::CONFIG["host_os"] = os
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
exit Test::Unit::AutoRunner.run
|
metadata
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: defcli
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Baptiste Fontaine
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIID/DCCAmSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAkMSIwIAYDVQQDDBliL0RD
|
14
|
+
PXB0aXN0ZWZvbnRhaW5lL0RDPWZyMB4XDTIwMDMwNDE5MDMyMVoXDTIxMDMwNDE5
|
15
|
+
MDMyMVowJDEiMCAGA1UEAwwZYi9EQz1wdGlzdGVmb250YWluZS9EQz1mcjCCAaIw
|
16
|
+
DQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKdjTwN/gnJ3WHxKeusaRN1o902Q
|
17
|
+
BmIRgdtbhpsHtgUruKNujutEBpmhG1fka8+mujhqh885blckeC8hXgqpHGK1MsJU
|
18
|
+
tgsNB2F2Nvof/uGBzi+OZ76HPLmfvJFb/KUiwrh08jTbFftMBCmuekbxBajt2N2F
|
19
|
+
shF6DFEqO2hl/itVt5UeIZhpIZvO7qSZ9FtLRXs0q2O27h4QfAv6XobNDwH5TBs5
|
20
|
+
z+EYufgTtupf26xW0v6z2NDG6z36Eap7QAwoivuPCuXO+IPgxhubtGvFYSo7ygP4
|
21
|
+
RbYsaGucRneCCzezTD+i1LnhGt9TCbQjdvidgM+i616JC/HRXglM0apgBZSjayoI
|
22
|
+
XHoajIajnU+570cu01Wsa+SF9m4stKao0hLnCUMeYybmA/Ilk58nJ2xZJWMULu76
|
23
|
+
7Ttzead1Ah25ZdWefKG5FIGkpezEp4z/YihGEJt+hxS7Aa2xYiIlnYFwUno530/8
|
24
|
+
So5Ibqdd3pMKJDUQJvGIBhsQIXF4Iogk4txoPwIDAQABozkwNzAJBgNVHRMEAjAA
|
25
|
+
MAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUsV1eKnEFtVRwyz6/nTuharH3G+UwDQYJ
|
26
|
+
KoZIhvcNAQELBQADggGBAJz7tbRe/iyMthV7fdqnhFv0SZo1UVWZSaIjB39W4lUi
|
27
|
+
7X1Smag2Fe7IqARUPLn2e49ObyupAmTi0zHoSG/+HsBUqNPPoVW1Y67dtrMM49o7
|
28
|
+
qSN66EogB4nvGdvqJ9eOlioiAX7vczWmQjfSONuk0ihOfaTChD7LwoPptTUu/Q6+
|
29
|
+
aT8zz7TH+sxxx+D09Q9+Ywf1RVnUe+i1PTo8kadnHIQdeBPudKrw5GWcIoLz1V16
|
30
|
+
A+j/SNEUqY1ui8TBX6axkd8vh6C1YcVAFCcdrxTMFTeB1irvL8jns6SulRHM08UC
|
31
|
+
9NR+YthP16QuQzb5R2wIGX6WT11cnIpo0LzTnY/QSZGgwJkuLalBLzUssMiVnoSX
|
32
|
+
rVdmQBLrs38YcJouqHpf0wCGygf5430Bq4nCu0xUaH5umPcwJE9qaF1ZfgSCfZEz
|
33
|
+
Qe5fflfwGHtlmT6SWZoQD48xF/ILJ+cLTpF79ardGYnWT6N7VUAI5lKp7OjZYd+q
|
34
|
+
wwYlmlBW0Femxy5WoxzECQ==
|
35
|
+
-----END CERTIFICATE-----
|
36
|
+
date: 2020-04-02 00:00:00.000000000 Z
|
37
|
+
dependencies:
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: optimist
|
40
|
+
requirement: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - "~>"
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '3.0'
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - "~>"
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '3.0'
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: colored
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - "~>"
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '1.2'
|
59
|
+
type: :runtime
|
60
|
+
prerelease: false
|
61
|
+
version_requirements: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - "~>"
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '1.2'
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
name: simplecov
|
68
|
+
requirement: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - "~>"
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0.18'
|
73
|
+
type: :development
|
74
|
+
prerelease: false
|
75
|
+
version_requirements: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0.18'
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: rake
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - "~>"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '12.3'
|
87
|
+
type: :development
|
88
|
+
prerelease: false
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - "~>"
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '12.3'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: test-unit
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - "~>"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '3.3'
|
101
|
+
type: :development
|
102
|
+
prerelease: false
|
103
|
+
version_requirements: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - "~>"
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '3.3'
|
108
|
+
- !ruby/object:Gem::Dependency
|
109
|
+
name: coveralls
|
110
|
+
requirement: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - "~>"
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0.8'
|
115
|
+
type: :development
|
116
|
+
prerelease: false
|
117
|
+
version_requirements: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - "~>"
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0.8'
|
122
|
+
description: Utilities to build simple dictionnary CLI tools.
|
123
|
+
email: b@ptistefontaine.fr
|
124
|
+
executables: []
|
125
|
+
extensions: []
|
126
|
+
extra_rdoc_files: []
|
127
|
+
files:
|
128
|
+
- lib/defcli.rb
|
129
|
+
- lib/defcli/formatting.rb
|
130
|
+
- tests/formatting_tests.rb
|
131
|
+
- tests/tests.rb
|
132
|
+
homepage: https://github.com/bfontaine/defcli
|
133
|
+
licenses:
|
134
|
+
- MIT
|
135
|
+
metadata: {}
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
requirements: []
|
151
|
+
rubygems_version: 3.1.2
|
152
|
+
signing_key:
|
153
|
+
specification_version: 4
|
154
|
+
summary: Dictionnary CLI tools utilities
|
155
|
+
test_files:
|
156
|
+
- tests/tests.rb
|
157
|
+
- tests/formatting_tests.rb
|
metadata.gz.sig
ADDED
@@ -0,0 +1,2 @@
|
|
1
|
+
H�y�����}^G|��>��ސ�J����>����k.^["O��*�O�-!��<�|�!HH?X�ȟ���,��I�V�Y����W�����mvq�4<<b���� ��y�D��W�#幗E-z��o�k�T���Pn�^�h�jHE�Zs5e������rъ��G8�P��V�֠dŢِ����!r�wF�%���2���5mƔv�{�\����]�8BNQ���V��{��������0W �d�YL��Id��Oo�E=�aC�}Cu���<��ъy
|
2
|
+
e���F� �u��x�u흝�8�9{�T��d�J�e�q�v��5 ����mM��'�C����a���9����20n=�}��|�L�I(<1�����k
|