codestatus 0.1.1 → 0.1.2

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: 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