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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88c04c0a3f92b224d8cf69412f3a93c6daeb829bc89749dd712874e88bd86531
4
- data.tar.gz: f50157ba3e8559bfe70903f08c5804451eea29b015dc1b9aa9c4e895bc50aef3
3
+ metadata.gz: 836f42b5a4924b0e9d94246ff6d12bb2f39faa30c51647d8443f75a4f1b98656
4
+ data.tar.gz: 22c882c0be0897264b54cbf865e9ba234cd7ec05d778ece19431c1158c6e8577
5
5
  SHA512:
6
- metadata.gz: c025fe44200548cc80821344aa8e930a71ef8b4bdea7001f2fb1ef7b5833e3694774803524f71b29a13b9c66e0d84f6b1e738463cf05c872d6fb179378e8f404
7
- data.tar.gz: 513e70c10abe50e0655dbf065672bb36564648567dc1086e6d72abc0203b91d37ee731e0ba896077762366cf137e84ad51123c7e4828da40fb24f9a99a27fc4f
6
+ metadata.gz: e911bd7cf6c713b46e3e9ca34da2edd34c2af8e6988e308ace4b403d7526a7722abc009f1b8c655f06f0da76fa5522cafffa82bceeaa8a2995dc2e80f1b60500
7
+ data.tar.gz: fb3c3a11745f66da76dc3db82173d3b01c611e5905578a6f3feeddac926bf8faa4208ca0c39ab95e6f5d2e8a1846ddf8dfdc9b16c3f477e6cd260b8c17a1819b
data/README.md CHANGED
@@ -1,40 +1,11 @@
1
- # RubyGems Clone Plugin
1
+ # gem-clone
2
2
 
3
- A RubyGems plugin that allows you to clone gem repositories using `ghq` based on gem metadata.
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
- The command will:
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
- ## Examples
25
+ ### Examples
66
26
 
67
27
  ```bash
68
- # With ghq available
28
+ # With git goget available (preferred)
69
29
  $ gem clone sinatra
70
- Executing: ghq get https://github.com/sinatra/sinatra
30
+ Executing: git goget https://github.com/sinatra/sinatra
71
31
  Successfully cloned repository: https://github.com/sinatra/sinatra
72
32
 
73
- # With verbose output
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 not available
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
- After checking out the repo, run tests and build the gem:
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
- The gem is available as open source under the terms of the MIT License.
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 ghq based on the homepage or
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.gsub(%r{/(tree|blob|commits|releases|issues|pull|tags|branches)/.*$}, '')
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?('ghq')
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 "Neither 'ghq' nor 'git' is available in your PATH. Please install one of them."
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
- command = "ghq get #{url}"
135
- say "Executing: #{command}" if options[:verbose]
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(command)
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: #{command}" if options[:verbose]
173
+ say "Executing: git clone #{url}" if options[:verbose]
151
174
 
152
- system(command)
175
+ system("git", "clone", url)
153
176
 
154
177
  if $?.success?
155
178
  say "Successfully cloned repository: #{url}"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gem-clone
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hiroshi SHIBATA