hookers 0.1.0

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 ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in hookers.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ - Provides hooks to integrate with Pivotal Tracker
2
+ - Generates changelogs descriptions based on standard commit messages and tagging
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ Historias e bugs:
2
+
3
+ * FEATURE #29418015: - http://pivotaltracker.com/story/show/29418015
4
+ - [FINISHED #29418015] adicionado - http://github.com/rhruiz/hookers/commit/d08f16b
5
+ - [FINISHED #29418015] adicionado - http://github.com/rhruiz/hookers/commit/d346159
6
+ - [FINISHED #29418015] Teste - http://github.com/rhruiz/hookers/commit/d3cbcd5
7
+
8
+ * FEATURE #29349419: - http://pivotaltracker.com/story/show/29349419
9
+ - [finished #29349419] corrigindo a sintaxe no post-commit - http://github.com/rhruiz/hookers/commit/8359b38
10
+ - [finished #29349419] alterando o post-commit file - http://github.com/rhruiz/hookers/commit/e0dca8b
11
+ - [STORY #29349419] alterando o post-commit file - http://github.com/rhruiz/hookers/commit/a79f429
12
+ - [STORY #29349419] adicionando commands - http://github.com/rhruiz/hookers/commit/2ad28c7
13
+ - [STORY #29349419] resolvendo conflitos do merge - http://github.com/rhruiz/hookers/commit/6a557f8
14
+ - [STORY #29349419] alterando a permissão de execução para o hook - http://github.com/rhruiz/hookers/commit/de33617
15
+ - [STORY #29349419] adicionando permissão de execução para o hook - http://github.com/rhruiz/hookers/commit/8218b57
16
+ - [STORY #29349419] criando o método de setup dos hooks do git - http://github.com/rhruiz/hookers/commit/38cf24a
17
+
18
+ * FEATURE #29348711: - http://pivotaltracker.com/story/show/29348711
19
+ - [STORY #29348711] Initial changelog commands - http://github.com/rhruiz/hookers/commit/4e71c06
data/bin/hookers ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'hookers'
5
+
6
+ args = ARGV.dup
7
+ command = args.shift
8
+
9
+ Hookers.run!(command, args)
data/hookers.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "hookers/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "hookers"
7
+ s.version = Hookers::VERSION
8
+ s.authors = ["Ricardo Hermida Ruiz"]
9
+ s.email = ["rhruiz@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = "Git hooks and change logs"
12
+ s.description = "Contains default hooks files to integrate git with pivotal tracker and change log generator"
13
+
14
+ s.rubyforge_project = "hookers"
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
+
21
+ s.add_runtime_dependency "slop", "~> 2.1"
22
+
23
+ s.add_runtime_dependency "rest-client"
24
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: UTF-8
2
+
3
+ module Hookers
4
+ module Changelog
5
+ class Affects
6
+ attr_accessor :commit, :type, :number
7
+
8
+ def bug?
9
+ self.type == "BUG"
10
+ end
11
+
12
+ def feature?
13
+ self.type == "FEATURE"
14
+ end
15
+
16
+ def type=(value)
17
+ @type = (value == "BUG" ? "BUG" : "FEATURE")
18
+ end
19
+
20
+ def identifier
21
+ "#{type} ##{number}"
22
+ end
23
+
24
+ def uri
25
+ return "http://bugzilla-qa.linux.locaweb.com.br/show_bug.cgi?id=#{self.number}" if bug?
26
+ return "http://pivotaltracker.com/story/show/#{self.number}" if feature?
27
+ end
28
+
29
+ def initialize(commit, type, number)
30
+ self.commit = commit
31
+ self.type = type
32
+ self.number = number
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'stringio'
4
+
5
+ module Hookers
6
+ module Changelog
7
+ class Changelogger
8
+ def initialize(project = Project.discover)
9
+ @project = project
10
+ end
11
+
12
+ def generate(options = {})
13
+ from = options[:from] || History.first
14
+ to = options[:to] || "HEAD"
15
+ lines = History.between(from, to)
16
+ parser = Parser.new(@project)
17
+ commits = lines.map { |e| parser.parse(e) }.flatten.group_by(&:identifier)
18
+
19
+ output = StringIO.new
20
+
21
+ output.puts "Historias e bugs:"
22
+ commits.each_pair do |identifier, commits|
23
+ output.puts "\n * #{identifier}: - #{commits.first.uri}"
24
+ commits.each do |affected|
25
+ output.puts " - #{affected.commit.message} - #{affected.commit.uri}"
26
+ end
27
+ end
28
+
29
+ output.rewind
30
+ output.read
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: UTF-8
2
+
3
+ module Hookers
4
+ module Changelog
5
+ class Commit
6
+ attr_accessor :id, :message, :project
7
+
8
+ def initialize(project, id, message)
9
+ self.project = project
10
+ self.id = id
11
+ self.message = message
12
+ end
13
+
14
+ def uri
15
+ project.commit_uri(self.id)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: UTF-8
2
+
3
+ module Hookers
4
+ module Changelog
5
+ class History
6
+ def self.first
7
+ %x[git rev-list --all --reverse | head -1].strip
8
+ end
9
+
10
+ def self.between(from, to)
11
+ lines = %x[git log --oneline #{from}..#{to}].split(/\n/)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: UTF-8
2
+
3
+ module Hookers
4
+ module Changelog
5
+ class Parser
6
+ attr_accessor :project, :message
7
+
8
+ REGEXP = /\[(bug|feature|story|fixed|fixes|completed|finished|delivers)\s+\#\s*(\d+)\]/i
9
+
10
+ def initialize(project)
11
+ self.project = project
12
+ end
13
+
14
+ def parse(line)
15
+ id, message = line.split(" ", 2)
16
+ data = message.scan(Parser::REGEXP)
17
+ affects = []
18
+ commit = Commit.new(project, id, message)
19
+
20
+ if !data.nil?
21
+ data.each do |type, number|
22
+ affects << Affects.new(commit, type.upcase, number)
23
+ end
24
+ end
25
+
26
+ affects
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: UTF-8
2
+
3
+ module Hookers
4
+ module Changelog
5
+ class Project
6
+ attr_accessor :name, :uri
7
+
8
+ def initialize(name, uri)
9
+ self.name = name
10
+ self.uri = uri
11
+ end
12
+
13
+ def commit_uri(id)
14
+ "#{self.uri}/commit/#{id}"
15
+ end
16
+
17
+ def self.discover
18
+ remote_uri = %x[git remote -v].split(/\n/).first.split(/\s+/).at(1)
19
+
20
+ return nil if remote_uri.nil?
21
+ remote_uri.gsub!(/(git@|git:\/\/)/, "http://")
22
+ remote_uri.gsub!(/:(?!\/\/)/, "/")
23
+ remote_uri.gsub!(/\.git$/, "")
24
+ name = remote_uri.split(/\//).at(-1)
25
+ new(name, remote_uri)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,7 @@
1
+ require "hookers/changelog/project"
2
+ require "hookers/changelog/affects"
3
+ require "hookers/changelog/changelogger"
4
+ require "hookers/changelog/commit"
5
+ require "hookers/changelog/history"
6
+ require "hookers/changelog/parser"
7
+ require "hookers/commands/changelog"
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module Hookers
4
+ def self.commands
5
+ @@commands ||= {}
6
+ end
7
+
8
+ module Command
9
+ def self.included(base)
10
+ Hookers.commands[base.name.gsub(/^Hookers::Commands::/, "").downcase] = base
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: UTF-8
2
+
3
+ module Hookers
4
+ module Commands
5
+ class Changelog
6
+ include Hookers::Command
7
+
8
+ def self.slop
9
+ Slop.new(help: true, banner: "Generates changelogs based on commit messages") do
10
+ on :from, "Generate changelog from this refence", argument: true
11
+ on :to, "Generate changelog up to this reference", argument: true
12
+ on :setup, "Copy git hooks files to project .git/hooks ", argument: true
13
+ end
14
+ end
15
+
16
+ attr_accessor :options
17
+
18
+ def initialize(command, args)
19
+ self.class.slop.parse(args)
20
+ self.options = self.class.slop.to_hash
21
+ end
22
+
23
+ def run
24
+ puts Hookers::Changelog::Changelogger.new.generate(options)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: UTF-8
2
+
3
+ module Hookers
4
+ module Commands
5
+ class GitCommit
6
+ include Hookers::Command
7
+
8
+ attr_accessor :options, :command, :git
9
+
10
+ KEYS = %w(bug feature story fixed fixes completed finished delivers)
11
+
12
+ KEYS.each{|command| Hookers.commands[command] = self }
13
+
14
+ def self.slop
15
+ Slop.new(help: true) do
16
+ on :m, "Message to be used on commit", argument: true
17
+ on :id, "Pivotal story id", argument: true
18
+ end
19
+ end
20
+
21
+ def initialize(command, args)
22
+ self.class.slop.parse(args)
23
+ self.options = self.class.slop.to_hash
24
+ self.git = Git::Repository.new
25
+ end
26
+
27
+ def run
28
+ puts git.commit "[#{self.command.upcase} ##{options[:id]}] #{options[:m]}"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: UTF-8
2
+
3
+ module Hookers
4
+ module Commands
5
+ class GitSetup
6
+ include Hookers::Command
7
+
8
+ attr_accessor :options
9
+
10
+ Hookers.commands["setup"] = self
11
+
12
+ def initialize(command, args)
13
+ self.class.slop.parse(args)
14
+ self.options = self.class.slop.to_hash
15
+ end
16
+
17
+ def run
18
+ puts Hookers::Git.setup
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: UTF-8
2
+
3
+ module Hookers
4
+ module Commands
5
+ class Help
6
+ include Hookers::Command
7
+
8
+ attr_accessor :args
9
+
10
+ def initialize(command, args)
11
+ self.args = args
12
+ end
13
+
14
+ def run
15
+ if args.length == 0 || Hookers.commands[args[0]] == nil
16
+ puts "Use hookers help <command> for additional options\nAvailable commands: "
17
+ Hookers.commands.keys.each { |k| puts "\t#{k}" }
18
+ return
19
+ end
20
+
21
+ if Hookers.commands[args[0]] && Hookers.commands[args[0]].respond_to?(:slop)
22
+ puts Hookers.commands[args[0]].slop.help
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: UTF-8
2
+
3
+ module Hookers
4
+ module Commands
5
+ class Pivotal
6
+ include Hookers::Command
7
+
8
+ attr_accessor :options
9
+
10
+ def self.slop
11
+ Slop.new(help: true) do
12
+ on :"api-token", "Pivotal user token to sync commits", argument: true
13
+ end
14
+ end
15
+
16
+ def initialize(command, args)
17
+ self.class.slop.parse(args)
18
+ self.options = self.class.slop.to_hash
19
+ end
20
+
21
+ def run
22
+ puts Hookers::Pivotal::TrackerProject.new(options[:"api-token"]).notify_changes
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ require "cgi"
2
+
3
+ module Hookers
4
+ module Git
5
+ class Commit
6
+ attr_accessor :id, :author, :message
7
+
8
+ def initialize(id, author, message)
9
+ self.id = id
10
+ self.author = author
11
+ self.message = message
12
+ end
13
+
14
+ def to_xml
15
+ "<source_commit>
16
+ <commit_id> #{ self.id } </commit_id>
17
+ <author> #{ CGI::escapeHTML(self.author) } </author>
18
+ <message> #{ CGI::escapeHTML(self.message) } </message>
19
+ </source_commit>"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ require 'shellwords'
2
+
3
+ module Hookers
4
+ module Git
5
+ class Repository
6
+ def last_commit
7
+ revision = %x(git log -1 HEAD --format=%H%n%an%n%s).split("\n")
8
+ Git::Commit.new(revision[0], revision[1], revision[2])
9
+ end
10
+
11
+ def commit(message)
12
+ %x(git commit -m'#{message}')
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: UTF-8
2
+ require 'fileutils'
3
+
4
+ module Hookers
5
+ module Git
6
+ extend self
7
+
8
+ def root_path
9
+ path = Dir.pwd
10
+
11
+ while (path != "/") and ! Dir.entries(path).include?(".git") do
12
+ path = File.expand_path("..", path)
13
+ end
14
+ path
15
+ end
16
+
17
+ def setup
18
+ from_path = "#{Hookers.root}/scripts/git/post-commit"
19
+ to_path = "#{root_path}/.git/hooks/post-commit"
20
+
21
+ FileUtils.cp(from_path, to_path)
22
+ FileUtils.chmod 0755, to_path
23
+
24
+ "setup successfully"
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ module Hookers
5
+ module Pivotal
6
+ module HttpClient
7
+ extend self
8
+
9
+ def post(url, body, headers)
10
+ uri = URI.parse(url)
11
+ http = Net::HTTP.new(uri.host)
12
+ request = Net::HTTP::Post.new(uri.request_uri)
13
+
14
+ request.body = body
15
+ request.initialize_http_header headers
16
+
17
+ http.request(request)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: UTF-8
2
+
3
+ module Hookers
4
+ module Pivotal
5
+ class TrackerProject
6
+ attr_accessor :token, :base_uri, :git
7
+
8
+ def initialize(token)
9
+ raise "Pivotal api token not found" unless token
10
+ self.token = token
11
+ self.git = Git::Repository.new
12
+ self.base_uri = 'http://www.pivotaltracker.com/'
13
+ end
14
+
15
+ def commit_uri
16
+ "#{self.base_uri}services/v3/source_commits"
17
+ end
18
+
19
+ def notify_changes
20
+ puts "Notifying pivotal tracker of changes..."
21
+
22
+ commit = git.last_commit
23
+
24
+ response = HttpClient.post(commit_uri, commit.to_xml, { "X-TrackerToken" => self.token, "Content-type" => "application/xml" })
25
+
26
+ puts "Pivotal notified succesfully" if response.code == "200"
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,8 @@
1
+ require "hookers/git/commit"
2
+ require "hookers/git/repository"
3
+ require "hookers/git/setup"
4
+ require "hookers/pivotal/http_client"
5
+ require "hookers/pivotal/tracker_project"
6
+ require "hookers/commands/pivotal"
7
+ require "hookers/commands/git_setup"
8
+ require "hookers/commands/git_commit"
@@ -0,0 +1,3 @@
1
+ module Hookers
2
+ VERSION = "0.1.0"
3
+ end
data/lib/hookers.rb ADDED
@@ -0,0 +1,20 @@
1
+ require "hookers/version"
2
+ require "hookers/command"
3
+ require "hookers/commands/help"
4
+
5
+ require "hookers/changelog"
6
+ require "hookers/pivotal"
7
+
8
+ require "slop"
9
+
10
+ module Hookers
11
+ extend self
12
+
13
+ def root
14
+ File.expand_path '../..', __FILE__
15
+ end
16
+
17
+ def self.run!(command, options = {})
18
+ commands.fetch(command, Hookers::Commands::Help).new(command, options).run
19
+ end
20
+ end
@@ -0,0 +1,8 @@
1
+
2
+ if [ "$PIVOTAL_TRACKER_TOKEN" = "" ]; then
3
+ echo "set PIVOTAL_TRACKER_TOKEN in the environment to enable notification";
4
+ exit 1;
5
+ else
6
+ hookers pivotal --api-token=$PIVOTAL_TRACKER_TOKEN;
7
+ exit $?;
8
+ fi
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hookers
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ricardo Hermida Ruiz
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-11 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: slop
16
+ requirement: &70208915722140 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.1'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70208915722140
25
+ - !ruby/object:Gem::Dependency
26
+ name: rest-client
27
+ requirement: &70208915721720 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70208915721720
36
+ description: Contains default hooks files to integrate git with pivotal tracker and
37
+ change log generator
38
+ email:
39
+ - rhruiz@gmail.com
40
+ executables:
41
+ - CHANGELOG.md
42
+ - hookers
43
+ extensions: []
44
+ extra_rdoc_files: []
45
+ files:
46
+ - .gitignore
47
+ - Gemfile
48
+ - README.md
49
+ - Rakefile
50
+ - bin/CHANGELOG.md
51
+ - bin/hookers
52
+ - hookers.gemspec
53
+ - lib/hookers.rb
54
+ - lib/hookers/changelog.rb
55
+ - lib/hookers/changelog/affects.rb
56
+ - lib/hookers/changelog/changelogger.rb
57
+ - lib/hookers/changelog/commit.rb
58
+ - lib/hookers/changelog/history.rb
59
+ - lib/hookers/changelog/parser.rb
60
+ - lib/hookers/changelog/project.rb
61
+ - lib/hookers/command.rb
62
+ - lib/hookers/commands/changelog.rb
63
+ - lib/hookers/commands/git_commit.rb
64
+ - lib/hookers/commands/git_setup.rb
65
+ - lib/hookers/commands/help.rb
66
+ - lib/hookers/commands/pivotal.rb
67
+ - lib/hookers/git/commit.rb
68
+ - lib/hookers/git/repository.rb
69
+ - lib/hookers/git/setup.rb
70
+ - lib/hookers/pivotal.rb
71
+ - lib/hookers/pivotal/http_client.rb
72
+ - lib/hookers/pivotal/tracker_project.rb
73
+ - lib/hookers/version.rb
74
+ - scripts/git/post-commit
75
+ homepage: ''
76
+ licenses: []
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project: hookers
95
+ rubygems_version: 1.8.10
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: Git hooks and change logs
99
+ test_files: []