plus2_git_tagger 0.0.6
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.
- data/.gitignore +6 -0
- data/Gemfile +4 -0
- data/Rakefile +11 -0
- data/lib/plus2_git_tagger.rb +7 -0
- data/lib/plus2_git_tagger/git.rb +58 -0
- data/lib/plus2_git_tagger/tags.rb +141 -0
- data/lib/plus2_git_tagger/task.rb +124 -0
- data/lib/plus2_git_tagger/version.rb +3 -0
- data/plus2_git_tagger.gemspec +20 -0
- metadata +76 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
|
3
|
+
module Bundler
|
4
|
+
class GemHelper
|
5
|
+
def rubygem_push(path)
|
6
|
+
out, _ = sh("gem inabox '#{path}'")
|
7
|
+
raise "Gem push failed due to lack of RubyGems.org credentials." if out[/Enter your RubyGems.org credentials/]
|
8
|
+
Bundler.ui.confirm "Pushed #{name} #{version} to local gems"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Plus2GitTagger
|
2
|
+
class Git < Struct.new( :repo )
|
3
|
+
def initialize(*)
|
4
|
+
super
|
5
|
+
self.repo = Pathname( repo ).expand_path
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
# Queries git for HEAD's subject.
|
10
|
+
#
|
11
|
+
# Returns a string containing HEAD's subject.
|
12
|
+
def current_subject
|
13
|
+
git_s('log --pretty="format:%s" -1').chomp
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
# Naive: remove quotes.
|
18
|
+
def escaped_current_subject
|
19
|
+
current_subject.gsub(/["']/, '')
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
# Try to commit, but don't worry if it doesn't work because it wasn't needed.
|
24
|
+
def commit_if_required(subject)
|
25
|
+
result = git_s("commit -uno -m '#{ subject }' 2>&1")
|
26
|
+
|
27
|
+
unless $?.success? || result[/nothing to commit/i] || result[/no changes added to commit/i]
|
28
|
+
abort result
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
# Returns a list of all tags for this repo.
|
34
|
+
def tags
|
35
|
+
git_s('show-ref --tags --abbrev=1').split("\n").map {|line| line.split(/\s/).last.chomp.sub(%r[^refs/tags/],'')}
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# Run git.
|
40
|
+
def git( cmd )
|
41
|
+
Dir.chdir( repo ) do
|
42
|
+
system "git #{cmd}"
|
43
|
+
|
44
|
+
abort("'git #{cmd}' failed") unless $?.success?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
alias_method :run, :git
|
48
|
+
|
49
|
+
|
50
|
+
# Run git, capture stdout.
|
51
|
+
def git_s( cmd )
|
52
|
+
Dir.chdir( repo ) do
|
53
|
+
`git #{cmd}`
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module Plus2GitTagger
|
2
|
+
class Tags < Struct.new( :git_helper, :tag_prefix )
|
3
|
+
|
4
|
+
|
5
|
+
def make!
|
6
|
+
if last_tag = todays_tags.sort.last
|
7
|
+
tag = next_tag(last_tag)
|
8
|
+
else
|
9
|
+
tag = base_tag
|
10
|
+
end
|
11
|
+
|
12
|
+
luser = git_s("config user.name").chomp
|
13
|
+
|
14
|
+
git "tag -m'auto-tagged by #{luser}' #{tag}"
|
15
|
+
|
16
|
+
|
17
|
+
banner "Behold a tag! #{ tag }"
|
18
|
+
|
19
|
+
git "push origin --tags"
|
20
|
+
|
21
|
+
banner "Your tag has been pushed automatically.", "Please don't forget to push your current branch too!"
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def banner(*msgs)
|
26
|
+
width = msgs.map {|m| m.size}.max
|
27
|
+
|
28
|
+
banner = "*" * (width + 6)
|
29
|
+
|
30
|
+
puts
|
31
|
+
puts banner
|
32
|
+
|
33
|
+
msgs.each do |m|
|
34
|
+
print "* #{m}"
|
35
|
+
print " " * (width - m.size + 2)
|
36
|
+
puts "*"
|
37
|
+
end
|
38
|
+
|
39
|
+
puts banner
|
40
|
+
puts
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
# Given a tag, using all the rules, find the next tag.
|
45
|
+
def next_tag(tag)
|
46
|
+
last_index = extensions.index( tag_ext(tag) ) || -1
|
47
|
+
next_ext = extensions[last_index+1]
|
48
|
+
|
49
|
+
"#{base_tag}-#{next_ext}"
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
# Returns a regex which matches tags in the required format, and starting with `tag_prefix`.
|
56
|
+
def tag_regex
|
57
|
+
@tag_regex ||= %r{^#{ Regexp.quote tag_prefix }-\d{4}-\d{2}-\d{2}}
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
# Returns tags matching `tag_regex` for this repo.
|
62
|
+
def tags_with_pattern
|
63
|
+
git_helper.tags.grep(tag_regex)
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
# Lists all tags matching the patten
|
68
|
+
def list
|
69
|
+
tags_with_pattern.sort.each do |tag|
|
70
|
+
puts tag
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
# List all tags made this month
|
76
|
+
def month_list
|
77
|
+
this_months_tags.sort.each do |tag|
|
78
|
+
puts tag
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
# Returns the base tag for today's date.
|
84
|
+
#
|
85
|
+
# Example:
|
86
|
+
#
|
87
|
+
# di/rel-2011-07-07
|
88
|
+
def base_tag
|
89
|
+
Time.now.strftime("#{ tag_prefix }-%Y-%m-%d")
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
# Returns a list matching the `tag_prefix`, on today's date.
|
94
|
+
def todays_tags
|
95
|
+
tags_with_pattern.grep(%r{^#{ base_tag }})
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
# Returns a pattern we can use to determine all tags for the month
|
100
|
+
def month_pattern
|
101
|
+
Time.now.strftime("#{ tag_prefix }-%Y-%m")
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
# Returns all tags for the month
|
106
|
+
def this_months_tags
|
107
|
+
tags_with_pattern.grep(%r{^#{ month_pattern }})
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
# Returns a sorted list of possible extensions.
|
112
|
+
def extensions
|
113
|
+
('1'..'9').to_a + ('a'..'z').to_a
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
# Extracts the extension from a tag
|
118
|
+
#
|
119
|
+
# Returns either the extension, or a blank string.
|
120
|
+
def tag_ext(tag)
|
121
|
+
ext = tag.sub(tag_regex, '')
|
122
|
+
if ext[0] == ?-
|
123
|
+
ext[1].chr
|
124
|
+
else
|
125
|
+
''
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
# delegate to git helper
|
132
|
+
def git(cmd)
|
133
|
+
git_helper.git( cmd )
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
def git_s(cmd)
|
138
|
+
git_helper.git_s( cmd )
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module Plus2GitTagger
|
2
|
+
class Task < ::Rake::TaskLib
|
3
|
+
|
4
|
+
attr_reader :name, :git
|
5
|
+
|
6
|
+
def initialize(name, &blk)
|
7
|
+
@name = name
|
8
|
+
@git = Plus2GitTagger::Git.new( Dir.pwd )
|
9
|
+
|
10
|
+
@prereqs = %w{preflight commit_preflight}.map {|p| "#{ name }:#{ p }"}
|
11
|
+
@taggers = []
|
12
|
+
|
13
|
+
@reporters = []
|
14
|
+
@monthlys = []
|
15
|
+
|
16
|
+
instance_eval(&blk)
|
17
|
+
|
18
|
+
add_global_reporters
|
19
|
+
|
20
|
+
desc "Preflight (asset compilation, packing etc)"
|
21
|
+
task "#{ name }:preflight" , &@preflight_block if @preflight_block
|
22
|
+
|
23
|
+
desc "Commit compiled assets"
|
24
|
+
task "#{ name }:commit_preflight", &@commit_preflight_block if @commit_preflight_block
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
# API: set the preflight block
|
29
|
+
def preflight(&blk)
|
30
|
+
@preflight_block = blk
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# API: set the preflight commit block
|
35
|
+
def commit_preflight(&blk)
|
36
|
+
@commit_preflight_block = blk
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
# API: define the default tagger
|
41
|
+
def default_tagger( *prefix )
|
42
|
+
@taggers << tagger(nil, *prefix)
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# API: define a tagger
|
47
|
+
def tagger( name, *prefix )
|
48
|
+
name = nil if name && name.strip == ''
|
49
|
+
|
50
|
+
task_name = if name
|
51
|
+
"#{ @name }:#{ name }"
|
52
|
+
else
|
53
|
+
@name
|
54
|
+
end
|
55
|
+
|
56
|
+
string_prefix = [ prefix ].flatten.compact.join("/")
|
57
|
+
|
58
|
+
tagger = Tags.new( @git, string_prefix )
|
59
|
+
|
60
|
+
@taggers << tagger
|
61
|
+
|
62
|
+
desc "Tag a #{name || 'default'} release"
|
63
|
+
task task_name => @prereqs do
|
64
|
+
tagger.make!
|
65
|
+
end
|
66
|
+
|
67
|
+
add_reporters(tagger, task_name)
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
# Adds two reporting tasks for this tagger
|
72
|
+
#
|
73
|
+
# Example:
|
74
|
+
#
|
75
|
+
# tag:hotfix:list
|
76
|
+
# tag:hotfix:list:month
|
77
|
+
def add_reporters(tagger, task_name)
|
78
|
+
|
79
|
+
@reporters << (report_all_name = "#{task_name}:list")
|
80
|
+
|
81
|
+
desc "List all #{basename(task_name)} tags"
|
82
|
+
task report_all_name do
|
83
|
+
tagger.list
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
@monthlys << (report_month_name = "#{task_name}:list:month")
|
88
|
+
|
89
|
+
desc "List all #{basename(task_name)} tags for the month"
|
90
|
+
task report_month_name do
|
91
|
+
tagger.month_list
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
# Adds tasks that will list all tags for this project, or all tags for the project for the month
|
97
|
+
def add_global_reporters
|
98
|
+
desc 'List all tags'
|
99
|
+
task 'tags:list:all' => @reporters
|
100
|
+
|
101
|
+
desc 'List all tags for the month'
|
102
|
+
task 'tags:list:month' => @monthlys
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
# Delegate to git interface.
|
107
|
+
|
108
|
+
# Runs a git command.
|
109
|
+
def git_c(cmd)
|
110
|
+
@git.git(cmd)
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
# Runs a git command, returning its standard out.
|
115
|
+
def git_s(cmd)
|
116
|
+
@git.git_s(cmd)
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
def basename(taskname)
|
121
|
+
taskname == @name ? 'default' : taskname.gsub("#{@name}:", "")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "plus2_git_tagger/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "plus2_git_tagger"
|
7
|
+
s.version = Plus2GitTagger::VERSION
|
8
|
+
s.authors = ["Lachie Cox", "Ben Askins"]
|
9
|
+
s.email = ["lachiec@gmail.com", "ben.askins@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Plus2 + Davidson style git tagger}
|
12
|
+
s.description = %q{Plus2 + Davidson style git tagger, for Davidson + Plus2}
|
13
|
+
|
14
|
+
s.rubyforge_project = "plus2_git_tagger"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: plus2_git_tagger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 6
|
10
|
+
version: 0.0.6
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Lachie Cox
|
14
|
+
- Ben Askins
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2011-09-06 00:00:00 Z
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: Plus2 + Davidson style git tagger, for Davidson + Plus2
|
23
|
+
email:
|
24
|
+
- lachiec@gmail.com
|
25
|
+
- ben.askins@gmail.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files: []
|
31
|
+
|
32
|
+
files:
|
33
|
+
- .gitignore
|
34
|
+
- Gemfile
|
35
|
+
- Rakefile
|
36
|
+
- lib/plus2_git_tagger.rb
|
37
|
+
- lib/plus2_git_tagger/git.rb
|
38
|
+
- lib/plus2_git_tagger/tags.rb
|
39
|
+
- lib/plus2_git_tagger/task.rb
|
40
|
+
- lib/plus2_git_tagger/version.rb
|
41
|
+
- plus2_git_tagger.gemspec
|
42
|
+
homepage: ""
|
43
|
+
licenses: []
|
44
|
+
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
hash: 3
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
version: "0"
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
hash: 3
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
version: "0"
|
68
|
+
requirements: []
|
69
|
+
|
70
|
+
rubyforge_project: plus2_git_tagger
|
71
|
+
rubygems_version: 1.8.5
|
72
|
+
signing_key:
|
73
|
+
specification_version: 3
|
74
|
+
summary: Plus2 + Davidson style git tagger
|
75
|
+
test_files: []
|
76
|
+
|