Skip to content

Commit

Permalink
Merge pull request tonsky#131 from randycoulman/support-latest-specs-…
Browse files Browse the repository at this point in the history
…endpoint

Support the latest_specs endpoint
  • Loading branch information
smellsblue authored Jan 23, 2017
2 parents 271fa4e + 5744bd2 commit 04372d8
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 13 deletions.
13 changes: 11 additions & 2 deletions lib/gemstash/db/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,17 @@ def self.slug(params)
end
end

def self.for_spec_collection(prerelease: false)
where(indexed: true, prerelease: prerelease).association_join(:rubygem)
def self.for_spec_collection(prerelease: false, latest: false)
versions = where(indexed: true, prerelease: prerelease).association_join(:rubygem)
latest ? select_latest(versions) : versions
end

def self.select_latest(versions)
versions.
all.
group_by {|version| [version.rubygem_id, version.platform] }.
values.
map {|gem_versions| gem_versions.max_by {|version| Gem::Version.new(version.number) } }
end

def self.find_by_spec(gem_id, spec)
Expand Down
9 changes: 5 additions & 4 deletions lib/gemstash/gem_source/private_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,16 @@ def serve_gem(id)
end
end

def serve_latest_specs
halt 403, "Not yet supported"
end

def serve_specs
params[:prerelease] = false
protected(Gemstash::SpecsBuilder)
end

def serve_latest_specs
params[:latest] = true
protected(Gemstash::SpecsBuilder)
end

def serve_prerelease_specs
params[:prerelease] = true
protected(Gemstash::SpecsBuilder)
Expand Down
15 changes: 10 additions & 5 deletions lib/gemstash/specs_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,23 @@ class SpecsBuilder
attr_reader :result

def self.serve(app)
prerelease = app.params[:prerelease]
prerelease = app.params.fetch(:prerelease, false)
latest = app.params.fetch(:latest, false)
app.content_type "application/octet-stream"
new(app.auth, prerelease: prerelease).serve
new(app.auth, prerelease: prerelease, latest: latest).serve
end

def self.invalidate_stored
storage = Gemstash::Storage.for("private").for("specs_collection")
storage.resource("specs.4.8.gz").delete(:specs)
storage.resource("latest_specs.4.8.gz").delete(:specs)
storage.resource("prerelease_specs.4.8.gz").delete(:specs)
end

def initialize(auth, prerelease: false)
def initialize(auth, prerelease: false, latest: false)
@auth = auth
@prerelease = prerelease
@latest = latest
end

def serve
Expand All @@ -44,7 +47,9 @@ def storage
end

def fetch_resource
if @prerelease
if @latest
storage.resource("latest_specs.4.8.gz")
elsif @prerelease
storage.resource("prerelease_specs.4.8.gz")
else
storage.resource("specs.4.8.gz")
Expand All @@ -61,7 +66,7 @@ def fetch_from_storage
end

def fetch_versions
@versions = Gemstash::DB::Version.for_spec_collection(prerelease: @prerelease).map(&:to_spec)
@versions = Gemstash::DB::Version.for_spec_collection(prerelease: @prerelease, latest: @latest).map(&:to_spec)
end

def marshal
Expand Down
75 changes: 73 additions & 2 deletions spec/gemstash/specs_builder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
expect(Marshal.load(gunzip(result))).to eq([])
end

it "returns an empty latest result" do
result = Gemstash::SpecsBuilder.new(auth, latest: true).serve
expect(Marshal.load(gunzip(result))).to eq([])
end

it "returns an empty prerelease result" do
result = Gemstash::SpecsBuilder.new(auth, prerelease: true).serve
expect(Marshal.load(gunzip(result))).to eq([])
Expand All @@ -33,6 +38,12 @@
["other-example", Gem::Version.new("0.1.0"), "ruby"]]
end

let(:expected_latest_specs) do
[["example", Gem::Version.new("0.0.2"), "ruby"],
["example", Gem::Version.new("0.0.2"), "java"],
["other-example", Gem::Version.new("0.1.0"), "ruby"]]
end

before do
gem_id = insert_rubygem("example")
insert_version(gem_id, "0.0.1")
Expand All @@ -47,6 +58,11 @@
expect(Marshal.load(gunzip(result))).to match_array(expected_specs)
end

it "marshals and gzips the latest versions" do
result = Gemstash::SpecsBuilder.new(auth, latest: true).serve
expect(Marshal.load(gunzip(result))).to match_array(expected_latest_specs)
end

it "returns an empty prerelease result" do
result = Gemstash::SpecsBuilder.new(auth, prerelease: true).serve
expect(Marshal.load(gunzip(result))).to eq([])
Expand Down Expand Up @@ -75,6 +91,11 @@
expect(Marshal.load(gunzip(result))).to eq([])
end

it "returns an empty latest result" do
result = Gemstash::SpecsBuilder.new(auth, latest: true).serve
expect(Marshal.load(gunzip(result))).to eq([])
end

it "marshals and gzips the prerelease versions" do
result = Gemstash::SpecsBuilder.new(auth, prerelease: true).serve
expect(Marshal.load(gunzip(result))).to match_array(expected_prerelease_specs)
Expand All @@ -89,6 +110,12 @@
["other-example", Gem::Version.new("0.1.0"), "ruby"]]
end

let(:expected_latest_specs) do
[["example", Gem::Version.new("0.0.2"), "ruby"],
["example", Gem::Version.new("0.0.2"), "java"],
["other-example", Gem::Version.new("0.1.0"), "ruby"]]
end

let(:expected_prerelease_specs) do
[["example", Gem::Version.new("0.0.2.rc1"), "ruby"],
["example", Gem::Version.new("0.0.2.rc2"), "ruby"],
Expand All @@ -114,6 +141,11 @@
expect(Marshal.load(gunzip(result))).to match_array(expected_specs)
end

it "marshals and gzips the latest versions" do
result = Gemstash::SpecsBuilder.new(auth, latest: true).serve
expect(Marshal.load(gunzip(result))).to match_array(expected_latest_specs)
end

it "marshals and gzips the prerelease versions" do
result = Gemstash::SpecsBuilder.new(auth, prerelease: true).serve
expect(Marshal.load(gunzip(result))).to match_array(expected_prerelease_specs)
Expand All @@ -128,6 +160,12 @@
["other-example", Gem::Version.new("0.1.0"), "ruby"]]
end

let(:expected_latest_specs) do
[["example", Gem::Version.new("0.0.2"), "ruby"],
["example", Gem::Version.new("0.0.2"), "java"],
["other-example", Gem::Version.new("0.1.0"), "ruby"]]
end

let(:expected_prerelease_specs) do
[["example", Gem::Version.new("0.0.2.rc1"), "ruby"],
["example", Gem::Version.new("0.0.2.rc2"), "ruby"],
Expand Down Expand Up @@ -159,6 +197,11 @@
expect(Marshal.load(gunzip(result))).to match_array(expected_specs)
end

it "marshals and gzips the latest versions" do
result = Gemstash::SpecsBuilder.new(auth, latest: true).serve
expect(Marshal.load(gunzip(result))).to match_array(expected_latest_specs)
end

it "marshals and gzips the prerelease versions" do
result = Gemstash::SpecsBuilder.new(auth, prerelease: true).serve
expect(Marshal.load(gunzip(result))).to match_array(expected_prerelease_specs)
Expand All @@ -167,7 +210,8 @@

context "with a new spec pushed" do
let(:initial_specs) { [["example", Gem::Version.new("0.0.1"), "ruby"]] }
let(:specs_after_push) { initial_specs + [["example", Gem::Version.new("0.1.0"), "ruby"]] }
let(:new_specs) { [["example", Gem::Version.new("0.1.0"), "ruby"]] }
let(:specs_after_push) { initial_specs + new_specs }

before do
Gemstash::Authorization.authorize(auth_key, "all")
Expand All @@ -182,6 +226,14 @@
result = Gemstash::SpecsBuilder.new(auth).serve
expect(Marshal.load(gunzip(result))).to match_array(specs_after_push)
end

it "busts the latest cache" do
result = Gemstash::SpecsBuilder.new(auth, latest: true).serve
expect(Marshal.load(gunzip(result))).to match_array(initial_specs)
Gemstash::GemPusher.new(auth, read_gem("example", "0.1.0")).serve
result = Gemstash::SpecsBuilder.new(auth, latest: true).serve
expect(Marshal.load(gunzip(result))).to match_array(new_specs)
end
end

context "with a new prerelease spec pushed" do
Expand Down Expand Up @@ -209,6 +261,8 @@
["example", Gem::Version.new("0.1.0"), "ruby"]]
end

let(:latest_specs) { [["example", Gem::Version.new("0.1.0"), "ruby"]] }

let(:specs_after_yank) { [["example", Gem::Version.new("0.0.1"), "ruby"]] }

before do
Expand All @@ -225,6 +279,14 @@
result = Gemstash::SpecsBuilder.new(auth).serve
expect(Marshal.load(gunzip(result))).to match_array(specs_after_yank)
end

it "busts the latest cache" do
result = Gemstash::SpecsBuilder.new(auth, latest: true).serve
expect(Marshal.load(gunzip(result))).to match_array(latest_specs)
Gemstash::GemYanker.new(auth, "example", "0.1.0").serve
result = Gemstash::SpecsBuilder.new(auth, latest: true).serve
expect(Marshal.load(gunzip(result))).to match_array(specs_after_yank)
end
end

context "with a prerelease spec yanked" do
Expand Down Expand Up @@ -253,7 +315,8 @@

context "with a spec unyanked" do
let(:initial_specs) { [["example", Gem::Version.new("0.0.1"), "ruby"]] }
let(:specs_after_unyank) { initial_specs + [["example", Gem::Version.new("0.1.0"), "ruby"]] }
let(:new_specs) { [["example", Gem::Version.new("0.1.0"), "ruby"]] }
let(:specs_after_unyank) { initial_specs + new_specs }

before do
Gemstash::Authorization.authorize(auth_key, "all")
Expand All @@ -270,6 +333,14 @@
result = Gemstash::SpecsBuilder.new(auth).serve
expect(Marshal.load(gunzip(result))).to match_array(specs_after_unyank)
end

it "busts the latest cache" do
result = Gemstash::SpecsBuilder.new(auth, latest: true).serve
expect(Marshal.load(gunzip(result))).to match_array(initial_specs)
Gemstash::GemUnyanker.new(auth, "example", "0.1.0").serve
result = Gemstash::SpecsBuilder.new(auth, latest: true).serve
expect(Marshal.load(gunzip(result))).to match_array(new_specs)
end
end

context "with a prerelease spec unyanked" do
Expand Down
6 changes: 6 additions & 0 deletions spec/integration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@
to exit_success.and_output(/speaker \(0.1.0\)/)
end

it "finds the latest version of private gems", db_transaction: false do
env = { "HOME" => env_dir }
expect(execute("gem", ["search", "-r", "speaker", "--clear-sources", "--source", host], env: env)).
to exit_success.and_output(/speaker \(0.1.0\)/)
end

it "finds private gems when just the private source is configured", db_transaction: false do
skip "this doesn't work because Rubygems sends /specs.4.8.gz instead of /private/specs.4.8.gz"
env = { "HOME" => env_dir }
Expand Down

0 comments on commit 04372d8

Please sign in to comment.