pr_log 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 219e0119cbee6cea394f2acad2aaff4bb31d74b6
4
+ data.tar.gz: bf6b1f5ea714216c73f0bfee3967e9f77052b44b
5
+ SHA512:
6
+ metadata.gz: a6d06a0f16cb8fd248d4557dd2047a8f0971115206968e12566bac5332b9ce54579364721754d5141e119cccd6b36ab3c5ef471bd75929470be6f1918665e5c3
7
+ data.tar.gz: 1541586d7a72ebf774c41160e9589147ff8fa64db79139ad83228754346436435e9797dd27cc6e84f85f7129552ed9693e76a855db885d5fa9a1a90a41118bdf
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,20 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.1.1
5
+
6
+ # User container based travis infrastructure which allows caching
7
+ # features for open source projects.
8
+ sudo: false
9
+ cache: bundler
10
+
11
+ before_install: gem install bundler -v 1.10.5
12
+
13
+ env:
14
+ global:
15
+ - PR_LOG_FIXTURE_OAUTH_TOKEN=8909728af9171b43308994050f0c6f57994ace5f
16
+
17
+ addons:
18
+ code_climate:
19
+ repo_token:
20
+ secure: "aQtvo+k13pyGi4Hi/7/Hx/wIv5lAlZ0AXrMNy0A4mPF4en6y2jW9yiO0pSMNBAPRmiFrDstarW4IcdtHVQ4vT6XBvcmu4DmYBdfcutrhBBXFXx2IOMtqKpGAib42HQW7lgSwVh2nPTqyVh2fw8TnEYk7Mr1cFK9zQXasFll/yCYtRHquDJxanwYyISw6q8YN7Z9e5M8Sv2Mc7Bu2qtx6QXkEEd8JvxtvXT2vQBdGrzH3Y+gC9hKr2BgJnV9of2Ofu0oFY958nlqxj3dSj9m64wt8xHt4W2fU4FNv4lPCHHotQdWTY2ugzdOA6GhSf76hOO5t/0lQ44eJySgmIzTIWWFUCAzvWpOv7Wj4jrMeoF+MxzQmEu7rUfuu/hFR+dEliQouiMAhBGy6cP8PtzHrUcf3cYaW5GcE57RU/FBb0cyM6QG2vDK0C12bjzpuLrv9dkfizlxPZnwdiuOQWG45sbZgKWv212Dj34jT2rDpfCfovbpse72Pi0FSN4Q04CvHkB/ITP6LGKF5NCmLAewJKOsjUbciPgX7PxnY9ieFLgadenfFQARpRCZaw5Gp7ZEJq+8LAFokW9lDu2HdByRGLDXvv+6yve+Rt5bCT5T+ALboGr0FXaZJ/YCAdL4mUudY/5rW36ZyPQrPpQnnxSe62GzHKCdJhtbhpaEIOubcScQ="
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # CHANGELOG
2
+
3
+ ## Version 0.1.0
4
+
5
+ 2015-07-28
6
+
7
+ - Initial release.
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pr_log.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Tim Fischbach
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,150 @@
1
+ # PR Log
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/pr_log.svg)](http://badge.fury.io/rb/pr_log)
4
+ [![Dependency Status](https://gemnasium.com/tf/pr_log.svg)](https://gemnasium.com/tf/pr_log)
5
+ [![Build Status](https://travis-ci.org/tf/pr_log.svg?branch=master)](https://travis-ci.org/tf/pr_log)
6
+ [![Test Coverage](https://codeclimate.com/github/tf/pr_log/badges/coverage.svg)](https://codeclimate.com/github/tf/pr_log)
7
+ [![Code Climate](https://codeclimate.com/github/tf/pr_log/badges/gpa.svg)](https://codeclimate.com/github/tf/pr_log)
8
+
9
+ Turn GitHub pull requests into changelog entries.
10
+
11
+ ## Assumptions
12
+
13
+ **Changelogs should be written for humans by humans**
14
+
15
+ PrLog does not try to auto generate a complete changelog. Instead, it
16
+ pulls GitHub data to prefill your changelog as a baseline for manual
17
+ editing. Add prose, order items by priority, insert headers.
18
+
19
+ **Merged pull requests fully describe project history**
20
+
21
+ PrLog ignores GitHub issues. If a pull request fixes an
22
+ important issue it can reference it in its title or description.
23
+
24
+ **Pull requests are tagged with version milestones**
25
+
26
+ PrLog expects pull requests to be assigned to version milestones like
27
+ `v1.1`. This ensures consistency with the issue tracker and helps
28
+ limit GitHub API requests to relevant data.
29
+
30
+ **Changelogs are written in Markdown**
31
+
32
+ Markdown is the de facto standard for formatting files to be
33
+ displayed on GitHub.
34
+
35
+ ## Installation
36
+
37
+ Install the command line tool:
38
+
39
+ $ gem install pr_log
40
+
41
+ Generate a
42
+ [personal access token](https://help.github.com/articles/creating-an-access-token-for-command-line-use/)
43
+ and place it in a `.pr_log.yml` file in your home directory:
44
+
45
+ # ~/.pr_log.yml
46
+ access_token: "xxx"
47
+
48
+ ## Usage
49
+
50
+ To insert items for new pull requests with milestone `v.1.2` into your
51
+ `CHANGELOG.md` file run:
52
+
53
+ $ prlog fetch --github-repository some/repository --milestone v1.2
54
+
55
+ By default, this creates entries of the form:
56
+
57
+ - Title of the pull request
58
+ ([#100](https://github.com/some/repository/pull/100)))
59
+
60
+ If a pull request URL is already mentioned in the changelog, no entry
61
+ will be created.
62
+
63
+ ### Convention over Configuration
64
+
65
+ The `fetch` command can also be invoked without command line options:
66
+
67
+ $ prlog fetch
68
+
69
+ PrLog tries to derive defaults from gemspec information:
70
+
71
+ - If the `homepage` attribute mentions the URL of the github
72
+ repository, it is used to determine the github repository name.
73
+ - PrLog constructs a milestone name of the form `v%{major}.%{minor}`
74
+ from the current gem version.
75
+
76
+ ### Configuration
77
+
78
+ To override PrLog's default configuration you can either pass command
79
+ line options or place a `.pr_log.yml` file inside your project's root
80
+ or your home directory:
81
+
82
+ # .pr_log.yml
83
+ changelog_file: "HISTORY.md"
84
+
85
+ The following configuration options are available:
86
+
87
+ - `access_token`: Personal access token to use for GitHub API
88
+ requests.
89
+
90
+ - `changelog_file`: Relative path to the changelog file.
91
+
92
+ - `entry_template`: Template string used for new changelog
93
+ entries. All fields from the
94
+ [issue search response](https://developer.github.com/v3/search/#search-issues)
95
+ can be used as interpolations.
96
+
97
+ - `github_repository`: Name of the GitHub repository of the form
98
+ `user/repository`.
99
+
100
+ - `insert_after`: Regular expression or string matching the line
101
+ inside the changelog after which new items shall be inserted.
102
+
103
+ - `label_prefixes`: A hash mapping GitHub label names to title
104
+ prefixes for changelog entries. See below for details.
105
+
106
+ - `milestone`: Name of the milestone filter fetched pull requests by.
107
+
108
+ - `milestone_format`: Template string used to derive a milestone name
109
+ from the current gem version. The strings `%{major}`, `%{minor}` and
110
+ `%{patch}` are replaces with the corresponding numeric component of
111
+ the current version. Default value: `v%{major}.%{minor}`.
112
+
113
+ ### Label Prefixes
114
+
115
+ Items for pull requests with certain labels can be prefixed with a
116
+ string automatically. To add a "Bug fix:" prefix to all pull requests
117
+ with the label `bug`, add the following lines to your configuration file:
118
+
119
+ # pr_log.yml
120
+ label_prefixes:
121
+ bug: "Bug fix:"
122
+
123
+ ## Development
124
+
125
+ After checking out the repo, run `bin/setup` to install
126
+ dependencies. You can also run `bin/console` for an interactive prompt
127
+ that will allow you to experiment.
128
+
129
+ ### Running the Test Suite
130
+
131
+ Ensure the environment variable `PR_LOG_FIXTURE_OAUTH_TOKEN` is set to
132
+ a valid GitHub access token. Then run `bin/rspec`. The test suite uses
133
+ [VCR](https://github.com/vcr/vcr) to record and replay requests to the
134
+ GitHub API. Fixture data used by the test suite comes from the
135
+ [tf/pr_log_test_fixture](https://github.com/tf/pr_log_test_fixture)
136
+ repository.
137
+
138
+ ## Contributing
139
+
140
+ Bug reports and pull requests are welcome on GitHub at
141
+ https://github.com/tf/pr_log. This project is intended to be a safe,
142
+ welcoming space for collaboration, and contributors are expected to
143
+ adhere to the [Contributor Covenant](http://contributor-covenant.org)
144
+ code of conduct.
145
+
146
+ ## License
147
+
148
+ The gem is available as open source under the terms of the
149
+ [MIT License](http://opensource.org/licenses/MIT).
150
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "pr_log"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/rspec ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rspec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rspec-core', 'rspec')
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/exe/prlog ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pr_log'
4
+
5
+ PrLog::Cli.start
data/lib/pr_log/cli.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'thor'
2
+
3
+ module PrLog
4
+ # The main command line interface
5
+ class Cli < Thor
6
+ desc 'fetch', 'Insert changelog entries for new pull requests'
7
+ method_option(:changelog_file,
8
+ aliases: '-c',
9
+ desc: 'Path of the changelog file')
10
+ method_option(:insert_after,
11
+ aliases: '-i',
12
+ desc: 'Line to insert new entries after')
13
+ method_option(:github_repository,
14
+ aliases: '-r',
15
+ desc: 'GitHub repository name')
16
+ method_option(:access_token,
17
+ aliases: '-t',
18
+ desc: 'OAuth access token for GitHub API')
19
+ method_option(:milestone,
20
+ aliases: '-m',
21
+ desc: 'Version milestone to filter pull requests')
22
+ method_option(:milestone_format,
23
+ desc: 'Pattern to derive milestone from gem version')
24
+ def fetch
25
+ FetchCommand.perform(options) do |command|
26
+ command.on(:fetching) do |milestone, github_repository_name|
27
+ say_status(:fetching,
28
+ "pull requests for milestone #{milestone} " \
29
+ "from #{github_repository_name}")
30
+ end
31
+
32
+ command.on(:inserting) do |pull_requests, changelog_file|
33
+ say_status(:inserting,
34
+ "#{pull_requests.size} entries " \
35
+ "into #{changelog_file}")
36
+ end
37
+ end
38
+ rescue Error => e
39
+ say_status(:error, e.message, :red)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,24 @@
1
+ require 'events'
2
+
3
+ module PrLog
4
+ # Event emitting command base class
5
+ class Command < Struct.new(:config)
6
+ include Events::Emitter
7
+
8
+ def self.perform(options)
9
+ command = new(Configuration.setup(options))
10
+ yield(command) if block_given?
11
+ command.perform
12
+ end
13
+
14
+ def perform
15
+ fail(NotImplementedError)
16
+ end
17
+
18
+ private
19
+
20
+ def project
21
+ @project ||= Project.new(config)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,54 @@
1
+ require 'virtus'
2
+
3
+ module PrLog
4
+ # Configuration options
5
+ class Configuration
6
+ include Virtus.model
7
+
8
+ attribute :changelog_file, String, default: 'CHANGELOG.md'
9
+
10
+ attribute :insert_after, Regexp, default: "# CHANGELOG\n"
11
+
12
+ attribute :label_prefixes, Hash, default: { bug: 'Bug fix:' }
13
+
14
+ attribute :github_repository, String
15
+
16
+ attribute :access_token, String
17
+
18
+ attribute :milestone, String
19
+
20
+ attribute :milestone_format, String, default: 'v%{major}.%{minor}'
21
+
22
+ attribute :entry_template, String, default: <<-TEXT.gsub(/^ {6}/, '')
23
+ - %{title}
24
+ ([#%{number}](%{html_url}))
25
+ TEXT
26
+
27
+ def set(attributes)
28
+ self.attributes = attributes.reject do |_, value|
29
+ value.nil?
30
+ end
31
+ end
32
+
33
+ def set_from_files
34
+ CONFIG_FILE_NAMES.each do |config_file_name|
35
+ next unless File.exist?(config_file_name)
36
+ self.attributes = YAML.load_file(config_file_name)
37
+ end
38
+ end
39
+
40
+ def self.setup(attributes)
41
+ config = new
42
+
43
+ config.set_from_files
44
+ config.set(attributes)
45
+
46
+ config
47
+ end
48
+
49
+ CONFIG_FILE_NAMES = [
50
+ "#{ENV['HOME']}/.pr_log.yml",
51
+ '.pr_log.yml'
52
+ ]
53
+ end
54
+ end
@@ -0,0 +1,25 @@
1
+ module PrLog
2
+ class Error < StandardError
3
+ end
4
+
5
+ class InsertPointNotFound < Error
6
+ end
7
+
8
+ class ChangelogFileNotFound < Error
9
+ end
10
+
11
+ class GemspecNotFound < Error
12
+ end
13
+
14
+ class GithubRepositoryRequired < Error
15
+ end
16
+
17
+ class NonGithubHomepage < Error
18
+ end
19
+
20
+ class NoPullRequestsForMilestone < Error
21
+ end
22
+
23
+ class GithubRepositoryNotFound < Error
24
+ end
25
+ end
@@ -0,0 +1,41 @@
1
+ require 'pr_log/command'
2
+
3
+ module PrLog
4
+ # Top level workflow of the fetch command
5
+ class FetchCommand < Command
6
+ def perform
7
+ emit(:fetching, project.milestone, project.github_repository_name)
8
+ pull_requests = new_pull_requests
9
+
10
+ emit(:inserting, pull_requests, config.changelog_file)
11
+ insert_pull_requests(pull_requests)
12
+ end
13
+
14
+ private
15
+
16
+ def new_pull_requests
17
+ pull_requests = project.pull_requests_for_current_milestone
18
+
19
+ excluded_issue_numbers = project.issue_numbers_mentioned_in_changelog
20
+
21
+ pull_requests.reject do |pull_request|
22
+ excluded_issue_numbers.include?(pull_request[:number])
23
+ end
24
+ end
25
+
26
+ def insert_pull_requests(pull_requests)
27
+ entries = formatter(pull_requests).entries
28
+ injector.insert_after(config.insert_after, entries)
29
+ end
30
+
31
+ def formatter(pull_requests)
32
+ Formatter.new(pull_requests,
33
+ config.entry_template,
34
+ config.label_prefixes)
35
+ end
36
+
37
+ def injector
38
+ Injector.new(config.changelog_file)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,36 @@
1
+ module PrLog
2
+ # Format new pull requests from github search response
3
+ class Formatter < Struct.new(:pull_requests,
4
+ :entry_template,
5
+ :label_prefixes)
6
+
7
+ def entries
8
+ return '' if pull_requests.empty?
9
+
10
+ pull_requests.map do |pull_request|
11
+ entry_template % entry_template_data(pull_request)
12
+ end.join.prepend("\n")
13
+ end
14
+
15
+ private
16
+
17
+ def entry_template_data(pull_request)
18
+ pull_request.merge(title: prefixed_title(pull_request))
19
+ end
20
+
21
+ def prefixed_title(pull_request)
22
+ [label_prefix(pull_request),
23
+ format_title(pull_request)].compact.join(' ')
24
+ end
25
+
26
+ def label_prefix(pull_request)
27
+ pull_request.fetch(:labels, []).map do |label|
28
+ label_prefixes[label[:name].to_s]
29
+ end.compact.first
30
+ end
31
+
32
+ def format_title(pull_request)
33
+ pull_request[:title].capitalize
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,30 @@
1
+ module PrLog
2
+ # Extract default configuration from a gem specification
3
+ class Gemspec < Struct.new(:specification, :milestone_format)
4
+ def github_repository
5
+ unless specification.homepage =~ %r{https?://github.com/}
6
+ fail(NonGithubHomepage,
7
+ 'Gemspec does not have GitHub hompage URL.')
8
+ end
9
+
10
+ specification.homepage.split('github.com/').last
11
+ end
12
+
13
+ def version_milestone
14
+ milestone_format % version_components
15
+ end
16
+
17
+ private
18
+
19
+ def version_components
20
+ components = specification.version.to_s.split('.')
21
+
22
+ [:major, :minor, :patch]
23
+ .each_with_index
24
+ .each_with_object({}) do |(name, index), result|
25
+
26
+ result[name] = components[index]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,34 @@
1
+ require 'octokit'
2
+
3
+ module PrLog
4
+ # Adapter for Github Api
5
+ class GithubRepository
6
+ def initialize(name, access_token)
7
+ @name = name
8
+ @client = Octokit::Client.new(access_token: access_token)
9
+ end
10
+
11
+ def pull_requests_with_milestone(milestone)
12
+ fail_if_empty(get_issues(milestone_query(milestone)))
13
+ end
14
+
15
+ private
16
+
17
+ def milestone_query(milestone)
18
+ "repo:#{@name} type:pr is:merged milestone:#{milestone}"
19
+ end
20
+
21
+ def fail_if_empty(result)
22
+ return result if result.any?
23
+
24
+ fail(NoPullRequestsForMilestone,
25
+ 'No pull requests for milestone')
26
+ end
27
+
28
+ def get_issues(query)
29
+ @client.search_issues(query, per_page: 1000)['items'].map(&:to_hash)
30
+ rescue Octokit::UnprocessableEntity
31
+ raise(GithubRepositoryNotFound, 'Github repository not found')
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,22 @@
1
+ module PrLog
2
+ # Injects text into a file
3
+ class Injector < Struct.new(:destination_file)
4
+ def insert_after(line, text)
5
+ unless replace!(/#{line}/, '\0' + text)
6
+ fail(InsertPointNotFound, "Insert point not found in #{destination_file}.")
7
+ end
8
+ end
9
+
10
+ private
11
+
12
+ def replace!(regexp, text)
13
+ content = File.binread(destination_file)
14
+
15
+ return false unless content.gsub!(regexp, text)
16
+
17
+ File.open(destination_file, 'wb') do |file|
18
+ file.write(content)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ module PrLog
2
+ # Get mentioned issues from a changelog
3
+ class ParsedChangelog
4
+ def initialize(text, options = {})
5
+ @text = text
6
+ @github_repository = options.fetch(:github_repository)
7
+ end
8
+
9
+ def mentioned_issue_numbers
10
+ @text.scan(pull_request_urls_matcher).flatten.map(&:to_i)
11
+ end
12
+
13
+ private
14
+
15
+ def pull_request_urls_matcher
16
+ %r{#{repository_url_matcher}/pull/(\d+)}
17
+ end
18
+
19
+ def repository_url_matcher
20
+ %r{https?://github.com/#{@github_repository}}
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,52 @@
1
+ module PrLog
2
+ # Parse files from the local project directory
3
+ class Project < Struct.new(:config)
4
+ def issue_numbers_mentioned_in_changelog
5
+ parsed_changelog.mentioned_issue_numbers
6
+ end
7
+
8
+ def milestone
9
+ config.milestone || gemspec.version_milestone
10
+ end
11
+
12
+ def github_repository_name
13
+ config.github_repository || gemspec.github_repository
14
+
15
+ rescue GemspecNotFound
16
+ raise(GithubRepositoryRequired,
17
+ 'Could not derive github repository from gemspec.')
18
+ rescue NonGithubHomepage
19
+ raise(GithubRepositoryRequired,
20
+ 'Homepage attribute in gemspec is not a GitHub URL.')
21
+ end
22
+
23
+ def pull_requests_for_current_milestone
24
+ github_repository.pull_requests_with_milestone(milestone)
25
+ end
26
+
27
+ private
28
+
29
+ def github_repository
30
+ GithubRepository.new(github_repository_name,
31
+ config.access_token)
32
+ end
33
+
34
+ def parsed_changelog
35
+ ParsedChangelog.new(File.read(config.changelog_file),
36
+ github_repository: github_repository_name)
37
+ rescue Errno::ENOENT
38
+ raise(ChangelogFileNotFound,
39
+ "Could not find '#{config.changelog_file}' file.")
40
+ end
41
+
42
+ def gemspec
43
+ Gemspec.new(Gem::Specification.load(gemspec_path),
44
+ config.milestone_format)
45
+ end
46
+
47
+ def gemspec_path
48
+ Dir.glob('*.gemspec').first ||
49
+ fail(GemspecNotFound, 'Gemspec not found.')
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,3 @@
1
+ module PrLog
2
+ VERSION = '0.1.0'
3
+ end
data/lib/pr_log.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'pr_log/cli'
2
+ require 'pr_log/configuration'
3
+ require 'pr_log/errors'
4
+ require 'pr_log/fetch_command'
5
+ require 'pr_log/formatter'
6
+ require 'pr_log/gemspec'
7
+ require 'pr_log/github_repository'
8
+ require 'pr_log/injector'
9
+ require 'pr_log/parsed_changelog'
10
+ require 'pr_log/project'
11
+ require 'pr_log/version'
12
+
13
+ require 'yaml'
14
+
15
+ module PrLog
16
+ end
data/pr_log.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'pr_log/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'pr_log'
8
+ spec.version = PrLog::VERSION
9
+ spec.authors = ['Tim Fischbach']
10
+ spec.email = ['mail@timfischbach.de']
11
+
12
+ spec.summary = 'Turn GitHub pull requests into changelog entries'
13
+ spec.homepage = 'https://github.com/tf/pr_log'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^spec/})
18
+ end
19
+ spec.bindir = 'exe'
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_dependency 'thor', '~> 0.19'
24
+ spec.add_dependency 'octokit', '~> 4.0'
25
+ spec.add_dependency 'virtus', '~> 1.0'
26
+ spec.add_dependency 'events'
27
+
28
+ spec.add_development_dependency 'bundler', '~> 1.10'
29
+ spec.add_development_dependency 'rake', '~> 10.0'
30
+ spec.add_development_dependency 'rspec', '~> 3.0'
31
+ spec.add_development_dependency 'webmock', '~> 1.21'
32
+ spec.add_development_dependency 'vcr', '~> 2.9'
33
+ spec.add_development_dependency 'unindent', '~> 1.0'
34
+ spec.add_development_dependency 'codeclimate-test-reporter'
35
+ end
metadata ADDED
@@ -0,0 +1,226 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pr_log
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Tim Fischbach
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-07-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.19'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.19'
27
+ - !ruby/object:Gem::Dependency
28
+ name: octokit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: virtus
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: events
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.10'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.10'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: webmock
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.21'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.21'
125
+ - !ruby/object:Gem::Dependency
126
+ name: vcr
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '2.9'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '2.9'
139
+ - !ruby/object:Gem::Dependency
140
+ name: unindent
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '1.0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '1.0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: codeclimate-test-reporter
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ description:
168
+ email:
169
+ - mail@timfischbach.de
170
+ executables:
171
+ - prlog
172
+ extensions: []
173
+ extra_rdoc_files: []
174
+ files:
175
+ - ".gitignore"
176
+ - ".rspec"
177
+ - ".travis.yml"
178
+ - CHANGELOG.md
179
+ - CODE_OF_CONDUCT.md
180
+ - Gemfile
181
+ - LICENSE.txt
182
+ - README.md
183
+ - Rakefile
184
+ - bin/console
185
+ - bin/rspec
186
+ - bin/setup
187
+ - exe/prlog
188
+ - lib/pr_log.rb
189
+ - lib/pr_log/cli.rb
190
+ - lib/pr_log/command.rb
191
+ - lib/pr_log/configuration.rb
192
+ - lib/pr_log/errors.rb
193
+ - lib/pr_log/fetch_command.rb
194
+ - lib/pr_log/formatter.rb
195
+ - lib/pr_log/gemspec.rb
196
+ - lib/pr_log/github_repository.rb
197
+ - lib/pr_log/injector.rb
198
+ - lib/pr_log/parsed_changelog.rb
199
+ - lib/pr_log/project.rb
200
+ - lib/pr_log/version.rb
201
+ - pr_log.gemspec
202
+ homepage: https://github.com/tf/pr_log
203
+ licenses:
204
+ - MIT
205
+ metadata: {}
206
+ post_install_message:
207
+ rdoc_options: []
208
+ require_paths:
209
+ - lib
210
+ required_ruby_version: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ required_rubygems_version: !ruby/object:Gem::Requirement
216
+ requirements:
217
+ - - ">="
218
+ - !ruby/object:Gem::Version
219
+ version: '0'
220
+ requirements: []
221
+ rubyforge_project:
222
+ rubygems_version: 2.2.2
223
+ signing_key:
224
+ specification_version: 4
225
+ summary: Turn GitHub pull requests into changelog entries
226
+ test_files: []