gem-clone 0.4.1 → 0.4.3
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/README.md +192 -53
- data/lib/rubygems/commands/clone_command.rb +36 -13
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 836f42b5a4924b0e9d94246ff6d12bb2f39faa30c51647d8443f75a4f1b98656
|
|
4
|
+
data.tar.gz: 22c882c0be0897264b54cbf865e9ba234cd7ec05d778ece19431c1158c6e8577
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e911bd7cf6c713b46e3e9ca34da2edd34c2af8e6988e308ace4b403d7526a7722abc009f1b8c655f06f0da76fa5522cafffa82bceeaa8a2995dc2e80f1b60500
|
|
7
|
+
data.tar.gz: fb3c3a11745f66da76dc3db82173d3b01c611e5905578a6f3feeddac926bf8faa4208ca0c39ab95e6f5d2e8a1846ddf8dfdc9b16c3f477e6cd260b8c17a1819b
|
data/README.md
CHANGED
|
@@ -1,40 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# gem-clone
|
|
2
2
|
|
|
3
|
-
A RubyGems plugin that allows you to clone gem repositories using `ghq
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
gem install gem-clone
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Or build and install locally:
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
gem build gem-clone.gemspec
|
|
15
|
-
gem install gem-clone-0.1.0.gem
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Prerequisites
|
|
19
|
-
|
|
20
|
-
This plugin works best with `ghq` but will automatically fall back to `git clone` if `ghq` is not available.
|
|
21
|
-
|
|
22
|
-
### Recommended: Install ghq
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
# Install ghq (example for macOS)
|
|
26
|
-
brew install ghq
|
|
27
|
-
|
|
28
|
-
# Or install via Go
|
|
29
|
-
go install github.com/x-motemen/ghq@latest
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Fallback: Git only
|
|
33
|
-
|
|
34
|
-
If `ghq` is not installed, the plugin will automatically use `git clone` instead. Make sure `git` is available in your PATH.
|
|
3
|
+
A RubyGems plugin that allows you to clone gem repositories by fetching source code URLs from gem metadata and using `git goget`, `ghq`, or `git clone`.
|
|
35
4
|
|
|
36
5
|
## Usage
|
|
37
6
|
|
|
7
|
+
### Basic Usage
|
|
8
|
+
|
|
38
9
|
```bash
|
|
39
10
|
# Clone a gem repository
|
|
40
11
|
gem clone sinatra
|
|
@@ -46,38 +17,28 @@ gem clone rails --verbose
|
|
|
46
17
|
gem clone rails --show-url
|
|
47
18
|
```
|
|
48
19
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
1. Fetch gem metadata from RubyGems.org API
|
|
52
|
-
2. Extract repository URL from:
|
|
53
|
-
- `source_code_uri` metadata
|
|
54
|
-
- `homepage_uri` (if it looks like a repository URL)
|
|
55
|
-
3. Clone the repository using:
|
|
56
|
-
- `ghq get` (preferred method if available)
|
|
57
|
-
- `git clone` (fallback if ghq is not available)
|
|
58
|
-
- Skip cloning if `--show-url` is specified
|
|
59
|
-
|
|
60
|
-
## Options
|
|
20
|
+
### Options
|
|
61
21
|
|
|
62
22
|
- `-v, --verbose`: Show verbose output during execution
|
|
63
23
|
- `-u, --show-url`: Display the repository URL without executing the clone operation
|
|
64
24
|
|
|
65
|
-
|
|
25
|
+
### Examples
|
|
66
26
|
|
|
67
27
|
```bash
|
|
68
|
-
# With
|
|
28
|
+
# With git goget available (preferred)
|
|
69
29
|
$ gem clone sinatra
|
|
70
|
-
Executing:
|
|
30
|
+
Executing: git goget https://github.com/sinatra/sinatra
|
|
71
31
|
Successfully cloned repository: https://github.com/sinatra/sinatra
|
|
72
32
|
|
|
73
|
-
#
|
|
33
|
+
# Fallback to ghq when git goget is not available
|
|
74
34
|
$ gem clone rails --verbose
|
|
75
35
|
Fetching gem metadata for 'rails'...
|
|
76
36
|
Found repository URL: https://github.com/rails/rails
|
|
37
|
+
git goget not found, falling back to ghq
|
|
77
38
|
Executing: ghq get https://github.com/rails/rails
|
|
78
39
|
Successfully cloned repository: https://github.com/rails/rails
|
|
79
40
|
|
|
80
|
-
# Fallback to git clone when ghq is
|
|
41
|
+
# Fallback to git clone when neither git goget nor ghq is available
|
|
81
42
|
$ gem clone rails --verbose
|
|
82
43
|
Fetching gem metadata for 'rails'...
|
|
83
44
|
Found repository URL: https://github.com/rails/rails
|
|
@@ -90,15 +51,193 @@ $ gem clone rails --show-url
|
|
|
90
51
|
https://github.com/rails/rails
|
|
91
52
|
```
|
|
92
53
|
|
|
54
|
+
## Installation
|
|
55
|
+
|
|
56
|
+
### From RubyGems
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
gem install gem-clone
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### From Source
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
git clone https://github.com/hsbt/gem-clone.git
|
|
66
|
+
cd gem-clone
|
|
67
|
+
gem build gem-clone.gemspec
|
|
68
|
+
gem install gem-clone-*.gem
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Prerequisites
|
|
72
|
+
|
|
73
|
+
This plugin works best with `git goget` but will automatically fall back to `ghq` or `git clone` if `git goget` is not available.
|
|
74
|
+
|
|
75
|
+
#### Recommended: Install git goget
|
|
76
|
+
|
|
77
|
+
[git goget](https://github.com/hsbt/git-goget) is a bash script for cloning Git repositories with additional features.
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Install git goget from GitHub
|
|
81
|
+
git clone https://github.com/hsbt/git-goget.git
|
|
82
|
+
cd git-goget
|
|
83
|
+
chmod +x git-goget
|
|
84
|
+
# Copy to a directory in your PATH
|
|
85
|
+
cp git-goget /usr/local/bin/
|
|
86
|
+
|
|
87
|
+
# Or download directly
|
|
88
|
+
curl -o git-goget https://raw.githubusercontent.com/hsbt/git-goget/main/git-goget
|
|
89
|
+
chmod +x git-goget
|
|
90
|
+
cp git-goget /usr/local/bin/
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### Alternative: Install ghq
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Install ghq (example for macOS)
|
|
97
|
+
brew install ghq
|
|
98
|
+
|
|
99
|
+
# Or install via Go
|
|
100
|
+
go install github.com/x-motemen/ghq@latest
|
|
101
|
+
|
|
102
|
+
# Or download binary from GitHub releases
|
|
103
|
+
# https://github.com/x-motemen/ghq/releases
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Fallback: Git only
|
|
107
|
+
|
|
108
|
+
If neither `git goget` nor `ghq` is installed, the plugin will automatically use `git clone` instead. Make sure `git` is available in your PATH.
|
|
109
|
+
|
|
110
|
+
## Technical Details
|
|
111
|
+
|
|
112
|
+
### How it works
|
|
113
|
+
|
|
114
|
+
The plugin performs the following steps:
|
|
115
|
+
|
|
116
|
+
1. **Fetch gem metadata** from RubyGems.org API (`/api/v1/gems/{gem_name}.json`)
|
|
117
|
+
2. **Extract repository URL** from gem metadata in this priority order:
|
|
118
|
+
- `source_code_uri` metadata field
|
|
119
|
+
- `homepage_uri` (if it looks like a repository URL)
|
|
120
|
+
3. **Normalize URL** by removing version-specific paths (e.g., `/tree/v1.0.0`, `/blob/main/README.md`)
|
|
121
|
+
4. **Clone repository** using:
|
|
122
|
+
- `git goget <url>` (preferred method if available)
|
|
123
|
+
- `ghq get <url>` (fallback if git goget is not available)
|
|
124
|
+
- `git clone <url>` (fallback if neither git goget nor ghq is available)
|
|
125
|
+
- Display URL only if `--show-url` option is specified
|
|
126
|
+
|
|
127
|
+
### URL Normalization
|
|
128
|
+
|
|
129
|
+
Gem metadata names the same repository in many shapes, so the plugin folds them to one before cloning. Common Git hosting service paths are removed:
|
|
130
|
+
|
|
131
|
+
- `/tree/*` → removed (GitHub, GitLab branches/tags)
|
|
132
|
+
- `/blob/*` → removed (GitHub, GitLab file views)
|
|
133
|
+
- `/commits/*` → removed (commit history pages)
|
|
134
|
+
- `/releases/*` → removed (release pages)
|
|
135
|
+
- `/issues/*` → removed (issue pages)
|
|
136
|
+
- `/pull/*` → removed (pull request pages)
|
|
137
|
+
- `/tags/*` → removed (tag pages)
|
|
138
|
+
- `/branches/*` → removed (branch pages)
|
|
139
|
+
|
|
140
|
+
So is anything else that does not name the repository itself:
|
|
141
|
+
|
|
142
|
+
- `#fragment` and `?query` → removed
|
|
143
|
+
- `http://` → `https://`
|
|
144
|
+
- `https://www.` → `https://`
|
|
145
|
+
- trailing `/` and `.git` → removed
|
|
146
|
+
|
|
147
|
+
**Examples:**
|
|
148
|
+
- `https://github.com/rails/rails/tree/v8.0.2` → `https://github.com/rails/rails`
|
|
149
|
+
- `http://www.github.com/rails/rails.git` → `https://github.com/rails/rails`
|
|
150
|
+
|
|
151
|
+
### Cross-platform Support
|
|
152
|
+
|
|
153
|
+
The plugin includes cross-platform command detection:
|
|
154
|
+
|
|
155
|
+
- **Unix/Linux/macOS**: Uses `which` command
|
|
156
|
+
- **Windows**: Uses `where` command
|
|
157
|
+
- **Error handling**: Gracefully handles missing commands
|
|
158
|
+
|
|
159
|
+
### Supported Repository Hosts
|
|
160
|
+
|
|
161
|
+
The plugin recognizes repository URLs from:
|
|
162
|
+
|
|
163
|
+
- GitHub (github.com)
|
|
164
|
+
- GitLab (gitlab.com)
|
|
165
|
+
- Bitbucket (bitbucket.org)
|
|
166
|
+
- Codeberg (codeberg.org)
|
|
167
|
+
- SourceHut (sourcehut.org)
|
|
168
|
+
|
|
169
|
+
### Requirements
|
|
170
|
+
|
|
171
|
+
- Ruby >= 2.7.0
|
|
172
|
+
- RubyGems
|
|
173
|
+
- `git goget` (recommended), `ghq` (alternative), or `git` (fallback)
|
|
174
|
+
|
|
93
175
|
## Development
|
|
94
176
|
|
|
95
|
-
|
|
177
|
+
### Setting up the development environment
|
|
96
178
|
|
|
97
179
|
```bash
|
|
180
|
+
# Clone the repository
|
|
181
|
+
git clone https://github.com/hsbt/gem-clone.git
|
|
182
|
+
cd gem-clone
|
|
183
|
+
|
|
184
|
+
# Install dependencies
|
|
185
|
+
bundle install
|
|
186
|
+
|
|
187
|
+
# Run tests
|
|
188
|
+
bundle exec rake test
|
|
189
|
+
|
|
190
|
+
# Build the gem
|
|
98
191
|
gem build gem-clone.gemspec
|
|
99
|
-
gem install gem-clone-0.1.0.gem
|
|
100
192
|
```
|
|
101
193
|
|
|
194
|
+
### Running Tests
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# Run all tests
|
|
198
|
+
bundle exec rake test
|
|
199
|
+
|
|
200
|
+
# Run specific test file
|
|
201
|
+
ruby -Ilib:test test/clone_command_test.rb
|
|
202
|
+
|
|
203
|
+
# Run with verbose output
|
|
204
|
+
ruby -Ilib:test test/clone_command_test.rb --verbose
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Contributing
|
|
208
|
+
|
|
209
|
+
1. Fork the repository
|
|
210
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
211
|
+
3. Make your changes and add tests
|
|
212
|
+
4. Run the test suite (`bundle exec rake test`)
|
|
213
|
+
5. Commit your changes (`git commit -am 'Add amazing feature'`)
|
|
214
|
+
6. Push to the branch (`git push origin feature/amazing-feature`)
|
|
215
|
+
7. Open a Pull Request
|
|
216
|
+
|
|
102
217
|
## License
|
|
103
218
|
|
|
104
|
-
|
|
219
|
+
This gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
MIT License
|
|
223
|
+
|
|
224
|
+
Copyright (c) 2024 Hiroshi SHIBATA
|
|
225
|
+
|
|
226
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
227
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
228
|
+
in the Software without restriction, including without limitation the rights
|
|
229
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
230
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
231
|
+
furnished to do so, subject to the following conditions:
|
|
232
|
+
|
|
233
|
+
The above copyright notice and this permission notice shall be included in all
|
|
234
|
+
copies or substantial portions of the Software.
|
|
235
|
+
|
|
236
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
237
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
238
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
239
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
240
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
241
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
242
|
+
SOFTWARE.
|
|
243
|
+
```
|
|
@@ -5,8 +5,11 @@ require 'uri'
|
|
|
5
5
|
require 'open3'
|
|
6
6
|
|
|
7
7
|
class Gem::Commands::CloneCommand < Gem::Command
|
|
8
|
+
# git goget answers with this when the repository cannot be reached at all.
|
|
9
|
+
GOGET_SKIPPED = 3
|
|
10
|
+
|
|
8
11
|
def initialize
|
|
9
|
-
super 'clone', 'Clone a gem repository using ghq'
|
|
12
|
+
super 'clone', 'Clone a gem repository using git goget, ghq, or git'
|
|
10
13
|
|
|
11
14
|
add_option('-v', '--verbose', 'Show verbose output') do |value, options|
|
|
12
15
|
options[:verbose] = true
|
|
@@ -24,8 +27,8 @@ class Gem::Commands::CloneCommand < Gem::Command
|
|
|
24
27
|
def description # :nodoc:
|
|
25
28
|
<<-EOF
|
|
26
29
|
The clone command fetches gem metadata from RubyGems.org and clones
|
|
27
|
-
the gem's source repository using
|
|
28
|
-
source_code_uri from the gem's metadata.
|
|
30
|
+
the gem's source repository using git goget (preferred), ghq, or git
|
|
31
|
+
based on the homepage or source_code_uri from the gem's metadata.
|
|
29
32
|
|
|
30
33
|
Examples:
|
|
31
34
|
gem clone sinatra
|
|
@@ -102,18 +105,22 @@ Examples:
|
|
|
102
105
|
def normalize_repository_url(url)
|
|
103
106
|
return url if url.nil? || url.empty?
|
|
104
107
|
|
|
105
|
-
normalized_url = url.
|
|
108
|
+
normalized_url = url.sub(/[#?].*/m, '')
|
|
109
|
+
normalized_url = normalized_url.sub(%r{\Ahttp://}, 'https://').sub(%r{\Ahttps://www\.}, 'https://')
|
|
110
|
+
normalized_url = normalized_url.gsub(%r{/(tree|blob|commits|releases|issues|pull|tags|branches)/.*$}, '')
|
|
106
111
|
|
|
107
|
-
normalized_url.chomp('/')
|
|
112
|
+
normalized_url.chomp('/').sub(/\.git\z/, '')
|
|
108
113
|
end
|
|
109
114
|
|
|
110
115
|
def clone_repository(url)
|
|
111
|
-
if command_available?('
|
|
116
|
+
if command_available?('git-goget')
|
|
117
|
+
clone_with_git_goget(url)
|
|
118
|
+
elsif command_available?('ghq')
|
|
112
119
|
clone_with_ghq(url)
|
|
113
120
|
elsif command_available?('git')
|
|
114
121
|
clone_with_git(url)
|
|
115
122
|
else
|
|
116
|
-
alert_error "
|
|
123
|
+
alert_error "None of 'git goget', 'ghq', or 'git' is available in your PATH. Please install one of them."
|
|
117
124
|
terminate_interaction 1
|
|
118
125
|
end
|
|
119
126
|
end
|
|
@@ -130,11 +137,28 @@ Examples:
|
|
|
130
137
|
end
|
|
131
138
|
end
|
|
132
139
|
|
|
140
|
+
def clone_with_git_goget(url)
|
|
141
|
+
say "Executing: git goget #{url}" if options[:verbose]
|
|
142
|
+
|
|
143
|
+
system("git", "goget", url)
|
|
144
|
+
|
|
145
|
+
case $?.exitstatus
|
|
146
|
+
when 0
|
|
147
|
+
say "Successfully cloned repository: #{url}"
|
|
148
|
+
when GOGET_SKIPPED
|
|
149
|
+
alert_error "Repository is unreachable: #{url}"
|
|
150
|
+
terminate_interaction 1
|
|
151
|
+
else
|
|
152
|
+
alert_error "Failed to clone repository with git goget."
|
|
153
|
+
terminate_interaction 1
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
133
157
|
def clone_with_ghq(url)
|
|
134
|
-
|
|
135
|
-
say "Executing: #{
|
|
158
|
+
say "git goget not found, falling back to ghq" if options[:verbose]
|
|
159
|
+
say "Executing: ghq get #{url}" if options[:verbose]
|
|
136
160
|
|
|
137
|
-
system(
|
|
161
|
+
system("ghq", "get", url)
|
|
138
162
|
|
|
139
163
|
if $?.success?
|
|
140
164
|
say "Successfully cloned repository: #{url}"
|
|
@@ -145,11 +169,10 @@ Examples:
|
|
|
145
169
|
end
|
|
146
170
|
|
|
147
171
|
def clone_with_git(url)
|
|
148
|
-
command = "git clone #{url}"
|
|
149
172
|
say "ghq not found, falling back to git clone" if options[:verbose]
|
|
150
|
-
say "Executing: #{
|
|
173
|
+
say "Executing: git clone #{url}" if options[:verbose]
|
|
151
174
|
|
|
152
|
-
system(
|
|
175
|
+
system("git", "clone", url)
|
|
153
176
|
|
|
154
177
|
if $?.success?
|
|
155
178
|
say "Successfully cloned repository: #{url}"
|