pronto 0.4.3 → 0.5.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: 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: