twigg 0.0.3 → 0.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d4acbfc3dab81cc46307e04748ccc89ade34cac2
4
- data.tar.gz: 13e6267f6bd29a0f84ddbcf7fd7110a7fd1806bd
3
+ metadata.gz: 282331adcc35a06bb23a3691d527af21569d18f4
4
+ data.tar.gz: 786b7007f4e5a6391eb8bb16b3bc28f9a7a03ff4
5
5
  SHA512:
6
- metadata.gz: 37d68f4ad72e96ae993e614e362ac5a5d2fd323d68724558970687ba3bab3a0d5b330d0b707744c98d99ae32ad967cfebdcf9d965510a66ae3ce638c69a23ba9
7
- data.tar.gz: b912766a33db3431a3a07d479b1cf831f01ba461555ba36a2956bc236d7f55aa9a997284b9b4f1312bc41961f19cc9076a211ad9c119151a6cf655c212058be6
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 simply truthiness check to determine presence.
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, NilClas, Numeric, or
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'
@@ -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
- #{executable} app [-D|--daemon] [-P|--pidfile <pidfile>]
36
+ twigg app [-D|--daemon] [-P|--pidfile <pidfile>]
43
37
  DOC
44
38
  end
45
39
 
46
40
  def commands
47
41
  <<-DOC
48
- #{executable} app # run the Twigg web app
49
- #{executable} gerrit # clone/update/report from Gerrit
50
- #{executable} git # perform operations on Git repos
51
- #{executable} github # clone/update from GitHub
52
- #{executable} init # generate a .twiggrc file
53
- #{executable} help # this help information
54
- #{executable} stats # show statistics about repos
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
- #{executable} gerrit clone [repos dir] # clone repos into repos dir
61
- #{executable} gerrit update [repos dir] # update repos in repos dir
62
- #{executable} gerrit stats [repos dir] # show stats for repos in dir
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
- #{executable} git gc [repos dir] # garbage collect repos in repos dir
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
- #{executable} github clone [repos dir] # clone repos into repos dir
75
- #{executable} github update [repos dir] # update repos in repos dir
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
- #{executable} help # this help information
82
- #{executable} help <subcommand> # help for a specific subcommand
83
- #{executable} help commands # list all subcommands
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
- #{executable} init # emit a sample .twiggrc file to standard out
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
- #{executable} russian <repos dir> <number of days> # easter egg
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
- #{executable} stats [--verbose|-v] <repos dir> <number of days>
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
- #{executable} <subcommand> [options] <arguments...>
108
- #{executable} help
108
+ twigg <subcommand> [options] <arguments...>
109
+ twigg help
109
110
  DOC
110
111
  end
111
112
  end
@@ -21,7 +21,7 @@ module Twigg
21
21
  puts '%5s %-24s %s' % [
22
22
  number_with_delimiter(commit_set.count),
23
23
  author,
24
- breakdown(commit_set, html: false),
24
+ commit_set.decorate.breakdown(html: false),
25
25
  ]
26
26
 
27
27
  if @verbose
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
- warn "unsupported extra arguments #{args.inspect} ignored" if args.any?
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
@@ -3,6 +3,7 @@ require 'set'
3
3
 
4
4
  module Twigg
5
5
  class CommitSet
6
+ include Decoratable
6
7
  extend Forwardable
7
8
  def_delegators :commits, :any?, :count, :each, :inject, :<<
8
9
  attr_reader :commits
@@ -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
- indent = doc.scan(/^[ \t]*(?=\S)/).map(&:size).min || 0
40
- doc.gsub(/^[ \t]{#{indent}}/, '')
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
@@ -0,0 +1,11 @@
1
+ module Twigg
2
+ class Decorator < BasicObject
3
+ def initialize(decorated)
4
+ @decorated = decorated
5
+ end
6
+
7
+ def method_missing(method, *args, &block)
8
+ @decorated.send(method, *args, &block)
9
+ end
10
+ end
11
+ 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', "--pretty=format:#{format}", '--numstat', *args
94
+ git 'log',
95
+ '--encoding=UTF-8', "--pretty=format:#{format}", '--numstat', *args
95
96
  end
96
97
 
97
98
  def parse_log(string)
@@ -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
- @inflections ||= Hash.new do |hash, key|
41
- hash[key] = [key, plural ? plural : key + 's']
42
- end
46
+ inflections = ::Twigg::Util.inflections
47
+ number = delimit ? number_with_delimiter(count) : count.to_s
43
48
 
44
- (delimit ? number_with_delimiter(count) : count.to_s) + ' ' +
45
- @inflections[singular][count == 1 ? 0 : 1]
46
- end
47
-
48
- # Returns a per-repo breakdown (repo names, commit counts) of commits in
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
- if html
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
@@ -1,3 +1,3 @@
1
1
  module Twigg
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.4'
3
3
  end
data/lib/twigg.rb CHANGED
@@ -1,23 +1,26 @@
1
1
  require 'pathname'
2
2
 
3
3
  module Twigg
4
- autoload :Cacher, 'twigg/cacher'
5
- autoload :Command, 'twigg/command'
6
- autoload :Commit, 'twigg/commit'
7
- autoload :CommitSet, 'twigg/commit_set'
8
- autoload :Config, 'twigg/config'
9
- autoload :Console, 'twigg/console'
10
- autoload :Dependency, 'twigg/dependency'
11
- autoload :Flesch, 'twigg/flesch'
12
- autoload :Gatherer, 'twigg/gatherer'
13
- autoload :PairMatrix, 'twigg/pair_matrix'
14
- autoload :Repo, 'twigg/repo'
15
- autoload :RepoSet, 'twigg/repo_set'
16
- autoload :RussianNovel, 'twigg/russian_novel'
17
- autoload :Settings, 'twigg/settings'
18
- autoload :Team, 'twigg/team'
19
- autoload :Util, 'twigg/util'
20
- autoload :VERSION, 'twigg/version'
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).
@@ -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.3
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-08-28 00:00:00.000000000 Z
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