primedia-qa_release_tasks 0.1.1

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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 PRIMEDIA
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,7 @@
1
+ ==Summary
2
+
3
+ QA Release Management Workflow for Git
4
+
5
+ ==Authors
6
+
7
+ Jason Noble, Rein Henrichs
data/Rakefile ADDED
@@ -0,0 +1,51 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rubygems/specification'
4
+ require 'date'
5
+ require 'spec/rake/spectask'
6
+
7
+ require 'lib/qa_release_tasks'
8
+
9
+ GEM = "qa_release_tasks"
10
+ GEM_VERSION = "0.1.1"
11
+ AUTHORS = "Jason Noble", "Rein Henrichs"
12
+ SUMMARY = "A gem that provides workflow driven rake tasks for git QA branch management"
13
+
14
+ spec = Gem::Specification.new do |s|
15
+ s.name = GEM
16
+ s.version = GEM_VERSION
17
+ s.platform = Gem::Platform::RUBY
18
+ s.has_rdoc = true
19
+ s.extra_rdoc_files = ["README.rdoc", "LICENSE"]
20
+ s.summary = SUMMARY
21
+ s.description = s.summary
22
+ s.authors = AUTHORS
23
+
24
+ s.require_path = 'lib'
25
+ s.autorequire = GEM
26
+ s.files = %w(LICENSE README.rdoc Rakefile) + Dir.glob("{lib,spec}/**/*")
27
+ end
28
+
29
+ task :default => :spec
30
+
31
+ desc "Run specs"
32
+ Spec::Rake::SpecTask.new do |t|
33
+ t.spec_files = FileList['spec/**/*_spec.rb']
34
+ t.spec_opts = %w(-fs --color)
35
+ end
36
+
37
+ Rake::GemPackageTask.new(spec) do |pkg|
38
+ pkg.gem_spec = spec
39
+ end
40
+
41
+ desc "install the gem locally"
42
+ task :install => [:package] do
43
+ sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
44
+ end
45
+
46
+ desc "create a gemspec file"
47
+ task :make_spec do
48
+ File.open("#{GEM}.gemspec", "w") do |file|
49
+ file.puts spec.to_ruby
50
+ end
51
+ end
data/lib/cli.rb ADDED
@@ -0,0 +1,43 @@
1
+ module CLI
2
+ def warn(message)
3
+ STDERR.puts "*" * 50
4
+ STDERR.puts "Warning: #{message}"
5
+ STDERR.puts "*" * 50
6
+ end
7
+
8
+ def error(message)
9
+ STDERR.puts "*" * 50
10
+ STDERR.puts "Error: #{message}"
11
+ STDERR.puts "*" * 50
12
+ exit 1
13
+ end
14
+
15
+ def ask(question, default=nil, valid_response=nil, invalid_message=nil)
16
+ loop do
17
+ print "#{question}"
18
+ print " [#{default}]" if default
19
+ print ": "
20
+ answer = STDIN.gets.chomp
21
+ answer = default if default && answer.empty?
22
+ valid = false
23
+ valid = true if valid_response.nil?
24
+ valid = true if valid_response.respond_to?(:include?) && valid_response.include?(answer)
25
+ valid = true if valid_response.respond_to?(:match) && valid_response.match(answer)
26
+ if valid
27
+ return answer
28
+ else
29
+ if valid_response.is_a?(Array)
30
+ puts invalid_message || begin
31
+ print "Invalid answer, please try again."
32
+ print " Valid answers include:\n"
33
+ puts valid_response
34
+ end
35
+ elsif valid_response.is_a?(Regexp)
36
+ puts invalid_message || "Invalid format for answer, please try again."
37
+ else
38
+ puts invalid_message || "Invalid answer, please try again."
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,74 @@
1
+ module Git
2
+ module Commands
3
+
4
+ def assert_is_git_repo
5
+ error "Not a git repository" unless is_git_repo?
6
+ end
7
+
8
+ def is_git_repo?
9
+ File.directory?('.git')
10
+ end
11
+
12
+ # figure out what branch the pwd's repo is on
13
+ def get_branch
14
+ match = Regexp.new("^# On branch (.*)").match(`git status`)
15
+ match && match[1]
16
+ end
17
+
18
+ # e.g. v1.4.3
19
+ def valid_version_regexp
20
+ /^v\d+\.\d+\.\d+/
21
+ end
22
+
23
+ # Find all version tags
24
+ def get_tags
25
+ version_regexp = valid_version_regexp
26
+ %x{git tag}.split.grep(version_regexp).sort_by{|v| v.split('.').map{|nbr| nbr[/\d+/].to_i}}.map{|tag| tag.strip}
27
+ end
28
+
29
+ def next_version(options={})
30
+ latest_tag = get_tags.last
31
+ return 'v0.0.1' unless latest_tag
32
+
33
+ unless latest_tag.match valid_version_regexp
34
+ warn "invalid version number"
35
+ return latest_tag
36
+ end
37
+
38
+ major, minor, point = latest_tag.split('.')
39
+ major = major[1..-1]
40
+ if options[:major]
41
+ major.succ!
42
+ minor, point = '0', '0'
43
+ elsif options[:minor]
44
+ minor.succ!
45
+ point = '0'
46
+ elsif options[:point]
47
+ point.succ!
48
+ else
49
+ warn "unable to increment version number."
50
+ end
51
+
52
+ 'v' + [major, minor, point].join('.')
53
+ end
54
+
55
+ # based on 'git status' output, does this repo contain changes that need to be committed?
56
+ # optional second argument is a specific file (or directory) in the repo.
57
+ def needs_commit?(dir = Dir.pwd, file = nil)
58
+ rval = false
59
+ Dir.chdir(dir) do
60
+ status = %x{git status}
61
+ if file.nil?
62
+ rval = true unless status =~ /nothing to commit \(working directory clean\)|nothing added to commit but untracked files present/
63
+ if status =~ /nothing added to commit but untracked files present/
64
+ warn "untracked files present in #{dir}"
65
+ show_changed_files(status)
66
+ end
67
+ else
68
+ rval = true if status =~ /^#\t.*modified: #{file}/
69
+ end
70
+ end
71
+ rval
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,33 @@
1
+ module Git
2
+ class ReleaseNotes
3
+ require 'enumerator'
4
+ include CLI
5
+ include Commands
6
+
7
+ def annotate!
8
+ assert_is_git_repo
9
+ tags = get_tags.reverse
10
+ error "No version tags available." if tags.empty?
11
+
12
+ start_tag = ask "Start at which tag?", tags[0], tags
13
+ start_index = tags.index(start_tag)
14
+ end_tag = ask "End at which tag?", tags[start_index + 1] || tags[start_index], tags
15
+ puts
16
+ end_index = tags.index(end_tag) + 1 # include end tag
17
+
18
+ start_index.upto(end_index-1) do |i|
19
+ start = tags[i]
20
+ finish = tags[i+1]
21
+ range = ''
22
+ range << "refs/tags/#{finish}.." if finish # log until end tag if there is an end tag
23
+ range << "refs/tags/#{start}"
24
+ log = `git log --no-merges --pretty=format:"%h %s" #{range}`.strip
25
+ next if log.empty?
26
+ puts "#{start}"
27
+ puts "=" * start.length
28
+ puts log
29
+ puts
30
+ end
31
+ end
32
+ end
33
+ end
data/lib/git/tagger.rb ADDED
@@ -0,0 +1,63 @@
1
+ module Git
2
+ class Tagger
3
+ include CLI
4
+ include Commands
5
+
6
+ attr_reader :options
7
+ def initialize(options)
8
+ @options = options
9
+ end
10
+
11
+ def tag!
12
+ assert_is_git_repo
13
+ begin
14
+ assert_on_qa_branch
15
+ assert_no_local_modifications
16
+ update_qa if options[:update]
17
+ tag_next_version(options)
18
+ git_push_tags
19
+ ensure
20
+ system 'git checkout qa_branch' unless get_branch == 'qa_branch'
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def assert_no_local_modifications
27
+ if needs_commit?
28
+ error "You have local modifications. Use git commit or git stash to fix that."
29
+ end
30
+ end
31
+
32
+ def assert_on_qa_branch
33
+ unless get_branch == 'qa_branch'
34
+ error "You have to be in the qa_branch to do a release."
35
+ end
36
+ end
37
+
38
+ def update_qa
39
+ system("git checkout master") &&
40
+ system("git pull") &&
41
+ system("git checkout qa_branch") &&
42
+ system("git pull") &&
43
+ response = %x(git merge master)
44
+
45
+ unless response.include?("Fast forward") || response.include?('Already up-to-date.')
46
+ warn "There are outstanding changes in qa_branch that may need to be merged into master"
47
+ end
48
+ end
49
+
50
+ def tag_next_version(options={})
51
+ tag = next_version(options)
52
+ if options[:update]
53
+ invalid_message = "Invalid version. Version must be in the format: \"v1.2.3\""
54
+ tag = ask "Name of new version tag ", tag, valid_version_regexp, invalid_message
55
+ end
56
+ system "git tag #{tag}"
57
+ end
58
+
59
+ def git_push_tags
60
+ system "git push --tags"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,6 @@
1
+ $:.unshift File.join(File.dirname(__FILE__))
2
+ require 'cli'
3
+ require 'git/commands'
4
+ require 'git/release_notes'
5
+ require 'git/tagger'
6
+ require 'tasks/qa_release'
@@ -0,0 +1,18 @@
1
+ namespace :qa do
2
+ namespace :release do
3
+ desc "Create a new minor version release from master."
4
+ task :new do
5
+ Git::Tagger.new(:minor => true, :update => true).tag!
6
+ end
7
+
8
+ desc "Create a new point version release from qa branch."
9
+ task :update do
10
+ Git::Tagger.new(:point => true).tag!
11
+ end
12
+
13
+ desc "Add release notes for a given tag based on commit summaries"
14
+ task :notes do
15
+ Git::ReleaseNotes.new.annotate!
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ # Load rake file
5
+ import "#{File.dirname(__FILE__)}/qa_release.rake"
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "qa_release_tasks" do
4
+ it "should do nothing" do
5
+ true.should == true
6
+ end
7
+ end
@@ -0,0 +1,2 @@
1
+ $TESTING=true
2
+ $:.push File.join(File.dirname(__FILE__), '..', 'lib')
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: primedia-qa_release_tasks
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Jason Noble
8
+ - Rein Henrichs
9
+ autorequire: qa_release_tasks
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-04-01 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: A gem that provides workflow driven rake tasks for git QA branch management
18
+ email:
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files:
24
+ - README.rdoc
25
+ - LICENSE
26
+ files:
27
+ - LICENSE
28
+ - README.rdoc
29
+ - Rakefile
30
+ - lib/cli.rb
31
+ - lib/git
32
+ - lib/git/commands.rb
33
+ - lib/git/release_notes.rb
34
+ - lib/git/tagger.rb
35
+ - lib/qa_release_tasks.rb
36
+ - lib/tasks
37
+ - lib/tasks/qa_release.rake
38
+ - lib/tasks/qa_release.rb
39
+ - spec/qa_release_tasks_spec.rb
40
+ - spec/spec_helper.rb
41
+ has_rdoc: true
42
+ homepage:
43
+ post_install_message:
44
+ rdoc_options: []
45
+
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ requirements: []
61
+
62
+ rubyforge_project:
63
+ rubygems_version: 1.2.0
64
+ signing_key:
65
+ specification_version: 2
66
+ summary: A gem that provides workflow driven rake tasks for git QA branch management
67
+ test_files: []
68
+