chandler 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 28c48e717e5bfe8d315838375675db111b000913
4
- data.tar.gz: 887b51655dca90533757f24715e81afaf1df6c11
3
+ metadata.gz: 5673a567ce734fb8e24c014c16de889faf2087a6
4
+ data.tar.gz: 524071c288c0424a61ba2d36da70c9af4a1f2a0a
5
5
  SHA512:
6
- metadata.gz: 3e9fbca039407baae857944739451a995303a8a67e1ca692266aaf2644cbd326114d22d1dcc0838dda68b6a569244276773145fbe6b5201c9da89ce1522dc221
7
- data.tar.gz: 3a188794e3bd013b64532385567a1fce8de60446dfd9a7d629dd414f5d86192e0838ab60a1c6fc1a7949f3b9f8557a1ff90b03e62d976dc21831673f79f80c57
6
+ metadata.gz: f89c8cdf4c90fd1586723fef2e89452a543694c2705e2343842493fc0217f42179304c4046a48c29bb0a2710a50c79b0a6dc13bcbe9b00523489abc13e2603ea
7
+ data.tar.gz: e32af5f2b0cbf6cf0e2637915e28640184f7f02bf88bbd3a7dcd6522aeb033a95d77928bae07581be592fa8076e19bc60b96367b306c0d5d940f4015ce049604
data/.rubocop.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  AllCops:
2
+ TargetRubyVersion: 2.1
2
3
  Exclude:
3
4
  - "*.gemspec"
4
5
 
data/.travis.yml CHANGED
@@ -2,4 +2,5 @@ language: ruby
2
2
  rvm:
3
3
  - 2.1
4
4
  - 2.2
5
+ - 2.3.0
5
6
  before_install: gem install bundler -v 1.10.4
data/CHANGELOG.md CHANGED
@@ -8,6 +8,13 @@ chandler is in a pre-1.0 state. This means that its APIs and behavior are subjec
8
8
 
9
9
  * Your contribution here!
10
10
 
11
+ ## [0.2.0][] (2016-02-19)
12
+
13
+ * Chandler now understands versions at Markdown/Rdoc h1-level headings (previously only h2 and h3 were searched).
14
+ * If Chandler can't find any version tags, print an error message rather than exiting silently.
15
+ * If Chandler can't find a version in your CHANGELOG, it will log a warning rather than exiting with an uncaught exception.
16
+ * Add `--tag-prefix` option to allow for other Git version tag formats (e.g. `myapp-v1.0.0`; see [#3](https://github.com/mattbrictson/chandler/issues/3))
17
+
11
18
  ## [0.1.2][] (2015-10-26)
12
19
 
13
20
  * Fix Windows test failures introduced in 0.1.1
@@ -21,6 +28,7 @@ chandler is in a pre-1.0 state. This means that its APIs and behavior are subjec
21
28
  * Initial release
22
29
 
23
30
  [Semver]: http://semver.org
24
- [Unreleased]: https://github.com/mattbrictson/chandler/compare/v0.1.2...HEAD
31
+ [Unreleased]: https://github.com/mattbrictson/chandler/compare/v0.2.0...HEAD
32
+ [0.2.0]: https://github.com/mattbrictson/chandler/compare/v0.1.2...v0.2.0
25
33
  [0.1.2]: https://github.com/mattbrictson/chandler/compare/v0.1.1...v0.1.2
26
34
  [0.1.1]: https://github.com/mattbrictson/chandler/compare/v0.1.0...v0.1.1
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015 Matt Brictson
3
+ Copyright (c) 2016 Matt Brictson
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -12,6 +12,8 @@
12
12
 
13
13
  chandler scans your git repository for version tags (e.g. `v1.0.2`), parses out the corresponding release notes for those tags from your CHANGELOG, and uploads those notes to the GitHub releases area via the GitHub API.
14
14
 
15
+ Chandler makes reasonable assumptions as to the name of your CHANGELOG file, your project's GitHub repository URL, and the naming convention of your Git version tags. These can all be overridden with command line options.
16
+
15
17
  ### Why go through the trouble?
16
18
 
17
19
  GitHub's releases feature is a nice UI for browsing the history of your project and downloading snapshots of each version. It is also structured data that can be queried via GitHub's API, making it a available for third-party integrations. For example, [Sibbell][] can automatically send the release notes out to interested parties whenever you publish a new version.
@@ -72,6 +74,7 @@ Other command-line options:
72
74
  * `--git=/path/to/project/.git` – location of the local git repository (defaults to `.git`)
73
75
  * `--github=username/repo` – GitHub repository to upload to (if unspecified, chandler will guess based on your git remotes)
74
76
  * `--changelog=History.md` – location of the CHANGELOG (defaults to `CHANGELOG.md`)
77
+ * `--tag-prefix=myapp-` – specify Git version tags are in the format `myapp-1.0.0` instead of `1.0.0`
75
78
 
76
79
 
77
80
  ## Rakefile integration
data/Rakefile CHANGED
@@ -3,13 +3,8 @@ require "rake/testtask"
3
3
  require "rubocop/rake_task"
4
4
 
5
5
  $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
6
- task "release:rubygem_push" do
7
- # Delay loading Chandler until this point, since it requires Ruby >= 2.1,
8
- # which may not be available in all environments (e.g. Travis).
9
- # We assume that the person doing `rake release` has Ruby >= 2.1.
10
- require "chandler/tasks"
11
- Rake.application.invoke_task("chandler:push")
12
- end
6
+ require "chandler/tasks"
7
+ task "release:rubygem_push" => "chandler:push"
13
8
 
14
9
  Rake::TestTask.new(:test) do |t|
15
10
  t.libs << "test"
data/chandler.gemspec CHANGED
@@ -29,5 +29,5 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency "minitest"
30
30
  spec.add_development_dependency "minitest-reporters"
31
31
  spec.add_development_dependency "mocha"
32
- spec.add_development_dependency "rubocop"
32
+ spec.add_development_dependency "rubocop", ">= 0.37.0"
33
33
  end
@@ -10,9 +10,11 @@ module Chandler
10
10
  NoMatchingVersion = Class.new(StandardError)
11
11
 
12
12
  HEADING_PATTERNS = [
13
- /^##[[:space:]]+.*\n/, # Markdown "atx" style
13
+ /^#[[:space:]]+.*\n/, # Markdown "atx" style
14
+ /^##[[:space:]]+.*\n/,
14
15
  /^###[[:space:]]+.*\n/,
15
- /^==[[:space:]]+.*\n/, # Rdoc style
16
+ /^=[[:space:]]+.*\n/, # Rdoc style
17
+ /^==[[:space:]]+.*\n/,
16
18
  /^===[[:space:]]+.*\n/,
17
19
  /^\S.*\n-+\n/ # Markdown "Setext" style
18
20
  ].freeze
@@ -32,10 +34,14 @@ module Chandler
32
34
  #
33
35
  def fetch(tag)
34
36
  versions.fetch(tag.version_number) do
35
- fail NoMatchingVersion, "Couldn’t find #{tag} in #{path}"
37
+ raise NoMatchingVersion, "Couldn’t find #{tag} in #{path}"
36
38
  end
37
39
  end
38
40
 
41
+ def basename
42
+ File.basename(path.to_s)
43
+ end
44
+
39
45
  private
40
46
 
41
47
  # Transforms the changelog into a hash where the keys are version numbers
@@ -45,19 +51,16 @@ module Chandler
45
51
  # The version numbers are assumed to be contained at Markdown or Rdoc
46
52
  # headings. The release notes for those version numbers are the text
47
53
  # delimited by those headings. The algorithm tries various styles of these
48
- # Markdown and Rdoc headings (see `HEADING_PATTERNS`) until it finds one
49
- # that matches.
54
+ # Markdown and Rdoc headings (see `HEADING_PATTERNS`).
50
55
  #
51
56
  # The resulting hash entries look like:
52
57
  # { "1.0.1" => "\nRelease notes for 1.0.1.\n" }
53
58
  #
54
59
  def versions
55
60
  @versions ||= begin
56
- versions = HEADING_PATTERNS.find do |heading_re|
57
- found = versions_at_headings(heading_re)
58
- break(found) unless found.empty?
61
+ HEADING_PATTERNS.reduce({}) do |found, heading_re|
62
+ versions_at_headings(heading_re).merge(found)
59
63
  end
60
- versions || {}
61
64
  end
62
65
  end
63
66
 
@@ -51,6 +51,11 @@ module Chandler
51
51
  config.changelog_path = p
52
52
  end
53
53
 
54
+ opts.on("--tag-prefix=[PREFIX]",
55
+ "Use PREFIX to identify Git version tags") do |p|
56
+ config.tag_prefix = p
57
+ end
58
+
54
59
  opts.on("--dry-run",
55
60
  "Simulate, but don’t actually push to GitHub") do |d|
56
61
  config.dry_run = d
@@ -1,6 +1,7 @@
1
1
  require "chandler/logging"
2
2
  require "chandler/refinements/color"
3
3
  require "chandler/refinements/version_format"
4
+ require "forwardable"
4
5
 
5
6
  module Chandler
6
7
  module Commands
@@ -8,6 +9,9 @@ module Chandler
8
9
  # from the CHANGELOG, and creates (or updates) the release notes for that
9
10
  # tag on GitHub.
10
11
  class Push
12
+ extend Forwardable
13
+ def_delegators :config, :github, :changelog, :tag_mapper
14
+
11
15
  include Logging
12
16
  using Chandler::Refinements::Color
13
17
  using Chandler::Refinements::VersionFormat
@@ -20,34 +24,44 @@ module Chandler
20
24
  end
21
25
 
22
26
  def call
23
- benchmarking_each_tag do |tag|
27
+ exit_with_warning if tags.empty?
28
+
29
+ each_tag_with_version_and_notes do |tag, version, notes|
24
30
  github.create_or_update_release(
25
31
  :tag => tag,
26
- :title => tag.version_number,
27
- :description => changelog.fetch(tag).strip
32
+ :title => version.version_number,
33
+ :description => notes
28
34
  )
29
35
  end
30
36
  end
31
37
 
32
38
  private
33
39
 
34
- def github
35
- config.github
36
- end
37
-
38
- def changelog
39
- config.changelog
40
- end
41
-
42
- def benchmarking_each_tag
40
+ def each_tag_with_version_and_notes
43
41
  width = tags.map(&:length).max
44
42
  tags.each do |tag|
43
+ version, notes = changelog_version_and_notes_for_tag(tag)
44
+ next if notes.nil?
45
+
45
46
  ellipsis = "…".ljust(1 + width - tag.length)
46
47
  benchmark("Push #{tag.blue}#{ellipsis}") do
47
- yield(tag)
48
+ yield(tag, version, notes)
48
49
  end
49
50
  end
50
51
  end
52
+
53
+ def exit_with_warning
54
+ error("No version tags found.")
55
+ exit(1)
56
+ end
57
+
58
+ def changelog_version_and_notes_for_tag(tag)
59
+ version = tag_mapper.call(tag)
60
+ [version, changelog.fetch(version).strip]
61
+ rescue Chandler::Changelog::NoMatchingVersion
62
+ info("Skip #{tag} (no #{version} entry in #{changelog.basename})".gray)
63
+ nil
64
+ end
51
65
  end
52
66
  end
53
67
  end
@@ -5,8 +5,8 @@ require "chandler/logger"
5
5
 
6
6
  module Chandler
7
7
  class Configuration
8
- attr_accessor :changelog_path, :git_path, :github_repository, :dry_run
9
- attr_accessor :logger
8
+ attr_accessor :changelog_path, :git_path, :github_repository, :dry_run,
9
+ :tag_prefix, :logger
10
10
 
11
11
  def initialize
12
12
  @changelog_path = "CHANGELOG.md"
@@ -20,7 +20,7 @@ module Chandler
20
20
  end
21
21
 
22
22
  def git
23
- @git ||= Chandler::Git.new(:path => git_path)
23
+ @git ||= Chandler::Git.new(:path => git_path, :tag_mapper => tag_mapper)
24
24
  end
25
25
 
26
26
  def github
@@ -35,5 +35,10 @@ module Chandler
35
35
  def github_repository
36
36
  @github_repository || git.origin_remote
37
37
  end
38
+
39
+ def tag_mapper
40
+ return ->(tag) { tag } if tag_prefix.nil?
41
+ ->(tag) { tag[/^#{Regexp.escape(tag_prefix)}(.*)/, 1] }
42
+ end
38
43
  end
39
44
  end
data/lib/chandler/git.rb CHANGED
@@ -7,15 +7,16 @@ module Chandler
7
7
  using Chandler::Refinements::VersionFormat
8
8
 
9
9
  Error = Class.new(StandardError)
10
- attr_reader :path
10
+ attr_reader :path, :tag_mapper
11
11
 
12
12
  # Initializes the Git object with the path to the `.git` directory of the
13
13
  # desired git repository.
14
14
  #
15
15
  # Chandler::Git.new(:path => "/path/to/my/project/.git")
16
16
  #
17
- def initialize(path:)
17
+ def initialize(path:, tag_mapper:)
18
18
  @path = path
19
+ @tag_mapper = tag_mapper
19
20
  end
20
21
 
21
22
  # Uses `git tag -l` to obtain the list of tags, then returns the subset of
@@ -23,12 +24,13 @@ module Chandler
23
24
  #
24
25
  # version_tags # => ["v0.0.1", "v0.2.0", "v0.2.1", "v0.3.0"]
25
26
  #
26
- # rubocop:disable Style/SymbolProc
27
27
  def version_tags
28
- tags = git("tag", "-l").lines.map(&:strip).select { |v| v.version? }
29
- tags.sort_by { |t| Gem::Version.new(t.version_number) }
28
+ tags = git("tag", "-l").lines.map(&:strip).select do |tag|
29
+ version_part = tag_mapper.call(tag)
30
+ version_part && version_part.version?
31
+ end
32
+ tags.sort_by { |t| Gem::Version.new(tag_mapper.call(t).version_number) }
30
33
  end
31
- # rubocop:enable Style/SymbolProc
32
34
 
33
35
  # Uses `git remote -v` to list the remotes and returns the URL of the
34
36
  # first one labeled "origin".
@@ -52,7 +54,7 @@ module Chandler
52
54
 
53
55
  message = "Failed to execute: #{args.join(' ')}"
54
56
  message << "\n#{err}" unless err.nil?
55
- fail Error, message
57
+ raise Error, message
56
58
  end
57
59
  end
58
60
  end
@@ -61,7 +61,7 @@ module Chandler
61
61
  message = "Couldn’t load GitHub credentials from ~/.netrc.\n"
62
62
  message << "For .netrc instructions, see: "
63
63
  message << "https://github.com/octokit/octokit.rb#using-a-netrc-file"
64
- fail MissingCredentials, message
64
+ raise MissingCredentials, message
65
65
  end
66
66
  end
67
67
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Chandler
2
- VERSION = "0.1.2"
3
+ VERSION = "0.2.0".freeze
3
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chandler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Brictson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-10-26 00:00:00.000000000 Z
11
+ date: 2016-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: netrc
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - ">="
130
130
  - !ruby/object:Gem::Version
131
- version: '0'
131
+ version: 0.37.0
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
- version: '0'
138
+ version: 0.37.0
139
139
  description:
140
140
  email:
141
141
  - chandler@mattbrictson.com
@@ -194,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
194
  version: '0'
195
195
  requirements: []
196
196
  rubyforge_project:
197
- rubygems_version: 2.4.8
197
+ rubygems_version: 2.5.1
198
198
  signing_key:
199
199
  specification_version: 4
200
200
  summary: Syncs CHANGELOG entries to GitHub's release notes