repofetch 0.4.2 → 0.4.4
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 +4 -4
- data/CONTRIBUTING.md +7 -0
- data/Gemfile.lock +14 -16
- data/README.md +14 -2
- data/RELEASE_NOTES +4 -16
- data/lib/repofetch/DEFAULT_CONFIG +1 -0
- data/lib/repofetch/bitbucketcloud/ASCII +17 -0
- data/lib/repofetch/bitbucketcloud.rb +158 -0
- data/lib/repofetch/cli.rb +5 -3
- data/lib/repofetch/exceptions.rb +6 -1
- data/lib/repofetch/github.rb +19 -21
- data/lib/repofetch/gitlab.rb +26 -9
- metadata +8 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3ad5af8ce1827ff6413451767fc8040cc710a057ecfde81d2d5db8c33282a15d
|
|
4
|
+
data.tar.gz: 3b9658cdeaf490accc551548464ea534e49b86a15dde562b16eec7da0d2d9d05
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 07a62248fa6ff9248b85b01fc7f8376ae6b17fd5b9f30fce25a7e1ad139892b4ee230e84e3eb43b1aa2d1b94c66ee0be8f330100b2949b3ba95edbe7bb7cb2b2
|
|
7
|
+
data.tar.gz: 814a0249c286baf5523a461c50acadd75c2f31149185e5c8f8886e2f48feddcc770445fac5f6441092663cd1dbdea6dd40c2a457526d2740774be67bdafdc709
|
data/CONTRIBUTING.md
CHANGED
|
@@ -13,6 +13,12 @@ bundle install
|
|
|
13
13
|
bundle exec overcommit --install
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
### Demo Animations
|
|
17
|
+
|
|
18
|
+
The demo animations are created using [vhs]. If you are going to create or
|
|
19
|
+
update the demo animations, please follow the installation instructions for
|
|
20
|
+
[vhs].
|
|
21
|
+
|
|
16
22
|
## Writing a 3rd-party plugin
|
|
17
23
|
|
|
18
24
|
3rd-party plugins are Ruby gems that users can install and activate in their
|
|
@@ -131,3 +137,4 @@ MyCoolPlugin.register
|
|
|
131
137
|
negative space, and uncolored text for positive space.
|
|
132
138
|
|
|
133
139
|
[git-base]: https://www.rubydoc.info/github/ruby-git/ruby-git/Git/Base
|
|
140
|
+
[vhs]: https://github.com/charmbracelet/vhs
|
data/Gemfile.lock
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
repofetch (0.4.
|
|
4
|
+
repofetch (0.4.4)
|
|
5
5
|
actionview (~> 7.0, >= 7.0.4)
|
|
6
6
|
dotenv (~> 2.8)
|
|
7
7
|
faraday-retry (~> 2.0)
|
|
8
8
|
git (~> 1.12)
|
|
9
9
|
octokit (~> 6.0, >= 6.0.1)
|
|
10
|
-
sawyer
|
|
10
|
+
sawyer
|
|
11
11
|
|
|
12
12
|
GEM
|
|
13
13
|
remote: https://rubygems.org/
|
|
@@ -41,7 +41,7 @@ GEM
|
|
|
41
41
|
faraday-net_http (3.0.2)
|
|
42
42
|
faraday-retry (2.0.0)
|
|
43
43
|
faraday (~> 2.0)
|
|
44
|
-
git (1.13.
|
|
44
|
+
git (1.13.1)
|
|
45
45
|
addressable (~> 2.8)
|
|
46
46
|
rchardet (~> 1.8)
|
|
47
47
|
i18n (1.12.0)
|
|
@@ -51,10 +51,8 @@ GEM
|
|
|
51
51
|
loofah (2.19.1)
|
|
52
52
|
crass (~> 1.0.2)
|
|
53
53
|
nokogiri (>= 1.5.9)
|
|
54
|
-
mini_portile2 (2.8.1)
|
|
55
54
|
minitest (5.17.0)
|
|
56
|
-
nokogiri (1.
|
|
57
|
-
mini_portile2 (~> 2.8.0)
|
|
55
|
+
nokogiri (1.14.0-x86_64-linux)
|
|
58
56
|
racc (~> 1.4)
|
|
59
57
|
octokit (6.0.1)
|
|
60
58
|
faraday (>= 1, < 3)
|
|
@@ -65,7 +63,7 @@ GEM
|
|
|
65
63
|
iniparse (~> 1.4)
|
|
66
64
|
rexml (~> 3.2)
|
|
67
65
|
parallel (1.22.1)
|
|
68
|
-
parser (3.
|
|
66
|
+
parser (3.2.0.0)
|
|
69
67
|
ast (~> 2.4.1)
|
|
70
68
|
public_suffix (5.0.1)
|
|
71
69
|
racc (1.6.2)
|
|
@@ -85,31 +83,31 @@ GEM
|
|
|
85
83
|
rspec-mocks (~> 3.12.0)
|
|
86
84
|
rspec-core (3.12.0)
|
|
87
85
|
rspec-support (~> 3.12.0)
|
|
88
|
-
rspec-expectations (3.12.
|
|
86
|
+
rspec-expectations (3.12.2)
|
|
89
87
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
90
88
|
rspec-support (~> 3.12.0)
|
|
91
|
-
rspec-mocks (3.12.
|
|
89
|
+
rspec-mocks (3.12.2)
|
|
92
90
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
93
91
|
rspec-support (~> 3.12.0)
|
|
94
92
|
rspec-snapshot (2.0.1)
|
|
95
93
|
awesome_print (> 1.0.0)
|
|
96
94
|
rspec (> 3.0.0)
|
|
97
95
|
rspec-support (3.12.0)
|
|
98
|
-
rubocop (1.
|
|
96
|
+
rubocop (1.43.0)
|
|
99
97
|
json (~> 2.3)
|
|
100
98
|
parallel (~> 1.10)
|
|
101
|
-
parser (>= 3.
|
|
99
|
+
parser (>= 3.2.0.0)
|
|
102
100
|
rainbow (>= 2.2.2, < 4.0)
|
|
103
101
|
regexp_parser (>= 1.8, < 3.0)
|
|
104
102
|
rexml (>= 3.2.5, < 4.0)
|
|
105
103
|
rubocop-ast (>= 1.24.1, < 2.0)
|
|
106
104
|
ruby-progressbar (~> 1.7)
|
|
107
|
-
unicode-display_width (>=
|
|
105
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
|
108
106
|
rubocop-ast (1.24.1)
|
|
109
107
|
parser (>= 3.1.1.0)
|
|
110
108
|
rubocop-rake (0.6.0)
|
|
111
109
|
rubocop (~> 1.0)
|
|
112
|
-
rubocop-rspec (2.
|
|
110
|
+
rubocop-rspec (2.17.0)
|
|
113
111
|
rubocop (~> 1.33)
|
|
114
112
|
ruby-progressbar (1.11.0)
|
|
115
113
|
ruby2_keywords (0.0.5)
|
|
@@ -127,13 +125,13 @@ GEM
|
|
|
127
125
|
simplecov_json_formatter (0.1.4)
|
|
128
126
|
tzinfo (2.0.5)
|
|
129
127
|
concurrent-ruby (~> 1.0)
|
|
130
|
-
unicode-display_width (2.
|
|
128
|
+
unicode-display_width (2.4.2)
|
|
131
129
|
webrick (1.7.0)
|
|
132
130
|
yard (0.9.28)
|
|
133
131
|
webrick (~> 1.7.0)
|
|
134
132
|
|
|
135
133
|
PLATFORMS
|
|
136
|
-
|
|
134
|
+
x86_64-linux
|
|
137
135
|
|
|
138
136
|
DEPENDENCIES
|
|
139
137
|
bundler (~> 2.0)
|
|
@@ -151,4 +149,4 @@ DEPENDENCIES
|
|
|
151
149
|
yard (~> 0.9.28)
|
|
152
150
|
|
|
153
151
|
BUNDLED WITH
|
|
154
|
-
2.
|
|
152
|
+
2.4.3
|
data/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://badge.fury.io/rb/repofetch)
|
|
4
4
|
[](./CREDITS.md)
|
|
5
5
|

|
|
6
|
-
[](https://github.com/spenserblack/repofetch/actions/workflows/github-code-scanning/codeql)
|
|
7
7
|
[](https://codecov.io/gh/spenserblack/repofetch)
|
|
8
8
|
|
|
9
9
|
Fetch details about your remote repository.
|
|
@@ -12,7 +12,7 @@ Fetch details about your remote repository.
|
|
|
12
12
|
|
|
13
13
|

|
|
14
14
|
|
|
15
|
-

|
|
16
16
|
|
|
17
17
|
## Description
|
|
18
18
|
|
|
@@ -20,9 +20,15 @@ repofetch is a CLI tool to fetch stats (think [neofetch] or
|
|
|
20
20
|
[onefetch]) that uses plugins for its implementation. The original version was focused on
|
|
21
21
|
repository stats, and any official plugin will be for repositories, hence the "repo" in
|
|
22
22
|
repofetch. With 3rd-party plugins, however, it can support other types of outputs, too.
|
|
23
|
+
This tool may be renamed in the future.
|
|
24
|
+
|
|
25
|
+
Follow [this discussion](https://github.com/spenserblack/repofetch/discussions/219)
|
|
26
|
+
for details about the potential rename.
|
|
23
27
|
|
|
24
28
|
## Installation
|
|
25
29
|
|
|
30
|
+
[](https://repology.org/project/ruby:repofetch/versions)
|
|
31
|
+
|
|
26
32
|
### Via RubyGems.org
|
|
27
33
|
|
|
28
34
|
```bash
|
|
@@ -45,6 +51,12 @@ yay -S ruby-repofetch-bin
|
|
|
45
51
|
yay -S ruby-repofetch
|
|
46
52
|
```
|
|
47
53
|
|
|
54
|
+
### Via NetBSD
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pkgin install ruby-repofetch
|
|
58
|
+
```
|
|
59
|
+
|
|
48
60
|
### Installing Version `< 0.4.0`
|
|
49
61
|
|
|
50
62
|
Version 0.3.3 and lower was a different implementation written in Rust. While `>= 0.4.0` is unstable
|
data/RELEASE_NOTES
CHANGED
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
Bitbucket Cloud Bugfix
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Fixed
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
## Other
|
|
9
|
-
|
|
10
|
-
- Publish gem with GitHub Actions
|
|
11
|
-
|
|
12
|
-
## Breaking for 3rd-party plugins
|
|
13
|
-
|
|
14
|
-
### Changed
|
|
15
|
-
|
|
16
|
-
- Configuration to be a class variable on `Repofetch` instead of a value that's
|
|
17
|
-
passed to various instantiation and rendering methods
|
|
18
|
-
- Stats to automatically receive theme from the base `Plugin` class
|
|
5
|
+
- Bitbucket Cloud not getting automatically detected when running `repofetch` in a
|
|
6
|
+
Bitbucket Cloud repository
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
%{blue}@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
2
|
+
%{blue}@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
3
|
+
%{blue} @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
4
|
+
%{blue} @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
5
|
+
%{blue} @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
6
|
+
%{blue} @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
7
|
+
%{blue} @@@@@@@@@ .........
|
|
8
|
+
%{blue} @@@@@@@@@ .........
|
|
9
|
+
%{blue} @@@@@@@@@ :::::::::
|
|
10
|
+
%{blue} @@@@@@@@@ :::::::::
|
|
11
|
+
%{blue} @@@@@@@@@ !!!!!!!!!
|
|
12
|
+
%{blue} @@@@@@@@@ !!!!!!!!!
|
|
13
|
+
%{blue} @@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
14
|
+
%{blue} @@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
15
|
+
%{blue} @@@@@@@@@@@@@@@@@@@@@@@@@
|
|
16
|
+
%{blue} @@@@@@@@@@@@@@@@@@@@@@@@@
|
|
17
|
+
%{blue} @@@@@@@@@@@@@@@@@@@@@@@
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'action_view'
|
|
4
|
+
require 'optparse'
|
|
5
|
+
require 'repofetch'
|
|
6
|
+
require 'repofetch/exceptions'
|
|
7
|
+
require 'sawyer'
|
|
8
|
+
|
|
9
|
+
class Repofetch
|
|
10
|
+
# Adds support for Bitbucket repositories.
|
|
11
|
+
class BitbucketCloud < Repofetch::Plugin
|
|
12
|
+
include ActionView::Helpers::NumberHelper
|
|
13
|
+
|
|
14
|
+
HTTP_REMOTE_REGEX = %r{https?://bitbucket\.org/(?<owner>[\w._-]+)/(?<repo>[\w._-]+)}.freeze
|
|
15
|
+
SSH_REMOTE_REGEX = %r{git@bitbucket\.org:(?<owner>[\w._-]+)/(?<repo>[\w._-]+)}.freeze
|
|
16
|
+
ASCII = File.read(File.expand_path('bitbucketcloud/ASCII', __dir__))
|
|
17
|
+
|
|
18
|
+
attr_reader :repo_identifier
|
|
19
|
+
|
|
20
|
+
def initialize(repo_identifier)
|
|
21
|
+
super
|
|
22
|
+
|
|
23
|
+
@repo_identifier = repo_identifier
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def header
|
|
27
|
+
"#{repo_data['owner']['display_name']}/#{repo_data['name']} @ Bitbucket"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def stats
|
|
31
|
+
stats = [http_clone_url, ssh_clone_url, watchers, forks, created, updated, size, issues, pull_requests]
|
|
32
|
+
|
|
33
|
+
stats.each { |stat| %i[bold blue].each { |style| stat.style_label!(style) } }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def ascii
|
|
37
|
+
ASCII
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def agent
|
|
41
|
+
@agent ||= Sawyer::Agent.new('https://api.bitbucket.org/2.0') do |http|
|
|
42
|
+
http.headers['Authorization'] = "Bearer #{token}" unless token.nil?
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def token
|
|
47
|
+
ENV.fetch('BITBUCKET_TOKEN', nil)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Detects that the repository is a Bitbucket repository.
|
|
51
|
+
def self.matches_repo?(git)
|
|
52
|
+
default_remote = Repofetch.default_remote(git)
|
|
53
|
+
matches_remote?(default_remote&.url)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Detects that the remote URL is for a Bitbucket Cloud repository.
|
|
57
|
+
def self.matches_remote?(remote)
|
|
58
|
+
HTTP_REMOTE_REGEX.match?(remote) || SSH_REMOTE_REGEX.match?(remote)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Gets the owner and repository from a GitHub local repository.
|
|
62
|
+
def self.repo_identifiers(git)
|
|
63
|
+
default_remote = Repofetch.default_remote(git)
|
|
64
|
+
remote_identifiers(default_remote&.url)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Gets the owner and repository from a GitHub remote URL.
|
|
68
|
+
#
|
|
69
|
+
# Returns nil if there is no match.
|
|
70
|
+
def self.remote_identifiers(remote)
|
|
71
|
+
match = HTTP_REMOTE_REGEX.match(remote)
|
|
72
|
+
match = SSH_REMOTE_REGEX.match(remote) if match.nil?
|
|
73
|
+
raise "Remote #{remote.inspect} doesn't look like a Bitbucket Cloud remote" if match.nil?
|
|
74
|
+
|
|
75
|
+
[match[:owner], match[:repo].delete_suffix('.git')]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Creates an instance from a +Git::Base+ instance.
|
|
79
|
+
#
|
|
80
|
+
# @raise [Repofetch::PluginUsageError] if this plugin was selected *and* arguments were passed.
|
|
81
|
+
def self.from_git(git, args)
|
|
82
|
+
raise Repofetch::PluginUsageError, 'Explicitly activate this plugin to CLI arguments' unless args.empty?
|
|
83
|
+
|
|
84
|
+
owner, repository = repo_identifiers(git)
|
|
85
|
+
|
|
86
|
+
new("#{owner}/#{repository}")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def self.from_args(args)
|
|
90
|
+
parser = OptionParser.new do |opts|
|
|
91
|
+
opts.banner = 'Usage: <plugin activation> -- [options] OWNER/PROJECT'
|
|
92
|
+
opts.separator ''
|
|
93
|
+
opts.separator 'This plugin can use the BITBUCKET_TOKEN environment variable'
|
|
94
|
+
end
|
|
95
|
+
parser.parse(args)
|
|
96
|
+
|
|
97
|
+
raise Repofetch::PluginUsageError, parser.to_s unless args.length == 1
|
|
98
|
+
|
|
99
|
+
new(args[0])
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
protected
|
|
103
|
+
|
|
104
|
+
def repo_data
|
|
105
|
+
@repo_data ||= agent.call(:get, "repositories/#{@repo_identifier}").data
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def clone_urls
|
|
109
|
+
@clone_urls ||= repo_data['links']['clone'].to_h { |clone| [clone['name'].to_sym, clone['href']] }
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def http_clone_url
|
|
113
|
+
Repofetch::Stat.new('HTTP(S)', clone_urls[:https], emoji: '🌐')
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def ssh_clone_url
|
|
117
|
+
Repofetch::Stat.new('SSH', clone_urls[:ssh], emoji: '🔑')
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def watchers
|
|
121
|
+
@watcher_data ||= agent.call(:get, "repositories/#{@repo_identifier}/watchers").data
|
|
122
|
+
Repofetch::Stat.new('subscribers', @watcher_data['size'], emoji: '👀')
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def forks
|
|
126
|
+
@fork_data ||= agent.call(:get, "repositories/#{@repo_identifier}/forks").data
|
|
127
|
+
Repofetch::Stat.new('forks', @fork_data['size'], emoji: '🔱')
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def created
|
|
131
|
+
Repofetch::TimespanStat.new('created', repo_data['created_on'], emoji: '🐣')
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def updated
|
|
135
|
+
Repofetch::TimespanStat.new('updated', repo_data['updated_on'], emoji: '📤')
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def size
|
|
139
|
+
# NOTE: Size is in bytes
|
|
140
|
+
# TODO: Move this somewhere else instead of using a copy-paste
|
|
141
|
+
byte_size = number_to_human_size(repo_data['size'] || 0, precision: 2, significant: false,
|
|
142
|
+
strip_insignificant_zeros: false)
|
|
143
|
+
Repofetch::Stat.new('size', byte_size, emoji: '💽')
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def issues
|
|
147
|
+
@issue_data ||= agent.call(:get, "repositories/#{@repo_identifier}/issues").data
|
|
148
|
+
Repofetch::Stat.new('issues', @issue_data['size'], emoji: '❗')
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def pull_requests
|
|
152
|
+
@pull_request_data ||= agent.call(:get, "repositories/#{@repo_identifier}/pullrequests").data
|
|
153
|
+
Repofetch::Stat.new('pull requests', @pull_request_data['size'], emoji: '🔀')
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
Repofetch::BitbucketCloud.register
|
data/lib/repofetch/cli.rb
CHANGED
|
@@ -4,6 +4,7 @@ require 'git'
|
|
|
4
4
|
require 'optparse'
|
|
5
5
|
require 'repofetch'
|
|
6
6
|
require 'repofetch/config'
|
|
7
|
+
require 'repofetch/exceptions'
|
|
7
8
|
|
|
8
9
|
class Repofetch
|
|
9
10
|
# Command line interface for repofetch.
|
|
@@ -29,7 +30,7 @@ class Repofetch
|
|
|
29
30
|
|
|
30
31
|
begin
|
|
31
32
|
plugin = new_plugin
|
|
32
|
-
rescue
|
|
33
|
+
rescue Repofetch::PluginUsageError => e
|
|
33
34
|
warn e
|
|
34
35
|
return 1
|
|
35
36
|
end
|
|
@@ -62,13 +63,14 @@ class Repofetch
|
|
|
62
63
|
private
|
|
63
64
|
|
|
64
65
|
def add_repository_options(opts)
|
|
65
|
-
opts.on('-r', '--repository
|
|
66
|
+
opts.on('-r', '--repository', '-p', '--path PATH',
|
|
67
|
+
'Use the provided path. Defaults to the current directory.') do |path|
|
|
66
68
|
@repository_path = path
|
|
67
69
|
end
|
|
68
70
|
end
|
|
69
71
|
|
|
70
72
|
def add_plugin_options(opts)
|
|
71
|
-
opts.on('-
|
|
73
|
+
opts.on('-P', '--plugin PLUGIN', 'Use the specified plugin.') do |plugin|
|
|
72
74
|
@plugin = available_plugins[plugin]
|
|
73
75
|
end
|
|
74
76
|
|
data/lib/repofetch/exceptions.rb
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Raised when there aren't any available plugins.
|
|
4
3
|
class Repofetch
|
|
5
4
|
class Error < RuntimeError
|
|
6
5
|
end
|
|
7
6
|
|
|
7
|
+
# Raised when there aren't any available plugins.
|
|
8
8
|
class NoPluginsError < Error
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
# Raised when more than one plugin is activated.
|
|
11
12
|
class TooManyPluginsError < Error
|
|
12
13
|
end
|
|
14
|
+
|
|
15
|
+
# Raised when a user incorrectly uses the CLI with a plugin.
|
|
16
|
+
class PluginUsageError < Error
|
|
17
|
+
end
|
|
13
18
|
end
|
data/lib/repofetch/github.rb
CHANGED
|
@@ -4,14 +4,15 @@ require 'action_view'
|
|
|
4
4
|
require 'octokit'
|
|
5
5
|
require 'optparse'
|
|
6
6
|
require 'repofetch'
|
|
7
|
+
require 'repofetch/exceptions'
|
|
7
8
|
|
|
8
9
|
class Repofetch
|
|
9
10
|
# Adds support for GitHub repositories.
|
|
10
11
|
class Github < Repofetch::Plugin
|
|
11
12
|
include ActionView::Helpers::NumberHelper
|
|
12
13
|
|
|
13
|
-
HTTP_REMOTE_REGEX = %r{https?://github\.com/(?<owner>[\w
|
|
14
|
-
SSH_REMOTE_REGEX = %r{git@github\.com:(?<owner>[\w
|
|
14
|
+
HTTP_REMOTE_REGEX = %r{https?://github\.com/(?<owner>[\w.-]+)/(?<repository>[\w.-]+)}.freeze
|
|
15
|
+
SSH_REMOTE_REGEX = %r{git@github\.com:(?<owner>[\w.-]+)/(?<repository>[\w.-]+)}.freeze
|
|
15
16
|
ASCII = File.read(File.expand_path('github/ASCII', __dir__))
|
|
16
17
|
|
|
17
18
|
attr_reader :owner, :repository
|
|
@@ -30,15 +31,15 @@ class Repofetch
|
|
|
30
31
|
end
|
|
31
32
|
|
|
32
33
|
def stats
|
|
33
|
-
stats = [
|
|
34
|
+
stats = [http_clone_url, ssh_clone_url, stargazers, subscribers, forks, created, updated, size, issues,
|
|
35
|
+
pull_requests]
|
|
34
36
|
stats.each { |stat| stat.style_label!(:bold) }
|
|
35
37
|
end
|
|
36
38
|
|
|
37
39
|
# Detects that the repository is a GitHub repository.
|
|
38
40
|
def self.matches_repo?(git)
|
|
39
41
|
default_remote = Repofetch.default_remote(git)
|
|
40
|
-
|
|
41
|
-
matches_remote?(url)
|
|
42
|
+
matches_remote?(default_remote&.url)
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
# Detects that the remote URL is for a GitHub repository.
|
|
@@ -49,8 +50,7 @@ class Repofetch
|
|
|
49
50
|
# Gets the owner and repository from a GitHub local repository.
|
|
50
51
|
def self.repo_identifiers(git)
|
|
51
52
|
default_remote = Repofetch.default_remote(git)
|
|
52
|
-
|
|
53
|
-
remote_identifiers(url)
|
|
53
|
+
remote_identifiers(default_remote&.url)
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
# Gets the owner and repository from a GitHub remote URL.
|
|
@@ -66,10 +66,9 @@ class Repofetch
|
|
|
66
66
|
|
|
67
67
|
# Creates an instance from a +Git::Base+ instance.
|
|
68
68
|
#
|
|
69
|
-
# @raise [
|
|
69
|
+
# @raise [Repofetch::PluginUsageError] if this plugin was selected *and* arguments were passed.
|
|
70
70
|
def self.from_git(git, args)
|
|
71
|
-
|
|
72
|
-
raise ArgumentError, 'Explicitly activate this plugin to CLI arguments' unless args.empty?
|
|
71
|
+
raise Repofetch::PluginUsageError, 'Explicitly activate this plugin to CLI arguments' unless args.empty?
|
|
73
72
|
|
|
74
73
|
owner, repository = repo_identifiers(git)
|
|
75
74
|
|
|
@@ -78,7 +77,7 @@ class Repofetch
|
|
|
78
77
|
|
|
79
78
|
# Creates an instance from CLI args and configuration.
|
|
80
79
|
#
|
|
81
|
-
# @raise [
|
|
80
|
+
# @raise [Repofetch::PluginUsageError] if +args+ couldn't be parsed.
|
|
82
81
|
def self.from_args(args)
|
|
83
82
|
parser = OptionParser.new do |opts|
|
|
84
83
|
opts.banner = 'Usage: <plugin activation> -- [options] OWNER/REPOSITORY'
|
|
@@ -88,8 +87,7 @@ class Repofetch
|
|
|
88
87
|
parser.parse(args)
|
|
89
88
|
split = args[0]&.split('/')
|
|
90
89
|
|
|
91
|
-
|
|
92
|
-
raise ArgumentError, parser.to_s unless split&.length == 2
|
|
90
|
+
raise Repofetch::PluginUsageError, parser.to_s unless split&.length == 2
|
|
93
91
|
|
|
94
92
|
new(*split)
|
|
95
93
|
end
|
|
@@ -109,8 +107,12 @@ class Repofetch
|
|
|
109
107
|
@repo_stats
|
|
110
108
|
end
|
|
111
109
|
|
|
112
|
-
def
|
|
113
|
-
Repofetch::Stat.new('
|
|
110
|
+
def http_clone_url
|
|
111
|
+
Repofetch::Stat.new('HTTP(S)', repo_stats['clone_url'], emoji: '🌐')
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def ssh_clone_url
|
|
115
|
+
Repofetch::Stat.new('SSH', repo_stats['ssh_url'], emoji: '🔑')
|
|
114
116
|
end
|
|
115
117
|
|
|
116
118
|
def stargazers
|
|
@@ -134,12 +136,8 @@ class Repofetch
|
|
|
134
136
|
end
|
|
135
137
|
|
|
136
138
|
def size
|
|
137
|
-
byte_size = number_to_human_size(
|
|
138
|
-
|
|
139
|
-
precision: 2,
|
|
140
|
-
significant: false,
|
|
141
|
-
strip_insignificant_zeros: false
|
|
142
|
-
)
|
|
139
|
+
byte_size = number_to_human_size((repo_stats['size'] || 0) * 1024, precision: 2, significant: false,
|
|
140
|
+
strip_insignificant_zeros: false)
|
|
143
141
|
Repofetch::Stat.new('size', byte_size, emoji: '💽')
|
|
144
142
|
end
|
|
145
143
|
|
data/lib/repofetch/gitlab.rb
CHANGED
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
require 'cgi'
|
|
4
4
|
require 'repofetch'
|
|
5
|
+
require 'repofetch/exceptions'
|
|
5
6
|
require 'sawyer'
|
|
6
7
|
|
|
7
8
|
class Repofetch
|
|
8
9
|
# Adds support for GitLab repositories.
|
|
9
10
|
class Gitlab < Repofetch::Plugin
|
|
10
|
-
HTTP_REMOTE_REGEX = %r{https?://gitlab\.com/(?<path>[\w
|
|
11
|
-
SSH_REMOTE_REGEX = %r{git@gitlab\.com:(?<path>[\w
|
|
11
|
+
HTTP_REMOTE_REGEX = %r{https?://gitlab\.com/(?<path>[\w.-][\w.\-/]+)}.freeze
|
|
12
|
+
SSH_REMOTE_REGEX = %r{git@gitlab\.com:(?<path>[\w.-][\w.\-/]+)}.freeze
|
|
12
13
|
ASCII = File.read(File.expand_path('gitlab/ASCII', __dir__))
|
|
13
14
|
|
|
14
15
|
attr_reader :repo_identifier
|
|
@@ -21,11 +22,15 @@ class Repofetch
|
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
def header
|
|
24
|
-
"#{repo_data['name_with_namespace']} @ GitLab"
|
|
25
|
+
"#{header_format(repo_data['name_with_namespace'])} @ #{header_format('GitLab')}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def header_format(text)
|
|
29
|
+
theme.format(:bold, theme.format(:red, text))
|
|
25
30
|
end
|
|
26
31
|
|
|
27
32
|
def stats
|
|
28
|
-
stats = [
|
|
33
|
+
stats = [http_clone_url, ssh_clone_url, stars, forks, created, updated]
|
|
29
34
|
|
|
30
35
|
# NOTE: Stats that require authentication
|
|
31
36
|
stats << open_issues unless token.nil?
|
|
@@ -51,8 +56,12 @@ class Repofetch
|
|
|
51
56
|
@repo_data ||= agent.call(:get, "projects/#{@repo_identifier}").data
|
|
52
57
|
end
|
|
53
58
|
|
|
54
|
-
def
|
|
55
|
-
Repofetch::Stat.new('
|
|
59
|
+
def http_clone_url
|
|
60
|
+
Repofetch::Stat.new('HTTP(S)', repo_data['http_url_to_repo'], emoji: '🌐')
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def ssh_clone_url
|
|
64
|
+
Repofetch::Stat.new('SSH', repo_data['ssh_url_to_repo'], emoji: '🔑')
|
|
56
65
|
end
|
|
57
66
|
|
|
58
67
|
def stars
|
|
@@ -108,10 +117,9 @@ class Repofetch
|
|
|
108
117
|
|
|
109
118
|
# Creates an instance from a +Git::Base+ instance.
|
|
110
119
|
#
|
|
111
|
-
# @raise [
|
|
120
|
+
# @raise [Repofetch::PluginUsageError] if this plugin was selected *and* arguments were passed.
|
|
112
121
|
def self.from_git(git, args)
|
|
113
|
-
|
|
114
|
-
raise ArgumentError, 'Explicitly activate this plugin to CLI arguments' unless args.empty?
|
|
122
|
+
raise Repofetch::PluginUsageError, 'Explicitly activate this plugin to CLI arguments' unless args.empty?
|
|
115
123
|
|
|
116
124
|
path = repo_identifier(git)
|
|
117
125
|
|
|
@@ -119,6 +127,15 @@ class Repofetch
|
|
|
119
127
|
end
|
|
120
128
|
|
|
121
129
|
def self.from_args(args)
|
|
130
|
+
parser = OptionParser.new do |opts|
|
|
131
|
+
opts.banner = 'Usage: <plugin activation> -- [options] OWNER/PROJECT/SUBPROJECT'
|
|
132
|
+
opts.separator ''
|
|
133
|
+
opts.separator 'This plugin can use the GITLAB_TOKEN environment variable to fetch more data'
|
|
134
|
+
end
|
|
135
|
+
parser.parse(args)
|
|
136
|
+
|
|
137
|
+
raise Repofetch::PluginUsageError, parser.to_s unless args.length == 1
|
|
138
|
+
|
|
122
139
|
new(args[0])
|
|
123
140
|
end
|
|
124
141
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: repofetch
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Spenser Black
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-01-
|
|
11
|
+
date: 2023-01-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: actionview
|
|
@@ -96,16 +96,16 @@ dependencies:
|
|
|
96
96
|
name: sawyer
|
|
97
97
|
requirement: !ruby/object:Gem::Requirement
|
|
98
98
|
requirements:
|
|
99
|
-
- - "
|
|
99
|
+
- - ">="
|
|
100
100
|
- !ruby/object:Gem::Version
|
|
101
|
-
version: '0
|
|
101
|
+
version: '0'
|
|
102
102
|
type: :runtime
|
|
103
103
|
prerelease: false
|
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
|
105
105
|
requirements:
|
|
106
|
-
- - "
|
|
106
|
+
- - ">="
|
|
107
107
|
- !ruby/object:Gem::Version
|
|
108
|
-
version: '0
|
|
108
|
+
version: '0'
|
|
109
109
|
- !ruby/object:Gem::Dependency
|
|
110
110
|
name: bundler
|
|
111
111
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -296,6 +296,8 @@ files:
|
|
|
296
296
|
- exe/repofetch
|
|
297
297
|
- lib/repofetch.rb
|
|
298
298
|
- lib/repofetch/DEFAULT_CONFIG
|
|
299
|
+
- lib/repofetch/bitbucketcloud.rb
|
|
300
|
+
- lib/repofetch/bitbucketcloud/ASCII
|
|
299
301
|
- lib/repofetch/cli.rb
|
|
300
302
|
- lib/repofetch/config.rb
|
|
301
303
|
- lib/repofetch/env.rb
|