rubygems-source 0.0.1
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.
- data/.gitignore +6 -0
- data/.gitmodules +3 -0
- data/Gemfile +4 -0
- data/README.md +111 -0
- data/Rakefile +11 -0
- data/config.ru.example +4 -0
- data/features/support/app.rb +5 -0
- data/features/support/env.rb +9 -0
- data/lib/rubygems-source/version.rb +5 -0
- data/lib/rubygems-source.rb +79 -0
- data/rubygems-source.gemspec +32 -0
- data/tmp/.gitignore +0 -0
- metadata +157 -0
data/.gitignore
ADDED
data/.gitmodules
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
rubygems-source 
|
|
2
|
+
===============
|
|
3
|
+
|
|
4
|
+
`rubygems-source` is a remote source server for Rubygems that implements the
|
|
5
|
+
core Rubygems gem source web API.
|
|
6
|
+
|
|
7
|
+
Use it to host private or local dev gem servers.
|
|
8
|
+
|
|
9
|
+
Usage
|
|
10
|
+
-----
|
|
11
|
+
|
|
12
|
+
### Start yr server ###
|
|
13
|
+
|
|
14
|
+
Create a `config.ru` like this (there's an example `config.ru.example`
|
|
15
|
+
included):
|
|
16
|
+
|
|
17
|
+
require "rubygems-source"
|
|
18
|
+
|
|
19
|
+
Rubygems::Source::App.public_folder = "/var/gems/" # or wherever
|
|
20
|
+
run Rubygems::Source::App
|
|
21
|
+
|
|
22
|
+
And rack up the `config.ru` with `passenger`, `thin`, `unicorn` etc.
|
|
23
|
+
|
|
24
|
+
Ensure `public_folder` is writeable by the server user.
|
|
25
|
+
|
|
26
|
+
Adapt `config.ru` to install Rack middleware if you need HTTP
|
|
27
|
+
authentication etc.
|
|
28
|
+
|
|
29
|
+
### Configure yr rubygems ###
|
|
30
|
+
|
|
31
|
+
You need to configure rubygems wherever you want to use your new source server.
|
|
32
|
+
|
|
33
|
+
If you use Bundler, add it to the top of your `Gemfile`s:
|
|
34
|
+
|
|
35
|
+
source "http://gems.example.com"
|
|
36
|
+
|
|
37
|
+
To make the new source server available to your entire Rubygems installation:
|
|
38
|
+
|
|
39
|
+
$ gem sources --add http://gems.example.com
|
|
40
|
+
|
|
41
|
+
You can also add the new source to your `.gemrc`s directly.
|
|
42
|
+
|
|
43
|
+
You can now find and install gems from the new source server.
|
|
44
|
+
|
|
45
|
+
$ gem list -r mygem
|
|
46
|
+
$ gem install mygem
|
|
47
|
+
|
|
48
|
+
You can also push gems to the server. **Be sure to specify the host**.
|
|
49
|
+
|
|
50
|
+
$ gem push pkg/mygem-0.0.2.gem --host http://gems.example.com
|
|
51
|
+
|
|
52
|
+
Check out
|
|
53
|
+
[rubygems-source-cli](https://github.com/kapoq/rubygems-source-cli)
|
|
54
|
+
for some patches to `gem yank` and `gem push` so they work better with
|
|
55
|
+
non-Rubygems.org sources.
|
|
56
|
+
|
|
57
|
+
Requirements
|
|
58
|
+
------------
|
|
59
|
+
|
|
60
|
+
* Rubygems
|
|
61
|
+
|
|
62
|
+
Install
|
|
63
|
+
-------
|
|
64
|
+
|
|
65
|
+
* `gem install rubygems-source`
|
|
66
|
+
|
|
67
|
+
or add it to your `Gemfile`:
|
|
68
|
+
|
|
69
|
+
* `gem "rubygems-source"`
|
|
70
|
+
|
|
71
|
+
Development
|
|
72
|
+
-----------
|
|
73
|
+
|
|
74
|
+
* Source hosted at [GitHub](https://github.com/kapoq/rubygems-source)
|
|
75
|
+
* Report issues/Questions/Feature requests on [GitHub Issues](https://github.com/kapoq/rubygems-source)
|
|
76
|
+
* CI at [Travis](http://travis-ci.org/#!/textgoeshere/rubygems-source)
|
|
77
|
+
|
|
78
|
+
Pull requests are very welcome! Make sure your patches are well tested. Please create a topic branch for every separate change
|
|
79
|
+
you make.
|
|
80
|
+
|
|
81
|
+
### Roadmap ###
|
|
82
|
+
|
|
83
|
+
* authenticate gem admin actions via API key
|
|
84
|
+
* implement gem dependency resolver
|
|
85
|
+
* show HTML list of gems/versions/links to rdoc at /
|
|
86
|
+
* remove Sintra dependency in favour of plain Rack for smaller footprint
|
|
87
|
+
* support legacy index/spec format?
|
|
88
|
+
|
|
89
|
+
### Testing ###
|
|
90
|
+
|
|
91
|
+
$ rake
|
|
92
|
+
|
|
93
|
+
Related projects
|
|
94
|
+
----------------
|
|
95
|
+
|
|
96
|
+
* [rubygems-source-cli](https://github.com/kapoq/rubygems-source-cli):
|
|
97
|
+
Patches to `gem push` and `gem yank` to make them work with
|
|
98
|
+
non-rubygems.org sources
|
|
99
|
+
[rubygems-source-features](https://github.com/kapoq/rubygems-source-features):
|
|
100
|
+
Cucumber features for Rubygems sources
|
|
101
|
+
* [rubygems.org](https://github.com/rubygems/rubygems.org):
|
|
102
|
+
Daddy
|
|
103
|
+
* [geminabox](https://github.com/cwninja/geminabox):
|
|
104
|
+
Very similar project, no `gem yank`, no tests of any kind
|
|
105
|
+
* [sinatra-rubygems](https://github.com/jnewland/sinatra-rubygems):
|
|
106
|
+
Replacement for `gem server` - no `gem push`, `gem yank` or resolver
|
|
107
|
+
|
|
108
|
+
Author
|
|
109
|
+
------
|
|
110
|
+
|
|
111
|
+
[Dave Nolan](https://github.com/textgoeshere)
|
data/Rakefile
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'bundler'
|
|
2
|
+
require 'rspec/core/rake_task'
|
|
3
|
+
require 'cucumber/rake/task'
|
|
4
|
+
|
|
5
|
+
Bundler::GemHelper.install_tasks
|
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
7
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
|
8
|
+
t.cucumber_opts = "features --format pretty"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
task :default => [:spec, :features]
|
data/config.ru.example
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require "rubygems/package"
|
|
2
|
+
require "rubygems/user_interaction"
|
|
3
|
+
require "rubygems/indexer"
|
|
4
|
+
require "sinatra/base"
|
|
5
|
+
|
|
6
|
+
module Rubygems
|
|
7
|
+
module Source
|
|
8
|
+
autoload :Version, "rubygems-source/version"
|
|
9
|
+
|
|
10
|
+
class App < Sinatra::Base
|
|
11
|
+
set :show_exceptions, false
|
|
12
|
+
set :raise_errors, true
|
|
13
|
+
|
|
14
|
+
helpers do
|
|
15
|
+
def path_to_gem(gem_file_name = "")
|
|
16
|
+
File.join(settings.public_folder, "gems", gem_file_name)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def clear_gem_specs_and_update_gem_indices
|
|
20
|
+
Gem.post_reset{ Gem::Specification.all = nil }
|
|
21
|
+
Gem::Indexer.new(settings.public_folder).generate_index
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def get_spec(data)
|
|
25
|
+
Gem::Package.open(StringIO.new(data), "r", nil) { |pkg| pkg.metadata }
|
|
26
|
+
rescue Gem::Package::FormatError
|
|
27
|
+
false
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# #
|
|
32
|
+
# # ROUTES
|
|
33
|
+
# #
|
|
34
|
+
|
|
35
|
+
# PUSH
|
|
36
|
+
post "/api/v1/gems" do
|
|
37
|
+
if spec = get_spec(request.body.read)
|
|
38
|
+
filename = path_to_gem("#{spec.original_name}.gem")
|
|
39
|
+
FileUtils.mkdir_p(path_to_gem) unless File.directory?(path_to_gem)
|
|
40
|
+
if File.exists?(filename)
|
|
41
|
+
"#{spec.original_name} already exists and will not be overwritten."
|
|
42
|
+
status 409
|
|
43
|
+
else
|
|
44
|
+
request.body.rewind
|
|
45
|
+
File.open(filename, "wb") { |f| f.write(request.body.read) }
|
|
46
|
+
clear_gem_specs_and_update_gem_indices
|
|
47
|
+
"#{spec.original_name} pushed. Have a nice day."
|
|
48
|
+
end
|
|
49
|
+
else
|
|
50
|
+
"Invalid gem"
|
|
51
|
+
status 403
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# YANK
|
|
56
|
+
delete "/api/v1/gems" do
|
|
57
|
+
requirements = params.dup
|
|
58
|
+
name = requirements.delete("gem_name")
|
|
59
|
+
version = requirements.delete("version")
|
|
60
|
+
# TODO: check required params present
|
|
61
|
+
platform = requirements.delete("platform")
|
|
62
|
+
candidates = Gem::Specification.find_all_by_name(name, "=#{version}")
|
|
63
|
+
gems_to_yank = if platform.nil? || platform == ""
|
|
64
|
+
candidates
|
|
65
|
+
else
|
|
66
|
+
candidates.select { |spec| spec.platform == platform }
|
|
67
|
+
end
|
|
68
|
+
unless gems_to_yank.empty?
|
|
69
|
+
gems_to_yank.each { |spec| FileUtils.rm(path_to_gem(spec.file_name)) }
|
|
70
|
+
clear_gem_specs_and_update_gem_indices
|
|
71
|
+
gems_to_yank.map { |spec| spec.original_name }.join(", ") + " yanked. Have a nice day."
|
|
72
|
+
else
|
|
73
|
+
"No matching gems found here"
|
|
74
|
+
status 404
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
+
require "rubygems-source/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = "rubygems-source"
|
|
7
|
+
s.version = Rubygems::Source::VERSION
|
|
8
|
+
s.authors = ["dave@kapoq.com"]
|
|
9
|
+
s.email = ["dave@kapoq.com"]
|
|
10
|
+
s.homepage = "https://github.com/kapoq/rubygems-source"
|
|
11
|
+
s.summary = "A Rubygems remote source server"
|
|
12
|
+
s.description = "A Rubygems remote source server that implements the core Rubygems web API (gem indicies, specs, push, and yank). Wins for local and private gem servers."
|
|
13
|
+
|
|
14
|
+
s.add_dependency "sinatra"
|
|
15
|
+
s.add_dependency "builder"
|
|
16
|
+
|
|
17
|
+
s.add_development_dependency "cucumber"
|
|
18
|
+
s.add_development_dependency "rspec"
|
|
19
|
+
s.add_development_dependency "guard-rspec"
|
|
20
|
+
s.add_development_dependency "rack-test"
|
|
21
|
+
s.add_development_dependency "rake"
|
|
22
|
+
if RUBY_PLATFORM =~ /linux/
|
|
23
|
+
s.add_development_dependency "rb-inotify"
|
|
24
|
+
s.add_development_dependency "libnotify"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
s.files = `git ls-files`.split("\n")
|
|
29
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
30
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
31
|
+
s.require_paths = ["lib"]
|
|
32
|
+
end
|
data/tmp/.gitignore
ADDED
|
File without changes
|
metadata
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rubygems-source
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- dave@kapoq.com
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2011-10-21 00:00:00.000000000Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: sinatra
|
|
16
|
+
requirement: &8184760 !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '0'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: *8184760
|
|
25
|
+
- !ruby/object:Gem::Dependency
|
|
26
|
+
name: builder
|
|
27
|
+
requirement: &8184140 !ruby/object:Gem::Requirement
|
|
28
|
+
none: false
|
|
29
|
+
requirements:
|
|
30
|
+
- - ! '>='
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: *8184140
|
|
36
|
+
- !ruby/object:Gem::Dependency
|
|
37
|
+
name: cucumber
|
|
38
|
+
requirement: &8183500 !ruby/object:Gem::Requirement
|
|
39
|
+
none: false
|
|
40
|
+
requirements:
|
|
41
|
+
- - ! '>='
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '0'
|
|
44
|
+
type: :development
|
|
45
|
+
prerelease: false
|
|
46
|
+
version_requirements: *8183500
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: rspec
|
|
49
|
+
requirement: &8182880 !ruby/object:Gem::Requirement
|
|
50
|
+
none: false
|
|
51
|
+
requirements:
|
|
52
|
+
- - ! '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
type: :development
|
|
56
|
+
prerelease: false
|
|
57
|
+
version_requirements: *8182880
|
|
58
|
+
- !ruby/object:Gem::Dependency
|
|
59
|
+
name: guard-rspec
|
|
60
|
+
requirement: &8182240 !ruby/object:Gem::Requirement
|
|
61
|
+
none: false
|
|
62
|
+
requirements:
|
|
63
|
+
- - ! '>='
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '0'
|
|
66
|
+
type: :development
|
|
67
|
+
prerelease: false
|
|
68
|
+
version_requirements: *8182240
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rack-test
|
|
71
|
+
requirement: &8181540 !ruby/object:Gem::Requirement
|
|
72
|
+
none: false
|
|
73
|
+
requirements:
|
|
74
|
+
- - ! '>='
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '0'
|
|
77
|
+
type: :development
|
|
78
|
+
prerelease: false
|
|
79
|
+
version_requirements: *8181540
|
|
80
|
+
- !ruby/object:Gem::Dependency
|
|
81
|
+
name: rake
|
|
82
|
+
requirement: &8180720 !ruby/object:Gem::Requirement
|
|
83
|
+
none: false
|
|
84
|
+
requirements:
|
|
85
|
+
- - ! '>='
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '0'
|
|
88
|
+
type: :development
|
|
89
|
+
prerelease: false
|
|
90
|
+
version_requirements: *8180720
|
|
91
|
+
- !ruby/object:Gem::Dependency
|
|
92
|
+
name: rb-inotify
|
|
93
|
+
requirement: &8179220 !ruby/object:Gem::Requirement
|
|
94
|
+
none: false
|
|
95
|
+
requirements:
|
|
96
|
+
- - ! '>='
|
|
97
|
+
- !ruby/object:Gem::Version
|
|
98
|
+
version: '0'
|
|
99
|
+
type: :development
|
|
100
|
+
prerelease: false
|
|
101
|
+
version_requirements: *8179220
|
|
102
|
+
- !ruby/object:Gem::Dependency
|
|
103
|
+
name: libnotify
|
|
104
|
+
requirement: &8178580 !ruby/object:Gem::Requirement
|
|
105
|
+
none: false
|
|
106
|
+
requirements:
|
|
107
|
+
- - ! '>='
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
110
|
+
type: :development
|
|
111
|
+
prerelease: false
|
|
112
|
+
version_requirements: *8178580
|
|
113
|
+
description: A Rubygems remote source server that implements the core Rubygems web
|
|
114
|
+
API (gem indicies, specs, push, and yank). Wins for local and private gem servers.
|
|
115
|
+
email:
|
|
116
|
+
- dave@kapoq.com
|
|
117
|
+
executables: []
|
|
118
|
+
extensions: []
|
|
119
|
+
extra_rdoc_files: []
|
|
120
|
+
files:
|
|
121
|
+
- .gitignore
|
|
122
|
+
- .gitmodules
|
|
123
|
+
- Gemfile
|
|
124
|
+
- README.md
|
|
125
|
+
- Rakefile
|
|
126
|
+
- config.ru.example
|
|
127
|
+
- features/support/app.rb
|
|
128
|
+
- features/support/env.rb
|
|
129
|
+
- lib/rubygems-source.rb
|
|
130
|
+
- lib/rubygems-source/version.rb
|
|
131
|
+
- rubygems-source.gemspec
|
|
132
|
+
- tmp/.gitignore
|
|
133
|
+
homepage: https://github.com/kapoq/rubygems-source
|
|
134
|
+
licenses: []
|
|
135
|
+
post_install_message:
|
|
136
|
+
rdoc_options: []
|
|
137
|
+
require_paths:
|
|
138
|
+
- lib
|
|
139
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
140
|
+
none: false
|
|
141
|
+
requirements:
|
|
142
|
+
- - ! '>='
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '0'
|
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
|
+
none: false
|
|
147
|
+
requirements:
|
|
148
|
+
- - ! '>='
|
|
149
|
+
- !ruby/object:Gem::Version
|
|
150
|
+
version: '0'
|
|
151
|
+
requirements: []
|
|
152
|
+
rubyforge_project:
|
|
153
|
+
rubygems_version: 1.8.11
|
|
154
|
+
signing_key:
|
|
155
|
+
specification_version: 3
|
|
156
|
+
summary: A Rubygems remote source server
|
|
157
|
+
test_files: []
|