plus2_git_tagger 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .*.sw?
6
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in plus2_git_tagger.gemspec
4
+ gemspec
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,7 @@
1
+ require "plus2_git_tagger/version"
2
+
3
+ module Plus2GitTagger
4
+ autoload :Tags, "plus2_git_tagger/tags"
5
+ autoload :Task, "plus2_git_tagger/task"
6
+ autoload :Git , "plus2_git_tagger/git"
7
+ 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,3 @@
1
+ module Plus2GitTagger
2
+ VERSION = "0.0.6"
3
+ 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
+