pronto 0.4.3 → 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1c969116e9f09a05199f174e918f6d1d2f585ee9
4
- data.tar.gz: ceade9cb751655a96c08a7ace4c333612bf12632
3
+ metadata.gz: c6eced888221992765e7822d10cc30c5bb425807
4
+ data.tar.gz: 3691ca0e624f99993eff02d044fc76dc8f13b633
5
5
  SHA512:
6
- metadata.gz: 8a49323ec0df4da0d1aa3a5b0698ec9396d1aa1281043420914ce7637158d1b6b0d645747508f93dd95a9142923aff2b6fadcdef04b503e2b3f62fa120a4b711
7
- data.tar.gz: 0580f948b0456f33ff48319b09fd1e572bc19beea2f255b94a62a39d9041d3fa7906cd804a364c4ee3876493f8cf9553883d6f00a3705051454d6041e8b8b65e
6
+ metadata.gz: 502260ec324f87bda046de5c75313abc8a48a2dc29c9c9f5339820ad40c683e1150e80013f9c5864b9f003a601759fcadfc99458fcb9424bf095aea02a0d4882
7
+ data.tar.gz: 640af0dbfe133fa024ccd924ccd9496011a32d5001bb076a692ac9e833a36b3bbeeb5caa857ef33600f9e1c0929e221899827a1f42d5c4ecd608446651cd84c9
data/CHANGELOG.md ADDED
@@ -0,0 +1,93 @@
1
+ # Changelog
2
+
3
+ ## Unreleased
4
+
5
+ ### New features
6
+ ### Changes
7
+ ### Bugs fixed
8
+
9
+ ## 0.5.0
10
+
11
+ ### New features
12
+
13
+ * [#104](https://github.com/mmozuras/pronto/pull/104): configure via .pronto.yml file.
14
+ * [#86](https://github.com/mmozuras/pronto/pull/86): ability to specify GitHub slug via configuration or environment variable.
15
+ * [#77](https://github.com/mmozuras/pronto/pull/77): ability to specify GitHub endpoints via configuration or environment variable.
16
+ * [#108](https://github.com/mmozuras/pronto/pull/108): ability to specify excluded files via configuration.
17
+
18
+ ### Changes
19
+
20
+ * [#82](https://github.com/mmozuras/pronto/pull/82): treat Rake files as Ruby files.
21
+ * [#107](https://github.com/mmozuras/pronto/pull/107): use desc: instead of banner: for CLI options descriptions.
22
+
23
+ ### Bugs fixed
24
+
25
+ * [#87](https://github.com/mmozuras/pronto/pull/87): handle github remote urls without .git suffix.
26
+ * [#91](https://github.com/mmozuras/pronto/pull/91): find position in full diff and fix how commit id is used in GithubPullRequestFormatter.
27
+ * [#92](https://github.com/mmozuras/pronto/pull/92): ignore failed pull request comments.
28
+ * [#93](https://github.com/mmozuras/pronto/pull/93): comments didn't have position when outdated.
29
+ * [#94](https://github.com/mmozuras/pronto/pull/94): duplicate comment detection was failing for large GitHub pull requests.
30
+ * [poper#4](https://github.com/mmozuras/pronto-poper/issues/4): handle message uniqueness when they're without line numbers.
31
+ * [#101](https://github.com/mmozuras/pronto/pull/101): make GitLab work with ssh port urls.
32
+
33
+ ## 0.4.3
34
+
35
+ ### Changes
36
+
37
+ * Depend on `rugged ~> 0.23.0` and `octokit ~> 4.1.0`.
38
+
39
+ ## 0.4.2
40
+
41
+ ### New features
42
+
43
+ * New formatter: NullFormatter. Discards data without writing it anywhere.
44
+
45
+ ## 0.4.1
46
+
47
+ ### Bugs fixed
48
+
49
+ * [#58](https://github.com/mmozuras/pronto/pull/58): GitlabFormatter uses a high +per_page+ value to avoid pagination (and thus duplicate comments).
50
+
51
+ ## 0.4.0
52
+
53
+ ### New features
54
+
55
+ * Try to detect pull request id automatically, if `PULL_REQUEST_ID` is not specified. Inspired by @willnet/prid.
56
+ * [#40](https://github.com/mmozuras/pronto/issues/40): add '--index' option for 'pronto run'. Pronto analyzes changes before committing.
57
+ * [#50](https://github.com/mmozuras/pronto/pull/50): add GitLab formatter
58
+ * [#52](https://github.com/mmozuras/pronto/pull/52): allow specifying a path for 'pronto run'.
59
+
60
+ ### Changes
61
+
62
+ * GitHub and GitHub pull request formatters now filter out duplicate offenses on the same line to avoid spamming with redundant comments.
63
+
64
+ ## 0.3.3
65
+
66
+ ### Bugs fixed
67
+
68
+ * GithubPullRequestFormatter was working incorrectly with merge commits.
69
+
70
+ ## 0.3.2
71
+
72
+ ### Bugs fixed
73
+
74
+ * GithubPullRequestFormatter had an off-by-one positioning error.
75
+
76
+ ## 0.3.1
77
+
78
+ ### Bugs fixed
79
+
80
+ * Git::Patches#repo was always returning nil.
81
+
82
+ ## 0.3.0
83
+
84
+ ### New features
85
+
86
+ * [#27](https://github.com/mmozuras/pronto/issues/27): '--exit-code' option for 'pronto run'. Pronto exits with non-zero code if there were any warnings/errors.
87
+ * [#16](https://github.com/mmozuras/pronto/issues/16): new formatter: GithubPullRequestFormatter. Writes review comments on GitHub pull requests.
88
+
89
+ ### Changes
90
+
91
+ * [#29](https://github.com/mmozuras/pronto/issues/29): be compatible and depend on rugged '0.21.0'.
92
+ * Performance improvement: use Rugged::Blame instead of one provided by Grit.
93
+ * Performance improvement: cache comments retrieved from GitHub.
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,32 @@
1
+ # Contributing
2
+
3
+ If you discover issues, have ideas for improvements or new features,
4
+ please report them to the [issue tracker][1] of the repository or
5
+ submit a pull request. Please, try to follow these guidelines when you
6
+ do so.
7
+
8
+ ## Issue reporting
9
+
10
+ * Check that the issue has not already been reported.
11
+ * Check that the issue has not already been fixed in the latest code
12
+ (a.k.a. `master`).
13
+ * Be clear, concise and precise in your description of the problem.
14
+ * Open an issue with a descriptive title and a summary in grammatically correct,
15
+ complete sentences.
16
+ * Include any relevant code or traces in the issue summary.
17
+
18
+ ## Pull requests
19
+
20
+ * Read [how to properly contribute to open source projects on Github][2].
21
+ * Fork the project.
22
+ * Use a topic/feature branch to easily amend a pull request later, if necessary.
23
+ * Write [good commit messages][3].
24
+ * Use the same coding conventions as the rest of the project.
25
+ * Commit and push until you are happy with your contribution.
26
+ * Open a [pull request][4] that relates to *only* one subject with a clear title
27
+ and description in grammatically correct, complete sentences.
28
+
29
+ [1]: https://github.com/mmozuras/pronto/issues
30
+ [2]: http://gun.io/blog/how-to-github-fork-branch-and-pull-request
31
+ [3]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
32
+ [4]: https://help.github.com/articles/using-pull-requests
data/README.md CHANGED
@@ -13,6 +13,13 @@ to your [styleguide](https://github.com/mmozuras/pronto-rubocop), [are DRY](http
13
13
 
14
14
  ![Pronto demo](pronto.gif "")
15
15
 
16
+ * [Usage](#usage)
17
+ * [Local Changes](#local-changes)
18
+ * [GitHub Integration](#github-integration)
19
+ * [GitLab Integration](#gitlab-integration)
20
+ * [Configuration](#configuration)
21
+ * [Runners](#runners)
22
+
16
23
  ## Usage
17
24
 
18
25
  Pronto runs the checks on a diff between the current HEAD and the provided commit-ish (default is master).
@@ -40,6 +47,16 @@ pronto run --commit=$(git log --pretty=format:%H | tail -1)
40
47
 
41
48
  Just run `pronto` without any arguments to see what Pronto is capable of.
42
49
 
50
+ Available Options
51
+
52
+ Command flag | Description
53
+ -----------------|------------------------------------------------------------
54
+ `--exit-code` | Exits with non-zero code if there were any warnings/errors.
55
+ `-c/--commit` | Commit for the diff.
56
+ `-i/--index` | Analyze changes in git index (staging area).
57
+ `-r/--runner` | Run only the passed runners.
58
+ `-f/--formatter` | Pick output formatter.
59
+
43
60
  ### GitHub Integration
44
61
 
45
62
  You can run Pronto as a step of your CI builds and get the results as comments
@@ -57,8 +74,8 @@ s.add_development_dependency 'pronto'
57
74
  s.add_development_dependency 'pronto-rubocop'
58
75
  s.add_development_dependency 'pronto-scss'
59
76
  ```
60
- Set the GITHUB_ACCESS_TOKEN environment variable to [OAuth token](https://help.github.com/articles/creating-an-access-token-for-command-line-use)
61
- that has access to the repository.
77
+ Set the GITHUB_ACCESS_TOKEN environment variable or value in `.pronto.yml` to
78
+ [OAuth token](https://help.github.com/articles/creating-an-access-token-for-command-line-use) that has access to the repository.
62
79
 
63
80
  Then just run it:
64
81
  ```bash
@@ -97,10 +114,11 @@ s.add_development_dependency 'pronto-rubocop'
97
114
  s.add_development_dependency 'pronto-scss'
98
115
  ```
99
116
 
100
- Set the `GITLAB_API_ENDPOINT` environment variable to your API endpoint URL.
101
- If you are using Gitlab.com's hosted service your endpoint will be `https://gitlab.com/api/v3`.
102
- Set the `GITLAB_API_PRIVATE_TOKEN` environment variable to your Gitlab private token
103
- which you can find in your account settings.
117
+ Set the `GITLAB_API_ENDPOINT` environment variable or value in `.pronto.yml` to
118
+ your API endpoint URL. If you are using Gitlab.com's hosted service your
119
+ endpoint will be `https://gitlab.com/api/v3`.
120
+ Set the `GITLAB_API_PRIVATE_TOKEN` environment variable or value in `.pronto.yml
121
+ to your Gitlab private token which you can find in your account settings.
104
122
 
105
123
  Then just run it:
106
124
  ```bash
@@ -115,6 +133,32 @@ formatter = Pronto::Formatter::GitlabFormatter.new
115
133
  Pronto.run('origin/master', '.', formatter)
116
134
  ```
117
135
 
136
+ ## Configuration
137
+
138
+ The behavior of Pronto can be controlled via the `.pronto.yml` configuration
139
+ file. It must be placed in your project directory.
140
+
141
+ The file has the following format:
142
+
143
+ ```yaml
144
+ all:
145
+ exclude: rspec/*
146
+ github:
147
+ slug: mmozuras/pronto
148
+ access_token: B26354
149
+ api_endpoint: https://api.github.com/
150
+ web_endpoint: https://github.com/
151
+ gitlab:
152
+ slug: mmozuras/pronto,
153
+ api_private_token: 46751,
154
+ api_endpoint: https://api.vinted.com/gitlab
155
+ ```
156
+
157
+ All properties that can be specified via `.pronto.yml`, can also be specified
158
+ via environment variables. Their names will be the upcased path to the property.
159
+ For example: `GITHUB_SLUG` or `GITLAB_API_PRIVATE_TOKEN`. Environment variables
160
+ will always take precedence over values in configuration file.
161
+
118
162
  ## Runners
119
163
 
120
164
  Pronto can run various tools and libraries, as long as there's a runner for it.
@@ -122,12 +166,14 @@ Currently available:
122
166
 
123
167
  * [pronto-brakeman](https://github.com/mmozuras/pronto-brakeman)
124
168
  * [pronto-coffeelint](https://github.com/siebertm/pronto-coffeelint)
169
+ * [pronto-fasterer](https://github.com/mmozuras/pronto-fasterer)
125
170
  * [pronto-flay](https://github.com/mmozuras/pronto-flay)
126
171
  * [pronto-foodcritic](https://github.com/mmozuras/pronto-foodcritic)
127
172
  * [pronto-jshint](https://github.com/mmozuras/pronto-jshint)
128
173
  * [pronto-haml](https://github.com/mmozuras/pronto-haml)
129
174
  * [pronto-poper](https://github.com/mmozuras/pronto-poper)
130
175
  * [pronto-rails_best_practices](https://github.com/mmozuras/pronto-rails_best_practices)
176
+ * [pronto-rails_schema](https://github.com/raimondasv/pronto-rails_schema)
131
177
  * [pronto-reek](https://github.com/mmozuras/pronto-reek)
132
178
  * [pronto-rubocop](https://github.com/mmozuras/pronto-rubocop)
133
179
  * [pronto-scss](https://github.com/mmozuras/pronto-scss)
data/lib/pronto.rb CHANGED
@@ -3,6 +3,9 @@ require 'octokit'
3
3
  require 'gitlab'
4
4
  require 'forwardable'
5
5
 
6
+ require 'pronto/config_file'
7
+ require 'pronto/config'
8
+
6
9
  require 'pronto/git/repository'
7
10
  require 'pronto/git/patches'
8
11
  require 'pronto/git/patch'
@@ -11,6 +14,7 @@ require 'pronto/git/line'
11
14
  require 'pronto/plugin'
12
15
  require 'pronto/message'
13
16
  require 'pronto/runner'
17
+ require 'pronto/runners'
14
18
  require 'pronto/github'
15
19
  require 'pronto/gitlab'
16
20
 
@@ -32,9 +36,9 @@ module Pronto
32
36
  options = { paths: [file] } if file
33
37
  patches = repo.diff(commit, options)
34
38
 
35
- result = run_all_runners(patches)
39
+ result = Runners.new.run(patches)
36
40
 
37
- formatted = formatter.format(result, repo)
41
+ formatted = formatter.format(result, repo, patches)
38
42
  puts formatted if formatted
39
43
 
40
44
  result
@@ -50,16 +54,6 @@ module Pronto
50
54
  end
51
55
  end
52
56
 
53
- gems.map { |gem| gem.name.sub(/^pronto-/, '') }
54
- .uniq
55
- .sort
56
- end
57
-
58
- private
59
-
60
- def self.run_all_runners(patches)
61
- Runner.runners.map do |runner|
62
- runner.new.run(patches, patches.commit)
63
- end.flatten.compact
57
+ gems.map { |gem| gem.name.sub(/^pronto-/, '') }.uniq.sort
64
58
  end
65
59
  end
data/lib/pronto/cli.rb CHANGED
@@ -16,30 +16,30 @@ module Pronto
16
16
 
17
17
  method_option :'exit-code',
18
18
  type: :boolean,
19
- banner: 'Exits with non-zero code if there were any warnings/errors.'
19
+ desc: 'Exits with non-zero code if there were any warnings/errors.'
20
20
 
21
21
  method_option :commit,
22
22
  type: :string,
23
23
  default: 'master',
24
24
  aliases: '-c',
25
- banner: 'Commit for the diff'
25
+ desc: 'Commit for the diff'
26
26
 
27
27
  method_option :index,
28
28
  type: :boolean,
29
29
  aliases: '-i',
30
- banner: 'Analyze changes in git index (staging area)'
30
+ desc: 'Analyze changes in git index (staging area)'
31
31
 
32
32
  method_option :runner,
33
33
  type: :array,
34
34
  default: [],
35
35
  aliases: '-r',
36
- banner: 'Run only the passed runners'
36
+ desc: 'Run only the passed runners'
37
37
 
38
38
  method_option :formatter,
39
39
  type: :string,
40
40
  default: 'text',
41
41
  aliases: '-f',
42
- banner: "Pick output formatter. Available: #{::Pronto::Formatter.names.join(', ')}"
42
+ desc: "Pick output formatter. Available: #{::Pronto::Formatter.names.join(', ')}"
43
43
 
44
44
  def run(path = nil)
45
45
  gem_names = options[:runner].any? ? options[:runner] : ::Pronto.gem_names
@@ -0,0 +1,30 @@
1
+ module Pronto
2
+ class Config
3
+ def initialize(config_hash = ConfigFile.new.to_h)
4
+ @config_hash = config_hash
5
+ end
6
+
7
+ %w(github gitlab).each do |service|
8
+ ConfigFile::EMPTY[service].each do |key, _|
9
+ name = "#{service}_#{key}"
10
+ define_method(name) { ENV[name.upcase] || @config_hash[service][key] }
11
+ end
12
+ end
13
+
14
+ def excluded_files
15
+ @excluded_files ||= Array(exclude)
16
+ .flat_map { |path| Dir[path.to_s] }
17
+ .map { |path| File.expand_path(path) }
18
+ end
19
+
20
+ def github_hostname
21
+ URI.parse(github_web_endpoint).host
22
+ end
23
+
24
+ private
25
+
26
+ def exclude
27
+ @config_hash['all']['exclude']
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,46 @@
1
+ module Pronto
2
+ class ConfigFile
3
+ EMPTY = {
4
+ 'all' => {
5
+ 'exclude' => [],
6
+ 'include' => []
7
+ },
8
+ 'github' => {
9
+ 'slug' => nil,
10
+ 'access_token' => nil,
11
+ 'api_endpoint' => 'https://api.github.com/',
12
+ 'web_endpoint' => 'https://github.com/'
13
+ },
14
+ 'gitlab' => {
15
+ 'slug' => nil,
16
+ 'api_private_token' => nil,
17
+ 'api_endpoint' => nil
18
+ },
19
+ 'runners' => [],
20
+ 'formatters' => []
21
+ }
22
+
23
+ def initialize(path = '.pronto.yml')
24
+ @path = path
25
+ end
26
+
27
+ def to_h
28
+ hash = File.exist?(@path) ? YAML.load_file(@path) : {}
29
+ deep_merge(hash)
30
+ end
31
+
32
+ private
33
+
34
+ def deep_merge(hash)
35
+ merger = proc do |_, oldval, newval|
36
+ if oldval.is_a?(Hash) && newval.is_a?(Hash)
37
+ oldval.merge(newval, &merger)
38
+ else
39
+ oldval || newval
40
+ end
41
+ end
42
+
43
+ hash.merge(EMPTY, &merger)
44
+ end
45
+ end
46
+ end
@@ -7,7 +7,7 @@ module Pronto
7
7
  @output = ''
8
8
  end
9
9
 
10
- def format(messages, _)
10
+ def format(messages, _, _)
11
11
  open_xml
12
12
  process_messages(messages)
13
13
  close_xml
@@ -1,11 +1,10 @@
1
1
  module Pronto
2
2
  module Formatter
3
3
  class GithubFormatter
4
- def format(messages, repo)
5
- messages = messages.uniq { |message| [message.msg, message.line.new_lineno] }
4
+ def format(messages, repo, _)
6
5
  client = Github.new(repo)
7
6
 
8
- commit_messages = messages.map do |message|
7
+ commit_messages = messages.uniq.map do |message|
9
8
  sha = message.commit_sha
10
9
  body = message.msg
11
10
  path = message.path
@@ -1,24 +1,16 @@
1
1
  module Pronto
2
2
  module Formatter
3
3
  class GithubPullRequestFormatter
4
- def format(messages, repo)
5
- messages = messages.uniq { |message| [message.msg, message.line.new_lineno] }
4
+ def format(messages, repo, patches)
6
5
  client = Github.new(repo)
6
+ head = repo.head_commit_sha
7
7
 
8
- commit_messages = messages.map do |message|
8
+ commit_messages = messages.uniq.map do |message|
9
9
  body = message.msg
10
10
  path = message.path
11
+ line = patches.find_line(message.full_path, message.line.new_lineno)
11
12
 
12
- commits = repo.commits_until(message.commit_sha)
13
-
14
- line = nil
15
- sha = commits.find do |commit|
16
- patches = repo.show_commit(commit)
17
- line = patches.find_line(message.full_path, message.line.new_lineno)
18
- line
19
- end
20
-
21
- create_comment(client, sha, body, path, line.position)
13
+ create_comment(client, head, body, path, line.position)
22
14
  end
23
15
 
24
16
  "#{commit_messages.compact.count} Pronto messages posted to GitHub"
@@ -31,6 +23,13 @@ module Pronto
31
23
  comments = client.pull_comments(sha)
32
24
  existing = comments.any? { |c| comment == c }
33
25
  client.create_pull_comment(comment) unless existing
26
+ rescue Octokit::UnprocessableEntity => e
27
+ # The diff output of the local git version and Github is not always
28
+ # consistent, especially in areas where file renames happened, Github
29
+ # tends to recognize these better, leading to messages we can't post
30
+ # because their diff position is non-existent on Github.
31
+ # Ignore such occasions and continue posting other messages.
32
+ STDERR.puts "Failed to post: #{comment.inspect} with #{e.message}"
34
33
  end
35
34
  end
36
35
  end
@@ -1,11 +1,10 @@
1
1
  module Pronto
2
2
  module Formatter
3
3
  class GitlabFormatter
4
- def format(messages, repo)
5
- messages = messages.uniq { |message| [message.msg, message.line.new_lineno] }
4
+ def format(messages, repo, _)
6
5
  client = Gitlab.new repo
7
6
 
8
- commit_messages = messages.map do |message|
7
+ commit_messages = messages.uniq.map do |message|
9
8
  create_comment(client,
10
9
  message.commit_sha,
11
10
  message.msg,
@@ -3,7 +3,7 @@ require 'json'
3
3
  module Pronto
4
4
  module Formatter
5
5
  class JsonFormatter
6
- def format(messages, _)
6
+ def format(messages, _, _)
7
7
  messages.map do |message|
8
8
  lineno = message.line.new_lineno if message.line
9
9
 
@@ -1,7 +1,7 @@
1
1
  module Pronto
2
2
  module Formatter
3
3
  class NullFormatter
4
- def format(_, _)
4
+ def format(_, _, _)
5
5
  end
6
6
  end
7
7
  end
@@ -1,18 +1,23 @@
1
1
  module Pronto
2
2
  module Formatter
3
3
  class TextFormatter
4
- def format(messages, _)
4
+ def format(messages, _, _)
5
5
  messages.map do |message|
6
6
  level = message.level[0].upcase
7
- line = message.line
8
- lineno = line.new_lineno if line
9
- path = message.path
10
- commit_sha = message.commit_sha[0..6] if message.commit_sha
11
-
12
- location = (path.nil? && lineno.nil?) ? commit_sha : "#{path}:#{lineno}"
13
- "#{location} #{level}: #{message.msg}"
7
+ "#{location(message)} #{level}: #{message.msg}"
14
8
  end
15
9
  end
10
+
11
+ private
12
+
13
+ def location(message)
14
+ line = message.line
15
+ lineno = line.new_lineno if line
16
+ path = message.path
17
+ commit_sha = message.commit_sha[0..6] if message.commit_sha
18
+
19
+ (path.nil? && lineno.nil?) ? commit_sha : "#{path}:#{lineno}"
20
+ end
16
21
  end
17
22
  end
18
23
  end
@@ -28,6 +28,9 @@ module Pronto
28
28
  end
29
29
 
30
30
  def ==(other)
31
+ return false if other.nil?
32
+ return true if line.nil? && other.line.nil?
33
+
31
34
  content == other.content &&
32
35
  line_origin == other.line_origin &&
33
36
  old_lineno == other.old_lineno &&
@@ -15,6 +15,10 @@ module Pronto
15
15
  @patches.each(&block)
16
16
  end
17
17
 
18
+ def reject!(&block)
19
+ @patches.reject!(&block)
20
+ end
21
+
18
22
  def find_line(path, line)
19
23
  patch = find { |p| p.new_file_full_path == path }
20
24
  lines = patch ? patch.lines : []
@@ -58,6 +58,10 @@ module Pronto
58
58
  @repo.remotes.map(&:url)
59
59
  end
60
60
 
61
+ def head_commit_sha
62
+ head.oid
63
+ end
64
+
61
65
  private
62
66
 
63
67
  def empty_patches(sha)
data/lib/pronto/github.rb CHANGED
@@ -2,6 +2,7 @@ module Pronto
2
2
  class Github
3
3
  def initialize(repo)
4
4
  @repo = repo
5
+ @config = Config.new
5
6
  @comment_cache = {}
6
7
  @pull_id_cache = {}
7
8
  end
@@ -9,7 +10,8 @@ module Pronto
9
10
  def pull_comments(sha)
10
11
  @comment_cache["#{pull_id}/#{sha}"] ||= begin
11
12
  client.pull_comments(slug, pull_id).map do |comment|
12
- Comment.new(sha, comment.body, comment.path, comment.position)
13
+ Comment.new(sha, comment.body, comment.path,
14
+ comment.position || comment.original_position)
13
15
  end
14
16
  end
15
17
  end
@@ -35,16 +37,21 @@ module Pronto
35
37
  private
36
38
 
37
39
  def slug
40
+ return @config.github_slug if @config.github_slug
38
41
  @slug ||= begin
39
42
  @repo.remote_urls.map do |url|
40
- match = /.*github.com(:|\/)(?<slug>.*).git/.match(url)
43
+ hostname = Regexp.escape(@config.github_hostname)
44
+ match = /.*#{hostname}(:|\/)(?<slug>.*?)(?:\.git)?\z/.match(url)
41
45
  match[:slug] if match
42
46
  end.compact.first
43
47
  end
44
48
  end
45
49
 
46
50
  def client
47
- @client ||= Octokit::Client.new(access_token: access_token)
51
+ @client ||= Octokit::Client.new(api_endpoint: @config.github_api_endpoint,
52
+ web_endpoint: @config.github_web_endpoint,
53
+ access_token: @config.github_access_token,
54
+ auto_paginate: true)
48
55
  end
49
56
 
50
57
  def pull_requests
@@ -63,10 +70,6 @@ module Pronto
63
70
  end
64
71
  end
65
72
 
66
- def access_token
67
- ENV['GITHUB_ACCESS_TOKEN']
68
- end
69
-
70
73
  Comment = Struct.new(:sha, :body, :path, :position) do
71
74
  def ==(other)
72
75
  position == other.position &&
data/lib/pronto/gitlab.rb CHANGED
@@ -2,6 +2,7 @@ module Pronto
2
2
  class Gitlab
3
3
  def initialize(repo)
4
4
  @repo = repo
5
+ @config = Config.new
5
6
  @comment_cache = {}
6
7
  end
7
8
 
@@ -22,26 +23,35 @@ module Pronto
22
23
  private
23
24
 
24
25
  def slug
26
+ return @config.gitlab_slug if @config.gitlab_slug
25
27
  @slug ||= begin
26
- host = URI.split(endpoint)[2, 2].compact.join(':')
27
28
  slug = @repo.remote_urls.map do |url|
28
- match = /.*#{host}(:|\/)(?<slug>.*).git/.match(url)
29
+ match = if url.match(/^ssh:\/\//)
30
+ /.*#{host}(:[0-9]+)?(:|\/)(?<slug>.*).git/.match(url)
31
+ else
32
+ /.*#{host}(:|\/)(?<slug>.*).git/.match(url)
33
+ end
29
34
  match[:slug] if match
30
35
  end.compact.first
31
36
  URI.escape(slug, '/') if slug
32
37
  end
33
38
  end
34
39
 
40
+ def host
41
+ @host ||= URI.split(gitlab_api_endpoint)[2, 2].compact.join(':')
42
+ end
43
+
35
44
  def client
36
- @client ||= ::Gitlab.client(endpoint: endpoint, private_token: private_token)
45
+ @client ||= ::Gitlab.client(endpoint: gitlab_api_endpoint,
46
+ private_token: gitlab_api_private_token)
37
47
  end
38
48
 
39
- def private_token
40
- ENV['GITLAB_API_PRIVATE_TOKEN']
49
+ def gitlab_api_private_token
50
+ @config.gitlab_api_private_token
41
51
  end
42
52
 
43
- def endpoint
44
- ENV['GITLAB_API_ENDPOINT']
53
+ def gitlab_api_endpoint
54
+ @config.gitlab_api_endpoint
45
55
  end
46
56
 
47
57
  Comment = Struct.new(:sha, :note, :path, :line) do
@@ -24,5 +24,25 @@ module Pronto
24
24
  def repo
25
25
  line.patch.repo if line
26
26
  end
27
+
28
+ def ==(other)
29
+ comparison_attributes.all? do |attribute|
30
+ send(attribute) == other.send(attribute)
31
+ end
32
+ end
33
+
34
+ alias_method :eql?, :==
35
+
36
+ def hash
37
+ comparison_attributes.reduce(0) do |hash, attribute|
38
+ hash ^ send(attribute).hash
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def comparison_attributes
45
+ line ? [:path, :msg, :level, :line] : [:path, :msg, :level, :commit_sha]
46
+ end
27
47
  end
28
48
  end
data/lib/pronto/runner.rb CHANGED
@@ -7,11 +7,19 @@ module Pronto
7
7
  end
8
8
 
9
9
  def ruby_file?(path)
10
- File.extname(path) == '.rb' || ruby_executable?(path)
10
+ rb_file?(path) || rake_file?(path) || ruby_executable?(path)
11
11
  end
12
12
 
13
13
  private
14
14
 
15
+ def rb_file?(path)
16
+ File.extname(path) == '.rb'
17
+ end
18
+
19
+ def rake_file?(path)
20
+ File.extname(path) == '.rake'
21
+ end
22
+
15
23
  def ruby_executable?(path)
16
24
  line = File.open(path, &:readline)
17
25
  line =~ /#!.*ruby/
@@ -0,0 +1,28 @@
1
+ module Pronto
2
+ class Runners
3
+ def initialize(runners = Runner.runners, config = Config.new)
4
+ @runners = runners
5
+ @config = config
6
+ end
7
+
8
+ def run(patches)
9
+ patches = reject_excluded(patches)
10
+ return [] unless patches.any?
11
+
12
+ @runners.map { |runner| runner.new.run(patches, patches.commit) }
13
+ .flatten.compact
14
+ end
15
+
16
+ private
17
+
18
+ def reject_excluded(patches)
19
+ return patches unless @config.excluded_files.any?
20
+ patches.reject! { |patch| excluded?(patch) }
21
+ patches
22
+ end
23
+
24
+ def excluded?(patch)
25
+ @config.excluded_files.include?(patch.new_file_full_path.to_s)
26
+ end
27
+ end
28
+ end
@@ -1,3 +1,3 @@
1
1
  module Pronto
2
- VERSION = '0.4.3'
2
+ VERSION = '0.5.0'
3
3
  end
data/pronto.gemspec ADDED
@@ -0,0 +1,52 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
4
+ require 'pronto/version'
5
+ require 'English'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = 'pronto'
9
+ s.version = Pronto::VERSION
10
+ s.platform = Gem::Platform::RUBY
11
+ s.author = 'Mindaugas Mozūras'
12
+ s.email = 'mindaugas.mozuras@gmail.com'
13
+ s.homepage = 'http://github.com/mmozuras/pronto'
14
+ s.summary = 'Pronto runs analysis by checking only the introduced changes'
15
+ s.description = <<-EOF
16
+ Pronto runs analysis quickly by checking only the relevant changes. Created
17
+ to be used on pull requests, but suited for other scenarios as well. Perfect
18
+ if you want to find out quickly if branch introduces changes that conform to
19
+ your styleguide, are DRY, don't introduce security holes and more.
20
+ EOF
21
+
22
+ s.licenses = ['MIT']
23
+ s.required_ruby_version = '>= 1.9.3'
24
+ s.rubygems_version = '1.8.23'
25
+
26
+ s.files = `git ls-files`.split($RS).reject do |file|
27
+ file =~ %r{^(?:
28
+ spec/.*
29
+ |Gemfile
30
+ |Rakefile
31
+ |\.rspec
32
+ |\.gitignore
33
+ |\.rubocop.yml
34
+ |\.travis.yml
35
+ )$}x
36
+ end
37
+ s.test_files = []
38
+ s.extra_rdoc_files = ['LICENSE', 'README.md']
39
+ s.require_paths = ['lib']
40
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
41
+
42
+ s.add_runtime_dependency('rugged', '~> 0.23.0')
43
+ s.add_runtime_dependency('thor', '~> 0.19.0')
44
+ s.add_runtime_dependency('octokit', '~> 4.1.0')
45
+ s.add_runtime_dependency('gitlab', '~> 3.4.0')
46
+ s.add_development_dependency('rake', '~> 10.4')
47
+ s.add_development_dependency('rspec', '~> 3.3')
48
+ s.add_development_dependency('rspec-its', '~> 1.2')
49
+ s.add_development_dependency('rspec-expectations', '~> 3.3')
50
+ s.add_development_dependency('bundler', '~> 1.3')
51
+ s.add_development_dependency('simplecov', '~> 0.10')
52
+ end
data/pronto.gif ADDED
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pronto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mindaugas Mozūras
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-05 00:00:00.000000000 Z
11
+ date: 2015-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rugged
@@ -72,56 +72,84 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 10.4.0
75
+ version: '10.4'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 10.4.0
82
+ version: '10.4'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 3.3.0
89
+ version: '3.3'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 3.3.0
96
+ version: '3.3'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rspec-its
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 1.2.0
103
+ version: '1.2'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 1.2.0
110
+ version: '1.2'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rspec-expectations
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 3.3.0
117
+ version: '3.3'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 3.3.0
124
+ version: '3.3'
125
+ - !ruby/object:Gem::Dependency
126
+ name: bundler
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.3'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.3'
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.10'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.10'
125
153
  description: |2
126
154
  Pronto runs analysis quickly by checking only the relevant changes. Created
127
155
  to be used on pull requests, but suited for other scenarios as well. Perfect
@@ -131,13 +159,19 @@ email: mindaugas.mozuras@gmail.com
131
159
  executables:
132
160
  - pronto
133
161
  extensions: []
134
- extra_rdoc_files: []
162
+ extra_rdoc_files:
163
+ - LICENSE
164
+ - README.md
135
165
  files:
166
+ - CHANGELOG.md
167
+ - CONTRIBUTING.md
136
168
  - LICENSE
137
169
  - README.md
138
170
  - bin/pronto
139
171
  - lib/pronto.rb
140
172
  - lib/pronto/cli.rb
173
+ - lib/pronto/config.rb
174
+ - lib/pronto/config_file.rb
141
175
  - lib/pronto/formatter/checkstyle_formatter.rb
142
176
  - lib/pronto/formatter/formatter.rb
143
177
  - lib/pronto/formatter/github_formatter.rb
@@ -156,7 +190,10 @@ files:
156
190
  - lib/pronto/plugin.rb
157
191
  - lib/pronto/rake_task/travis_pull_request.rb
158
192
  - lib/pronto/runner.rb
193
+ - lib/pronto/runners.rb
159
194
  - lib/pronto/version.rb
195
+ - pronto.gemspec
196
+ - pronto.gif
160
197
  homepage: http://github.com/mmozuras/pronto
161
198
  licenses:
162
199
  - MIT
@@ -169,12 +206,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
169
206
  requirements:
170
207
  - - ">="
171
208
  - !ruby/object:Gem::Version
172
- version: '0'
209
+ version: 1.9.3
173
210
  required_rubygems_version: !ruby/object:Gem::Requirement
174
211
  requirements:
175
212
  - - ">="
176
213
  - !ruby/object:Gem::Version
177
- version: 1.3.6
214
+ version: '0'
178
215
  requirements: []
179
216
  rubyforge_project:
180
217
  rubygems_version: 2.4.5
@@ -182,4 +219,3 @@ signing_key:
182
219
  specification_version: 4
183
220
  summary: Pronto runs analysis by checking only the introduced changes
184
221
  test_files: []
185
- has_rdoc: