twigg 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/twigg/cacher.rb +3 -3
- data/lib/twigg/command/help.rb +30 -29
- data/lib/twigg/command/stats.rb +1 -1
- data/lib/twigg/command.rb +9 -2
- data/lib/twigg/commit_set.rb +1 -0
- data/lib/twigg/commit_set_decorator.rb +31 -0
- data/lib/twigg/console.rb +4 -3
- data/lib/twigg/decoratable.rb +17 -0
- data/lib/twigg/decorator.rb +11 -0
- data/lib/twigg/repo.rb +3 -2
- data/lib/twigg/settings.rb +8 -0
- data/lib/twigg/util.rb +14 -24
- data/lib/twigg/version.rb +1 -1
- data/lib/twigg.rb +20 -17
- data/templates/twiggrc.yml +5 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 282331adcc35a06bb23a3691d527af21569d18f4
|
4
|
+
data.tar.gz: 786b7007f4e5a6391eb8bb16b3bc28f9a7a03ff4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 994087ede63df1cff19699ea8da0690ef4ad5f7fc7f939cf022a31ab5673cba565db42904483a68594e03bd8585adf8c518fba8e4c8573c7735a5128dc092f59
|
7
|
+
data.tar.gz: d79c58a57e7dcad78881604de48505e144423096434c714bfcb626418b07fd5c3cbd5a7991ba05983335ee2b59408b70514a6690ba623f331b1a347e41872839
|
data/lib/twigg/cacher.rb
CHANGED
@@ -24,7 +24,7 @@ module Twigg
|
|
24
24
|
#
|
25
25
|
# Note: if a `nil` or `false` value is ever stored in the cache, this
|
26
26
|
# method will consider any lookup of the corresponding key to be a miss,
|
27
|
-
# because we employ a
|
27
|
+
# because we employ a simple truthiness check to determine presence.
|
28
28
|
def get(key, *args, &block)
|
29
29
|
raise ArgumentError, 'block required by not given' unless block_given?
|
30
30
|
digest = hashed_key_and_args(key, *args)
|
@@ -60,7 +60,7 @@ module Twigg
|
|
60
60
|
# recursion to incorporate the contents of those objects in the digest.
|
61
61
|
#
|
62
62
|
# Will raise an exception if `args` or any object encontered via recursion
|
63
|
-
# is not a "simple" object (Hash, Array, String,
|
63
|
+
# is not a "simple" object (Hash, Array, String, NilClass, Numeric, or
|
64
64
|
# Symbol).
|
65
65
|
def hashed_key_and_args(key, *args)
|
66
66
|
base = args.inject('') do |memo, arg|
|
@@ -69,7 +69,7 @@ module Twigg
|
|
69
69
|
hashed_key_and_args(key, *arg)
|
70
70
|
when Hash
|
71
71
|
hashed_key_and_args(key, *arg.to_a)
|
72
|
-
when NilClass,Numeric, String, Symbol
|
72
|
+
when NilClass, Numeric, String, Symbol
|
73
73
|
arg.to_s
|
74
74
|
else
|
75
75
|
raise ArgumentError, 'can only compute digest for primitive objects'
|
data/lib/twigg/command/help.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'shellwords'
|
2
|
-
|
3
1
|
module Twigg
|
4
2
|
class Command
|
5
3
|
class Help < Command
|
@@ -22,10 +20,6 @@ module Twigg
|
|
22
20
|
|
23
21
|
private
|
24
22
|
|
25
|
-
def executable
|
26
|
-
Shellwords.escape($0)
|
27
|
-
end
|
28
|
-
|
29
23
|
TOPIC_HEADERS = Hash.new { |h, k| h[k] = k.capitalize }.merge(
|
30
24
|
# header = subcommand with first letter capitalized; exceptions:
|
31
25
|
'app' => 'Web application',
|
@@ -34,78 +28,85 @@ module Twigg
|
|
34
28
|
|
35
29
|
def show_help(topic)
|
36
30
|
puts TOPIC_HEADERS[topic] + ':'
|
37
|
-
stderr strip_heredoc(send(topic)) + "\n"
|
31
|
+
stderr strip_heredoc(send(topic), indent: 2) + "\n"
|
38
32
|
end
|
39
33
|
|
40
34
|
def app
|
41
35
|
<<-DOC
|
42
|
-
|
36
|
+
twigg app [-D|--daemon] [-P|--pidfile <pidfile>]
|
43
37
|
DOC
|
44
38
|
end
|
45
39
|
|
46
40
|
def commands
|
47
41
|
<<-DOC
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
42
|
+
twigg app # run the Twigg web app
|
43
|
+
twigg gerrit # clone/update/report from Gerrit
|
44
|
+
twigg git # perform operations on Git repos
|
45
|
+
twigg github # clone/update from GitHub
|
46
|
+
twigg init # generate a .twiggrc file
|
47
|
+
twigg help # this help information
|
48
|
+
twigg pivotal # show open stories in Pivotal Tracker
|
49
|
+
twigg stats # show statistics about repos
|
55
50
|
DOC
|
56
51
|
end
|
57
52
|
|
58
53
|
def gerrit
|
59
54
|
<<-DOC
|
60
|
-
|
61
|
-
|
62
|
-
|
55
|
+
twigg gerrit clone [repos dir] # clone repos into repos dir
|
56
|
+
twigg gerrit update [repos dir] # update repos in repos dir
|
57
|
+
twigg gerrit stats [repos dir] # show stats for repos in dir
|
63
58
|
DOC
|
64
59
|
end
|
65
60
|
|
66
61
|
def git
|
67
62
|
<<-DOC
|
68
|
-
|
63
|
+
twigg git gc [repos dir] # garbage collect repos in repos dir
|
69
64
|
DOC
|
70
65
|
end
|
71
66
|
|
72
67
|
def github
|
73
68
|
<<-DOC
|
74
|
-
|
75
|
-
|
69
|
+
twigg github clone [repos dir] # clone repos into repos dir
|
70
|
+
twigg github update [repos dir] # update repos in repos dir
|
76
71
|
DOC
|
77
72
|
end
|
78
73
|
|
79
74
|
def help
|
80
75
|
<<-DOC
|
81
|
-
|
82
|
-
|
83
|
-
|
76
|
+
twigg help # this help information
|
77
|
+
twigg help <subcommand> # help for a specific subcommand
|
78
|
+
twigg help commands # list all subcommands
|
84
79
|
DOC
|
85
80
|
end
|
86
81
|
|
87
82
|
def init
|
88
83
|
<<-DOC
|
89
|
-
|
84
|
+
twigg init # emit a sample .twiggrc file to standard out
|
85
|
+
DOC
|
86
|
+
end
|
87
|
+
|
88
|
+
def pivotal
|
89
|
+
<<-DOC
|
90
|
+
twigg pivotal stats # show overview of open stories
|
90
91
|
DOC
|
91
92
|
end
|
92
93
|
|
93
94
|
def russian
|
94
95
|
<<-DOC
|
95
|
-
|
96
|
+
twigg russian <repos dir> <number of days> # easter egg
|
96
97
|
DOC
|
97
98
|
end
|
98
99
|
|
99
100
|
def stats
|
100
101
|
<<-DOC
|
101
|
-
|
102
|
+
twigg stats [--verbose|-v] <repos dir> <number of days>
|
102
103
|
DOC
|
103
104
|
end
|
104
105
|
|
105
106
|
def usage
|
106
107
|
<<-DOC
|
107
|
-
|
108
|
-
|
108
|
+
twigg <subcommand> [options] <arguments...>
|
109
|
+
twigg help
|
109
110
|
DOC
|
110
111
|
end
|
111
112
|
end
|
data/lib/twigg/command/stats.rb
CHANGED
data/lib/twigg/command.rb
CHANGED
@@ -3,7 +3,7 @@ require 'forwardable'
|
|
3
3
|
module Twigg
|
4
4
|
class Command
|
5
5
|
# Subcommands, in the order they should appear in the help output.
|
6
|
-
PUBLIC_SUBCOMMANDS = %w[help init app stats gerrit github git]
|
6
|
+
PUBLIC_SUBCOMMANDS = %w[help init app stats gerrit github pivotal git]
|
7
7
|
|
8
8
|
EASTER_EGGS = %w[russian]
|
9
9
|
SUBCOMMANDS = PUBLIC_SUBCOMMANDS + EASTER_EGGS
|
@@ -44,7 +44,10 @@ module Twigg
|
|
44
44
|
private
|
45
45
|
|
46
46
|
def ignore(args)
|
47
|
-
|
47
|
+
if args.any?
|
48
|
+
warn "unsupported extra argument#{'s' if args.size > 1} " \
|
49
|
+
"#{args.inspect} ignored"
|
50
|
+
end
|
48
51
|
end
|
49
52
|
|
50
53
|
def app(*args)
|
@@ -71,6 +74,10 @@ module Twigg
|
|
71
74
|
Init.new(*args).run
|
72
75
|
end
|
73
76
|
|
77
|
+
def pivotal(*args)
|
78
|
+
with_dependency('twigg-pivotal') { Pivotal.new(*args).run }
|
79
|
+
end
|
80
|
+
|
74
81
|
def russian(*args)
|
75
82
|
Russian.new(*args).run
|
76
83
|
end
|
data/lib/twigg/commit_set.rb
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Twigg
|
2
|
+
class CommitSetDecorator < Decorator
|
3
|
+
include Util # for `number_with_delimiter`
|
4
|
+
|
5
|
+
# Returns a per-repo breakdown (repo names, commit counts) of commits in
|
6
|
+
# the decorated {CommitSet}.
|
7
|
+
#
|
8
|
+
# Returns HTML output by default, or plain-text when `html` is `false`.
|
9
|
+
def breakdown(html: true)
|
10
|
+
commit_set.count_by_repo.map do |data|
|
11
|
+
if html && (link = data[:repo].link)
|
12
|
+
name = %{<a href="#{link}">#{data[:repo].name}</a>}
|
13
|
+
else
|
14
|
+
name = data[:repo].name
|
15
|
+
end
|
16
|
+
|
17
|
+
if html
|
18
|
+
"<i>#{name}:</i> <b>#{number_with_delimiter data[:count]}</b>"
|
19
|
+
else
|
20
|
+
"#{name}: #{number_with_delimiter data[:count]}"
|
21
|
+
end
|
22
|
+
end.join(', ')
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def commit_set
|
28
|
+
@decorated
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/twigg/console.rb
CHANGED
@@ -31,13 +31,14 @@ module Twigg
|
|
31
31
|
|
32
32
|
# Given a "heredoc" `doc`, find the non-empty line with the smallest indent,
|
33
33
|
# and strip that amount of whitespace from the beginning of each line.
|
34
|
+
# Subsequently, prepend a fixed number (`indent`) of spaces to each line.
|
34
35
|
#
|
35
36
|
# This allows us to write nicely indented copy that sits well with the
|
36
37
|
# surrounding code, irrespective of the level of indentation of the code,
|
37
38
|
# without emitting excessive whitespace to the user at runtime.
|
38
|
-
def strip_heredoc(doc)
|
39
|
-
|
40
|
-
doc.gsub(/^[ \t]{#{
|
39
|
+
def strip_heredoc(doc, indent: 0)
|
40
|
+
strip_count = doc.scan(/^[ \t]*(?=\S)/).map(&:size).min || 0
|
41
|
+
doc.gsub(/^[ \t]{#{strip_count}}/, ' ' * indent)
|
41
42
|
end
|
42
43
|
|
43
44
|
# Given `switches` (which may be either a single switch or an array of
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Twigg
|
2
|
+
module Decoratable
|
3
|
+
def decorate
|
4
|
+
klass = self.class.instance_variable_get('@decorator_class')
|
5
|
+
|
6
|
+
if !klass
|
7
|
+
components = (self.class.name + 'Decorator').split('::')
|
8
|
+
klass = components.inject(Object) do |namespace, klass|
|
9
|
+
namespace.const_get(klass)
|
10
|
+
end
|
11
|
+
self.class.instance_variable_set('@decorator_class', klass)
|
12
|
+
end
|
13
|
+
|
14
|
+
klass.new(self)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/twigg/repo.rb
CHANGED
@@ -75,7 +75,7 @@ module Twigg
|
|
75
75
|
IO.popen([{ 'GIT_DIR' => git_dir },
|
76
76
|
'git', command, *args, *STDERR_TO_STDOUT], 'r') do |io|
|
77
77
|
io.read
|
78
|
-
end
|
78
|
+
end.force_encoding('UTF-8')
|
79
79
|
end
|
80
80
|
|
81
81
|
def log(*args)
|
@@ -91,7 +91,8 @@ module Twigg
|
|
91
91
|
'%w(0,4,4)%b', # body, indented 4 spaces
|
92
92
|
].join
|
93
93
|
|
94
|
-
git 'log',
|
94
|
+
git 'log',
|
95
|
+
'--encoding=UTF-8', "--pretty=format:#{format}", '--numstat', *args
|
95
96
|
end
|
96
97
|
|
97
98
|
def parse_log(string)
|
data/lib/twigg/settings.rb
CHANGED
@@ -28,6 +28,10 @@ module Twigg
|
|
28
28
|
namespace :gerrit do
|
29
29
|
setting :enabled, default: false
|
30
30
|
end
|
31
|
+
|
32
|
+
namespace :pivotal do
|
33
|
+
setting :enabled, default: false
|
34
|
+
end
|
31
35
|
end
|
32
36
|
|
33
37
|
namespace :cache do
|
@@ -64,6 +68,10 @@ module Twigg
|
|
64
68
|
setting :token, required: true
|
65
69
|
end
|
66
70
|
|
71
|
+
namespace :pivotal do
|
72
|
+
setting :token, required: true
|
73
|
+
end
|
74
|
+
|
67
75
|
setting :repositories_directory, required: true do |name, value|
|
68
76
|
raise ArgumentError, "#{name} not a directory" unless File.directory?(value)
|
69
77
|
end
|
data/lib/twigg/util.rb
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
module Twigg
|
2
2
|
module Util
|
3
|
+
class << self
|
4
|
+
def inflections
|
5
|
+
@inflections ||= {}
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
3
9
|
private
|
4
10
|
|
5
11
|
# Returns the age of `time` relative to now in hours (for short intervals)
|
@@ -37,32 +43,16 @@ module Twigg
|
|
37
43
|
# pluralize(1_200, 'commit', delimit: false) # => "1200 commits"
|
38
44
|
#
|
39
45
|
def pluralize(count, singular, plural = nil, delimit: true)
|
40
|
-
|
41
|
-
|
42
|
-
end
|
46
|
+
inflections = ::Twigg::Util.inflections
|
47
|
+
number = delimit ? number_with_delimiter(count) : count.to_s
|
43
48
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
# `commit_set`.
|
50
|
-
#
|
51
|
-
# Returns HTML output by default, or plain-text when `html` is `false`.
|
52
|
-
def breakdown(commit_set, html: true)
|
53
|
-
commit_set.count_by_repo.map do |data|
|
54
|
-
if html && (link = data[:repo].link)
|
55
|
-
name = %{<a href="#{link}">#{data[:repo].name}</a>}
|
56
|
-
else
|
57
|
-
name = data[:repo].name
|
58
|
-
end
|
49
|
+
if plural
|
50
|
+
inflections[singular] ||= plural
|
51
|
+
else
|
52
|
+
plural = inflections[singular] || (singular + 's')
|
53
|
+
end
|
59
54
|
|
60
|
-
|
61
|
-
"<i>#{name}:</i> <b>#{number_with_delimiter data[:count]}</b>"
|
62
|
-
else
|
63
|
-
"#{name}: #{number_with_delimiter data[:count]}"
|
64
|
-
end
|
65
|
-
end.join(', ')
|
55
|
+
"#{number} #{count == 1 ? singular : plural}"
|
66
56
|
end
|
67
57
|
end
|
68
58
|
end
|
data/lib/twigg/version.rb
CHANGED
data/lib/twigg.rb
CHANGED
@@ -1,23 +1,26 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
|
3
3
|
module Twigg
|
4
|
-
autoload :Cacher,
|
5
|
-
autoload :Command,
|
6
|
-
autoload :Commit,
|
7
|
-
autoload :CommitSet,
|
8
|
-
autoload :
|
9
|
-
autoload :
|
10
|
-
autoload :
|
11
|
-
autoload :
|
12
|
-
autoload :
|
13
|
-
autoload :
|
14
|
-
autoload :
|
15
|
-
autoload :
|
16
|
-
autoload :
|
17
|
-
autoload :
|
18
|
-
autoload :
|
19
|
-
autoload :
|
20
|
-
autoload :
|
4
|
+
autoload :Cacher, 'twigg/cacher'
|
5
|
+
autoload :Command, 'twigg/command'
|
6
|
+
autoload :Commit, 'twigg/commit'
|
7
|
+
autoload :CommitSet, 'twigg/commit_set'
|
8
|
+
autoload :CommitSetDecorator, 'twigg/commit_set_decorator'
|
9
|
+
autoload :Config, 'twigg/config'
|
10
|
+
autoload :Console, 'twigg/console'
|
11
|
+
autoload :Dependency, 'twigg/dependency'
|
12
|
+
autoload :Decorator, 'twigg/decorator'
|
13
|
+
autoload :Decoratable, 'twigg/decoratable'
|
14
|
+
autoload :Flesch, 'twigg/flesch'
|
15
|
+
autoload :Gatherer, 'twigg/gatherer'
|
16
|
+
autoload :PairMatrix, 'twigg/pair_matrix'
|
17
|
+
autoload :Repo, 'twigg/repo'
|
18
|
+
autoload :RepoSet, 'twigg/repo_set'
|
19
|
+
autoload :RussianNovel, 'twigg/russian_novel'
|
20
|
+
autoload :Settings, 'twigg/settings'
|
21
|
+
autoload :Team, 'twigg/team'
|
22
|
+
autoload :Util, 'twigg/util'
|
23
|
+
autoload :VERSION, 'twigg/version'
|
21
24
|
|
22
25
|
# Returns a Pathname instance corresponding to the root directory of the gem
|
23
26
|
# (ie. the directory containing the `files` and `templates` directories).
|
data/templates/twiggrc.yml
CHANGED
@@ -13,6 +13,8 @@ app:
|
|
13
13
|
bind: '0.0.0.0' # default
|
14
14
|
gerrit:
|
15
15
|
enabled: false # default
|
16
|
+
pivotal:
|
17
|
+
enabled: false # default
|
16
18
|
|
17
19
|
cache:
|
18
20
|
enabled: false # default
|
@@ -40,6 +42,9 @@ github:
|
|
40
42
|
organization: causes
|
41
43
|
token: 0da57c4304855867e97dd4419d7d070543c5c092
|
42
44
|
|
45
|
+
pivotal:
|
46
|
+
token: dcc9b8d1445dc21d02f1cbea1edd8aa56ffd6af2
|
47
|
+
|
43
48
|
teams:
|
44
49
|
Red Team:
|
45
50
|
- John Smith
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twigg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Causes Engineering
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -101,8 +101,11 @@ files:
|
|
101
101
|
- lib/twigg/command.rb
|
102
102
|
- lib/twigg/commit.rb
|
103
103
|
- lib/twigg/commit_set.rb
|
104
|
+
- lib/twigg/commit_set_decorator.rb
|
104
105
|
- lib/twigg/config.rb
|
105
106
|
- lib/twigg/console.rb
|
107
|
+
- lib/twigg/decoratable.rb
|
108
|
+
- lib/twigg/decorator.rb
|
106
109
|
- lib/twigg/dependency.rb
|
107
110
|
- lib/twigg/flesch.rb
|
108
111
|
- lib/twigg/gatherer.rb
|