codestatus 0.1.1 → 0.1.2

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: 87b7e13b35690cbbe12b7c3f2872c00e1f02842e
4
- data.tar.gz: 78147b8083a665a96f7fb692717da21b2a338573
3
+ metadata.gz: c422e70b25fb0d3623d7b93e15695d30efae525f
4
+ data.tar.gz: 8624d34d7925435b19f9bb9b5a6961b2fd61894b
5
5
  SHA512:
6
- metadata.gz: 821c2b8b1f0efce58896face9f9d45ca0b1b3c1e4b9a2bc73ae6d49efbfef0c50ea0f8686ab37a31a886f76e9e3707652aa46ed777ce661777400e8fc1c31c51
7
- data.tar.gz: adedf790e67684c29fb72946c7e7c84a4aa77482bf88f99b80186c08e006ac7262334b3b79dec31e72e3ecfa6d9c999578a16906d7e4b2bb8ff28cd9e1728d91
6
+ metadata.gz: 6cf171f0b406a442f15596b4ad0d681c5bafc7d75055d4024a2ce5a1577756ee938aaafc292f51fc5af532f8028692cdba416788ea96c25c801536bf448b6239
7
+ data.tar.gz: 35b775075e73d08eb83a3c3a12ae89a9d6b022ac49ca6ac9b50d5344a554a4f47eaa8aa73d3db97e6607d41b41040b478b859bd62d5b5bf0b6da06b45493c036
data/.travis.yml CHANGED
@@ -1,5 +1,7 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.4.1
4
+ - 2.4.3
5
+ - 2.5.0
6
+
5
7
  before_install: gem install bundler -v 1.16.1
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- codestatus (0.1.1)
4
+ codestatus (0.1.2)
5
5
  gems
6
6
  octokit
7
7
  rest-client
data/README.md CHANGED
@@ -20,6 +20,8 @@ $ codestatus status npm/react
20
20
  success
21
21
  $ codestatus status --registry=npm react
22
22
  success
23
+ $ codestatus status npm/@atlassian/aui
24
+ success
23
25
  ```
24
26
 
25
27
  ```ruby
data/lib/codestatus.rb CHANGED
@@ -1,23 +1,31 @@
1
1
  require "codestatus/version"
2
2
  require "codestatus/build_status"
3
3
  require "codestatus/cli"
4
- require "codestatus/repository_resolver"
5
- require "codestatus/repository_resolver/user_defined_resolver"
6
- require "codestatus/repository_resolver/rubygems_resolver"
7
- require "codestatus/repository_resolver/npm_resolver"
8
- require "codestatus/package_repository"
9
- require "codestatus/package_repository/github_repository"
4
+ require "codestatus/package_resolvers/base"
5
+ require "codestatus/package_resolvers/rubygems_resolver"
6
+ require "codestatus/package_resolvers/npm_resolver"
7
+ require "codestatus/repositories/github_repository"
8
+ require "codestatus/repositories/bitbucket_repository"
10
9
 
11
10
  module Codestatus
12
- def self.status(registry:, package:)
13
- resolver = RepositoryResolver.new(registry: registry, package: package)
14
-
15
- package_repository = resolver.repository
11
+ def self.status(repository: nil, registry: nil, package: nil)
12
+ if !repository && registry && package
13
+ repository = resolver(registry).resolve(package: package)
14
+ end
16
15
 
17
- if package_repository
18
- package_repository.status
16
+ if repository
17
+ repository.status
19
18
  else
20
19
  BuildStatus.new(sha: nil, status: nil)
21
20
  end
22
21
  end
22
+
23
+ def self.resolver(registry)
24
+ case registry
25
+ when /rubygems/
26
+ PackageResolvers::RubygemsResolver
27
+ when /npm/
28
+ PackageResolvers::NpmResolver
29
+ end
30
+ end
23
31
  end
@@ -8,6 +8,12 @@ module Codestatus
8
8
  PENDING = 'pending'.freeze
9
9
  SUCCESS = 'success'.freeze
10
10
 
11
+ # Statuses defined in Bitbucket are mapped into GitHub's status
12
+ # STOPPED => ERROR
13
+ # FAILED => FAILURE
14
+ # INPROGRESS => PENDING
15
+ # SUCCESSFUL => SUCCESS
16
+
11
17
  STATUSES = [
12
18
  ERROR,
13
19
  FAILURE,
@@ -10,7 +10,7 @@ module Codestatus
10
10
  package_registry = options[:registry]
11
11
  package_name = slug
12
12
  else
13
- package_registry, package_name = slug.split('/')
13
+ package_registry, package_name = slug.split('/', 2)
14
14
  end
15
15
 
16
16
  status = Codestatus.status(registry: package_registry, package: package_name)
@@ -0,0 +1,50 @@
1
+ module Codestatus
2
+ module PackageResolvers
3
+ class Base
4
+ GITHUB_REPOSITORY_REGEXP = %r{(https?|git)://github.com/(?<owner>[^/]*)/(?<repo>[^/]*)(\.git)?/?.*}.freeze
5
+ BITBUCKET_REPOSITORY_REGEXP = %r{(https?|git)://bitbucket.org/(?<owner>[^/]*)/(?<repo>[^/]*)(\.git)?/?.*}.freeze
6
+
7
+ def self.resolve(package:)
8
+ self.new(package: package).resolve
9
+ end
10
+
11
+ def initialize(package:)
12
+ @package = package
13
+ end
14
+
15
+ attr_reader :package
16
+
17
+ def resolve
18
+ @package = package
19
+
20
+ github_repository || bitbucket_repository
21
+ end
22
+
23
+ private
24
+
25
+ def github_repository
26
+ urls.map { |url|
27
+ matched = GITHUB_REPOSITORY_REGEXP.match(url)
28
+ next unless matched
29
+
30
+ repo = [matched[:owner], matched[:repo]].join('/')
31
+ Repositories::GitHubRepository.new(repo)
32
+ }.compact.first
33
+ end
34
+
35
+ def bitbucket_repository
36
+ urls.map { |url|
37
+ matched = BITBUCKET_REPOSITORY_REGEXP.match(url)
38
+ next unless matched
39
+
40
+ repo = [matched[:owner], matched[:repo]].join('/')
41
+ Repositories::BitbucketRepository.new(repo)
42
+ }.compact.first
43
+ end
44
+
45
+ def urls
46
+ raise NotImplementedError
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,51 @@
1
+ require 'rest-client'
2
+
3
+ module Codestatus
4
+ module PackageResolvers
5
+ class NpmResolver < Base
6
+ NPM_REGISTRY_ENDPOINT = 'https://registry.npmjs.org/'.freeze
7
+
8
+ private
9
+
10
+ def urls
11
+ [
12
+ bugs_url,
13
+ repository_url,
14
+ homepage_url,
15
+ ].compact
16
+ end
17
+
18
+ def bugs_url
19
+ package_info.dig('bugs', 'url')
20
+ end
21
+
22
+ def homepage_url
23
+ package_info.dig('homepage')
24
+ end
25
+
26
+ def repository_url
27
+ package_info.dig('repository', 'url')
28
+ end
29
+
30
+ def package_info
31
+ @package_info ||= JSON.parse(client.get(package_uri))
32
+ end
33
+
34
+ def client
35
+ RestClient
36
+ end
37
+
38
+ def package_uri
39
+ File.join(NPM_REGISTRY_ENDPOINT, slash_escaped_package)
40
+ end
41
+
42
+ # for scoped package
43
+ # For example, to access @atlassian/aui information,
44
+ # we must use https://registry.npmjs.org/@atlassian%2Faui,
45
+ # not https://registry.npmjs.org/%40atlassian%2Faui.
46
+ def slash_escaped_package
47
+ package.gsub('/', CGI.escape('/'))
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,33 @@
1
+ require "gems"
2
+
3
+ module Codestatus
4
+ module PackageResolvers
5
+ class RubygemsResolver < Base
6
+ private
7
+
8
+ def urls
9
+ [
10
+ source_code_uri,
11
+ homepage_uri,
12
+ bug_tracker_uri,
13
+ ].compact
14
+ end
15
+
16
+ def homepage_uri
17
+ gem_info['homepage_uri']
18
+ end
19
+
20
+ def source_code_uri
21
+ gem_info['source_code_uri']
22
+ end
23
+
24
+ def bug_tracker_uri
25
+ gem_info['bug_tracker_uri']
26
+ end
27
+
28
+ def gem_info
29
+ @info ||= Gems.info(package)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,64 @@
1
+ require 'rest-client'
2
+
3
+ module Codestatus
4
+ module Repositories
5
+ class BitbucketRepository
6
+ BITBUCKET_API_ENDPOINT = 'https://api.bitbucket.org/2.0/' #repositories/atlassian/aui
7
+ def initialize(slug)
8
+ # 'atlassian/aui'
9
+ @slug = slug
10
+ end
11
+
12
+ # This combined status is generated by the rule of GitHub's
13
+ # https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
14
+ def status(ref = main_branch)
15
+ statuses = statuses(ref)
16
+
17
+ sha = statuses['values'].map {|x| x.dig('commit', 'hash') }.compact.first
18
+ states = statuses['values'].map { |status| status['state'] }
19
+
20
+ state = if states.any? { |x| ['STOPPED', 'FAILED'].include?(x) }
21
+ BuildStatus::FAILURE
22
+ elsif states.empty? || states.all? { |x| x == 'INPROGRESS' }
23
+ BuildStatus::PENDING
24
+ elsif states.all? { |x| x == 'SUCCESSFUL' }
25
+ BuildStatus::SUCCESS
26
+ else
27
+ BuildStatus::UNDEFINED
28
+ end
29
+
30
+ BuildStatus.new(sha: sha, status: state)
31
+ end
32
+
33
+ attr_reader :slug
34
+
35
+ private
36
+
37
+ def main_branch
38
+ repository.dig('mainbranch', 'name')
39
+ end
40
+
41
+ def repository
42
+ @repository ||= JSON.parse(client.get(repository_uri))
43
+ end
44
+
45
+ def repository_uri
46
+ File.join(BITBUCKET_API_ENDPOINT, 'repositories', slug)
47
+ end
48
+
49
+ def client
50
+ RestClient
51
+ end
52
+
53
+ # https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Busername%7D/%7Brepo_slug%7D/commit/%7Bnode%7D/statuses
54
+ # example: https://api.bitbucket.org/2.0/repositories/atlassian/aui/commit/master/statuses
55
+ def statuses(ref)
56
+ @statuses ||= JSON.parse(client.get(statuses_uri(ref)))
57
+ end
58
+
59
+ def statuses_uri(ref)
60
+ File.join(BITBUCKET_API_ENDPOINT, 'repositories', slug, 'commit', ref, 'statuses')
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,27 +1,23 @@
1
1
  require "octokit"
2
2
 
3
3
  module Codestatus
4
- class PackageRepository
4
+ module Repositories
5
5
  class GitHubRepository
6
6
  def initialize(slug)
7
7
  # 'influitive/apartment'
8
8
  @repo = slug
9
9
  end
10
10
 
11
- def status
12
- status_of_default_branch
13
- end
14
-
15
- private
16
-
17
11
  # combined status on github
18
12
  # https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
19
- def status_of_default_branch
20
- response = client.combined_status(@repo, default_branch)
13
+ def status(ref = default_branch)
14
+ response = client.combined_status(@repo, ref)
21
15
 
22
16
  BuildStatus.new(sha: response.sha, status: response.state)
23
17
  end
24
18
 
19
+ private
20
+
25
21
  def default_branch
26
22
  repository['default_branch']
27
23
  end
@@ -1,3 +1,3 @@
1
1
  module Codestatus
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codestatus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - meganemura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-01-01 00:00:00.000000000 Z
11
+ date: 2018-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: octokit
@@ -159,12 +159,11 @@ files:
159
159
  - lib/codestatus.rb
160
160
  - lib/codestatus/build_status.rb
161
161
  - lib/codestatus/cli.rb
162
- - lib/codestatus/package_repository.rb
163
- - lib/codestatus/package_repository/github_repository.rb
164
- - lib/codestatus/repository_resolver.rb
165
- - lib/codestatus/repository_resolver/npm_resolver.rb
166
- - lib/codestatus/repository_resolver/rubygems_resolver.rb
167
- - lib/codestatus/repository_resolver/user_defined_resolver.rb
162
+ - lib/codestatus/package_resolvers/base.rb
163
+ - lib/codestatus/package_resolvers/npm_resolver.rb
164
+ - lib/codestatus/package_resolvers/rubygems_resolver.rb
165
+ - lib/codestatus/repositories/bitbucket_repository.rb
166
+ - lib/codestatus/repositories/github_repository.rb
168
167
  - lib/codestatus/version.rb
169
168
  homepage: https://github.com/meganemura/codestatus
170
169
  licenses:
@@ -1,16 +0,0 @@
1
- module Codestatus
2
- class PackageRepository
3
- def initialize(github: nil)
4
- @github = GitHubRepository.new(github) if github
5
- # bitbucket, gitlab, ...
6
- end
7
-
8
- attr_reader :github
9
-
10
- def status
11
- if github
12
- github.status # default branch's commit's status
13
- end
14
- end
15
- end
16
- end
@@ -1,37 +0,0 @@
1
- module Codestatus
2
- class RepositoryResolver
3
- def initialize(registry:, package:)
4
- @registry = registry
5
- @package = package
6
- end
7
-
8
- attr_reader :registry, :package
9
-
10
- def repository
11
- @repository ||= resolve
12
- end
13
-
14
- private
15
-
16
- def resolve
17
- result = nil
18
- resolvers.each do |resolver|
19
- result = resolver.resolve(registry: registry, package: package)
20
- break if result
21
- end
22
- result
23
- end
24
-
25
- def resolvers
26
- @resolvers ||= resolver_classes.map(&:new)
27
- end
28
-
29
- def resolver_classes
30
- @resolver_classes ||= [
31
- RepositoryResolver::RubygemsResolver,
32
- RepositoryResolver::NpmResolver,
33
- RepositoryResolver::UserDefinedResolver,
34
- ]
35
- end
36
- end
37
- end
@@ -1,63 +0,0 @@
1
- require 'rest-client'
2
-
3
- module Codestatus
4
- class RepositoryResolver
5
- class NpmResolver
6
- GITHUB_REPOSITORY_REGEXP = %r{(https|git)://github.com/(?<owner>[^/]*)/(?<repo>[^/]*)(\.git)?/?.*}.freeze
7
- NPM_REGISTRY_ENDPOINT = 'https://registry.npmjs.org/'.freeze
8
-
9
- def resolve(registry:, package:)
10
- return unless registry.to_s == 'npm'
11
- @package = package
12
-
13
- github_repository
14
- end
15
-
16
- attr_reader :package
17
-
18
- private
19
-
20
- # FIXME: Copied from RubygemsResolver
21
- def github_repository
22
- result = nil
23
- urls.each do |url|
24
- matched = GITHUB_REPOSITORY_REGEXP.match(url)
25
- next unless matched
26
-
27
- repo = [matched[:owner], matched[:repo]].join('/')
28
- result = Codestatus::PackageRepository.new(github: repo)
29
- break
30
- end
31
- result
32
- end
33
-
34
- def package_info
35
- @package_info ||= JSON.parse(client.get("#{NPM_REGISTRY_ENDPOINT}/#{package}"))
36
- end
37
-
38
- def urls
39
- [
40
- bugs_url,
41
- repository_url,
42
- homepage_url,
43
- ].compact
44
- end
45
-
46
- def bugs_url
47
- package_info.dig('bugs', 'url')
48
- end
49
-
50
- def homepage_url
51
- package_info.dig('homepage')
52
- end
53
-
54
- def repository_url
55
- package_info.dig('repository', 'url')
56
- end
57
-
58
- def client
59
- RestClient
60
- end
61
- end
62
- end
63
- end
@@ -1,57 +0,0 @@
1
- require "gems"
2
-
3
- module Codestatus
4
- class RepositoryResolver
5
- class RubygemsResolver
6
- GITHUB_REPOSITORY_REGEXP = %r{(https|git)://github.com/(?<owner>[^/]*)/(?<repo>[^/]*)(\.git)?/?.*}.freeze
7
-
8
- def resolve(registry:, package:)
9
- return unless registry.to_s == 'rubygems'
10
- @package = package
11
-
12
- github_repository
13
- end
14
-
15
- attr_reader :package
16
-
17
- private
18
-
19
- def github_repository
20
- result = nil
21
- urls.each do |url|
22
- matched = GITHUB_REPOSITORY_REGEXP.match(url)
23
- next unless matched
24
-
25
- repo = [matched[:owner], matched[:repo]].join('/')
26
- result = Codestatus::PackageRepository.new(github: repo)
27
- break
28
- end
29
- result
30
- end
31
-
32
- def gem_info
33
- @info ||= Gems.info(package)
34
- end
35
-
36
- def urls
37
- [
38
- source_code_uri,
39
- homepage_uri,
40
- bug_tracker_uri,
41
- ].compact
42
- end
43
-
44
- def homepage_uri
45
- gem_info['homepage_uri']
46
- end
47
-
48
- def source_code_uri
49
- gem_info['source_code_uri']
50
- end
51
-
52
- def bug_tracker_uri
53
- gem_info['bug_tracker_uri']
54
- end
55
- end
56
- end
57
- end
@@ -1,18 +0,0 @@
1
- module Codestatus
2
- class RepositoryResolver
3
- class UserDefinedResolver
4
- def self.definitions
5
- @definitions ||= {
6
- 'rubygems/apartment': Codestatus::PackageRepository.new(github: 'influitive/apartment'),
7
- 'rubygems/octokit': Codestatus::PackageRepository.new(github: 'octokit/octokit.rb'),
8
- }
9
- end
10
-
11
- def resolve(registry:, package:)
12
- key = [registry, package].join('/')
13
-
14
- self.class.definitions[key.to_sym]
15
- end
16
- end
17
- end
18
- end