forkreadme 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1 +1,2 @@
1
1
  Gemfile.lock
2
+ *.gem
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Adam Mckaig
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,34 @@
1
+ This is a command-line utility for generating READMEs for GitHub forks.
2
+
3
+ I have quite a few forks of popular repos which contain no useful indication of
4
+ why they exist. Mostly they're hanging around waiting for a pull request to be
5
+ merged into or rejected from the upstream repo. And since my changes are tucked
6
+ away in feature branches, it's not immediately obvious to visitors (or me) why I
7
+ created the fork, what I changed, and whether those changes have been merged
8
+ upstream.
9
+
10
+ My solution is to replace the `README.md` in the master branch of my fork with a
11
+ note detailing what and why.
12
+ This tool does that automatically.
13
+
14
+
15
+ ## Usage
16
+
17
+ ```bash
18
+ $ gem install forkreadme
19
+ $ forkreadme generate
20
+ ```
21
+
22
+ Here's an [example of the output] [example].
23
+
24
+
25
+ ## License
26
+
27
+ [Fork README] [repo] is available under the [MIT license] [license].
28
+
29
+
30
+
31
+
32
+ [repo]: https://github.com/adammck/forkreadme
33
+ [license]: https://raw.github.com/adammck/forkreadme/master/LICENSE
34
+ [example]: https://github.com/adammck/grit
data/bin/forkreadme CHANGED
@@ -2,24 +2,29 @@
2
2
  # vim: et ts=2 sw=2
3
3
 
4
4
  require "forkreadme"
5
- require "thor"
6
-
7
- module ForkReadme
8
- class App < Thor
9
-
10
- desc "generate [DIR]", "Generate a README for a GitHub fork repo"
11
- method_option :path, :default=>"."
12
- def generate path=""
13
- begin
14
- dir = File.expand_path path, Dir.pwd
15
- puts Generator.new(dir).readme
16
-
17
- rescue ForkReadme::Error => err
18
- $stderr.puts err
19
- exit false
20
- end
21
- end
22
- end
5
+ require "trollop"
6
+
7
+ BANNER = <<EOT
8
+ ForkReadme generates a README.md for GitHub forks, containing a list of the pull requests submitted upstream.
9
+
10
+ Usage:
11
+ forkreadme [options] [path]
12
+
13
+ Options:
14
+ EOT
15
+
16
+ opts = Trollop::options do
17
+ banner BANNER
18
+ opt :pullstatus, "Include pullstat.us images", :short=>"i", :type=>:bool, :default=>true
23
19
  end
24
20
 
25
- ForkReadme::App.start
21
+ path = ARGV.shift || "."
22
+
23
+ begin
24
+ dir = File.expand_path path, Dir.pwd
25
+ puts ForkReadme::Generator.new(dir, opts[:pullstatus]).readme
26
+
27
+ rescue ForkReadme::Error => err
28
+ $stderr.puts err
29
+ exit false
30
+ end
data/forkreadme.gemspec CHANGED
@@ -6,13 +6,14 @@ require File.expand_path("../lib/forkreadme/version", __FILE__)
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = "forkreadme"
8
8
  gem.version = ForkReadme::VERSION
9
+ gem.license = "MIT"
9
10
 
10
11
  gem.authors = ["Adam Mckaig"]
11
12
  gem.email = ["adam.mckaig@gmail.com"]
12
13
  gem.summary = %q{Generate useful READMEs for GitHub forks}
13
14
  gem.homepage = "https://github.com/adammck/forkreadme"
14
15
 
15
- gem.add_dependency "thor", "~> 0.14.6"
16
+ gem.add_dependency "trollop", "~> 1.16.2"
16
17
  gem.add_dependency "octokit", "~> 1.0.2"
17
18
 
18
19
  gem.files = `git ls-files`.split($\)
@@ -4,10 +4,13 @@
4
4
  module ForkReadme
5
5
  class Error < StandardError
6
6
  end
7
-
8
- class NotRepo < Error
7
+
8
+ class NotGitRepo < Error
9
+ end
10
+
11
+ class NotGitHubRepo < Error
9
12
  end
10
-
13
+
11
14
  class NotFork < Error
12
15
  end
13
16
  end
@@ -8,56 +8,83 @@ module ForkReadme
8
8
  class Generator
9
9
  include URI::REGEXP::PATTERN
10
10
 
11
- def initialize dir
12
- @dir = dir
11
+ def initialize path, with_images
12
+ @path = path
13
+ @with_images = with_images
14
+
15
+ repo_name = github_repo_name @path
16
+ @repo = octokit.repo repo_name
17
+ @parent = parent_of @repo
13
18
  end
14
19
 
15
20
  def readme
16
- repo_name = github_repo_name @dir
21
+ intro + "\n\n" + (links.join "\n")
22
+ end
17
23
 
18
- if repo_name.empty?
19
- raise NotRepo.new "Not a GitHub repo: #{@dir}"
20
- end
24
+ # Public: Returns the introduction paragraph.
25
+ def intro
26
+ link = link_to(@parent.name, @parent.html_url)
27
+ "This is a fork of #{link}, with pull requests:"
28
+ end
21
29
 
22
- repo = octokit.repo repo_name
30
+ # Public: Returns a paragraph summarizing the pull requests.
31
+ def links
32
+ pull_requests(@parent).select do |pull|
33
+ pull.head.repo.id == @repo.id
23
34
 
24
- unless repo.fork
25
- raise NotFork.new "Not a GitHub fork: #{repo_name}"
35
+ end.map do |pull|
36
+ "* " + line_for(pull, @with_images)
26
37
  end
38
+ end
27
39
 
28
- parent_name = full_name repo.parent
29
- parent = octokit.repo parent_name
30
-
31
- s = []
32
- s << "This is a fork of [#{parent.name}] (#{parent.html_url}), with pull requests:"
33
- s << ""
40
+ private
34
41
 
35
- logins = collaborator_logins repo
36
- my_pulls = pull_requests(parent).select do |pull|
37
- pull.user and logins.include?(pull.user.login)
42
+ # Private: Returns a line of Markdown summarizing a pull request.
43
+ def line_for pull_request, with_images
44
+ img = if with_images
45
+ image "Status of ##{pull_request.number}", status_image(pull_request)
38
46
  end
39
47
 
40
- my_pulls.each do |short_pull|
41
- pull = pull_request(parent, short_pull.number)
42
- if repo_name == full_name(pull.head.repo)
43
- s << " * [#{pull.title}] (#{pull.html_url})"
44
- end
48
+ suffix = img ? (" " + img) : ""
49
+ link_to(pull_request.title, pull_request.html_url) + suffix
50
+ end
51
+
52
+ # Private: Returns the parent repo (as an Octokit repo) of an Octokit repo,
53
+ # or raises NotFork if the repo does not have a parent.
54
+ def parent_of child_repo
55
+ if child_repo.parent
56
+ parent_repo_name = full_name child_repo.parent
57
+ octokit.repo parent_repo_name
58
+ else
59
+ child_name = full_name child_repo
60
+ raise NotFork.new "Not a GitHub fork: #{child_name}"
45
61
  end
62
+ end
46
63
 
47
- s.join "\n"
64
+ # Private: Returns a link in Markdown format.
65
+ def link_to text, href
66
+ "[#{text}] (#{href})"
48
67
  end
49
-
50
-
51
- private
52
-
53
- # Private: Returns an Array containing the logins of all collaborators for an
54
- # Octokit repo.
68
+
69
+ # Private: Returns an image in Markdown format.
70
+ def image alt_text, href
71
+ "!" + link_to(alt_text, href)
72
+ end
73
+
74
+ # Private: Returns an Array containing the logins of all collaborators for
75
+ # an Octokit repo.
55
76
  def collaborator_logins repo
56
77
  octokit.collabs(full_name repo).map do |user|
57
78
  user.login
58
79
  end
59
80
  end
60
-
81
+
82
+ # Private: Returns the URL of the status image (via pullstat.us) for an
83
+ # Octokit pull request.
84
+ def status_image pull_request
85
+ pull_request.html_url.sub "github.com", "pullstat.us"
86
+ end
87
+
61
88
  # Private: Returns all pull request summaries (as returned by the "List pull
62
89
  # requests" API, and wrapped by Octokit) for an Octokit repo.
63
90
  def pull_requests repo
@@ -68,16 +95,16 @@ module ForkReadme
68
95
  end
69
96
  end
70
97
 
71
- # Private: Return full pull request (as returned by the "Get a single pull
72
- # request" API, and wrapped by Octokit) to an Octokit repo and pull number.
73
- def pull_request repo, number
74
- octokit.pull full_name(repo), number
75
- end
76
-
77
- # Private: Returns the full GitHub repo name of a Git working directory.
98
+ # Private: Returns the full GitHub repo name (e.g. adammck/forkreadme) of a
99
+ # Git working directory, or raises NotGitHubRepo.
78
100
  def github_repo_name path
79
101
  clone_url = parse_url remote_url path
80
- chop_extension clone_url.path
102
+
103
+ if clone_url.host.downcase != "github.com"
104
+ raise NotGitHubRepo.new "Not a GitHub repo: #{path}"
105
+ end
106
+
107
+ chop_extension chop_leading_slash clone_url.path
81
108
  end
82
109
 
83
110
  # Private: Returns the full GitHub repo name of an Octokit repo.
@@ -90,8 +117,13 @@ module ForkReadme
90
117
  @ok ||= Octokit.new(:auto_traversal=>true)
91
118
  end
92
119
 
93
- # Private: Returns the remote url of a Git working directory.
120
+ # Private: Returns the remote clone URL of a Git working directory, or
121
+ # raises NotGitRepo.
94
122
  def remote_url path
123
+ unless is_working_dir path
124
+ raise NotGitRepo.new "Not a Git repo: #{path}"
125
+ end
126
+
95
127
  %x{git config --file #{path}/.git/config --get remote.origin.url}
96
128
  end
97
129
 
@@ -103,17 +135,27 @@ module ForkReadme
103
135
 
104
136
  rescue URI::InvalidURIError
105
137
  if m = url.match("^(#{USERINFO})@(#{HOST}):(#{REL_PATH})$")
106
- URI::Generic.new "ssh", m[1], m[2], 22, nil, m[3], nil, nil, nil
138
+ URI::Generic.new "ssh", m[1], m[2], 22, nil, "/" + m[3], nil, nil, nil
107
139
 
108
140
  else
109
141
  raise
110
142
  end
111
143
  end
112
144
  end
113
-
145
+
146
+ # Private: Return true if +path+ is a Git working directory.
147
+ def is_working_dir path
148
+ File.exist? File.expand_path ".git", path
149
+ end
150
+
114
151
  # Private: Returns a filename with the extension removed.
115
152
  def chop_extension filename
116
153
  filename.sub /\.\w+$/, ""
117
154
  end
155
+
156
+ # Private: Returns a filename with the leading slash removed.
157
+ def chop_leading_slash filename
158
+ filename.sub /^\//, ""
159
+ end
118
160
  end
119
161
  end
@@ -2,5 +2,5 @@
2
2
  # vim: et ts=2 sw=2
3
3
 
4
4
  module ForkReadme
5
- VERSION = "0.0.1"
5
+ VERSION = "0.0.2"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forkreadme
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,27 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-26 00:00:00.000000000 Z
12
+ date: 2012-05-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: thor
16
- requirement: &70204084253700 !ruby/object:Gem::Requirement
15
+ name: trollop
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 0.14.6
21
+ version: 1.16.2
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70204084253700
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.16.2
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: octokit
27
- requirement: &70204084253100 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ~>
@@ -32,7 +37,12 @@ dependencies:
32
37
  version: 1.0.2
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *70204084253100
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.0.2
36
46
  description:
37
47
  email:
38
48
  - adam.mckaig@gmail.com
@@ -43,6 +53,8 @@ extra_rdoc_files: []
43
53
  files:
44
54
  - .gitignore
45
55
  - Gemfile
56
+ - LICENSE
57
+ - README.md
46
58
  - bin/forkreadme
47
59
  - forkreadme.gemspec
48
60
  - lib/forkreadme.rb
@@ -50,7 +62,8 @@ files:
50
62
  - lib/forkreadme/generator.rb
51
63
  - lib/forkreadme/version.rb
52
64
  homepage: https://github.com/adammck/forkreadme
53
- licenses: []
65
+ licenses:
66
+ - MIT
54
67
  post_install_message:
55
68
  rdoc_options: []
56
69
  require_paths:
@@ -69,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
82
  version: '0'
70
83
  requirements: []
71
84
  rubyforge_project:
72
- rubygems_version: 1.8.15
85
+ rubygems_version: 1.8.23
73
86
  signing_key:
74
87
  specification_version: 3
75
88
  summary: Generate useful READMEs for GitHub forks