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 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