copiousfreetime / stickler

a tool to organize and maintain an internal gem distribution server
MIT License
143 stars 29 forks source link

Prototypic bundler-integration for Stickler #31

Closed bascht closed 10 years ago

bascht commented 10 years ago

This is a rough attempt to solve #13 and get the required gems from bundlers Gemfile by iterating trought the list of all dependencies. It might be useful to migrate repositories to a internal Stickler-server or to keep mirrored gems up to date via "bundle update + stickler bundle".

Example run

$ stickler bundle
Asking http://127.0.0.1:6789/ to mirror rspec-2.12.0 from rubygems.org : OK -> http://127.0.0.1:6789/gems/rspec-2.12.0.gem
Asking http://127.0.0.1:6789/ to mirror webmock-1.13.0 from rubygems.org : OK -> http://127.0.0.1:6789/gems/webmock-1.13.0.gem
Asking http://127.0.0.1:6789/ to mirror vcr-2.5.0 from rubygems.org : OK -> http://127.0.0.1:6789/gems/vcr-2.5.0.gem
Asking http://127.0.0.1:6789/ to mirror uglifier-2.1.2 from rubygems.org : OK -> http://127.0.0.1:6789/gems/uglifier-2.1.2.gem
Asking http://127.0.0.1:6789/ to mirror tzinfo-0.3.37 from rubygems.org : ERROR: gem tzinfo-0.3.37 already exists in remote repository
Asking http://127.0.0.1:6789/ to mirror treetop-1.4.14 from rubygems.org : ERROR: gem treetop-1.4.14 already exists in remote repository

[…]
copiousfreetime commented 10 years ago

Thanks @bascht. My initial thoughts back when I put this in here was to have it all done on the server side, and probably do it by pushing the Gemfile.lock and parsing that natively so as not to get the entire dependency of bundler in there just to parse a single text file and extract out the gem names and versions.

I do happen to like the immediate feedback on the client side with each gem's mirror result. What you have here is a good addition, although not exactly what I had in mind. And my mind may change.

I'm going to ponder the state of things for a bit and get back to you.

bascht commented 10 years ago

Hey @copiousfreetime! Thanks for your feedback. I actually do like the idea of parsing the whole Gemfile.lock on the server side (You can imagine the guilt I felt, inserting the require 'bundler' line :wink:). For now my little 'workaround' serves us well. I needed to convince our team to switch to Stickler and manually mirroring 30 Gemfiles with different gem versions would have gotten me into a hell of a mess. :grinning:.

Looking forward to see your approach - if I have some time left I may look into parsing the versions from the Gemfile.lock.

By the way - is there anything like a 'plugin' system to add new commands to stickler? Otherwise I could simply publish my additions as a separate gem, which would then just 'remote control' Stickler and fire the stickler mirror command.

jsmestad commented 10 years ago

@copiousfreetime I would love to see this functionality so we can replace our current approach of having devs push new gems to the gemserver by hand. Let me know if there is any more work needed towards here.

bascht commented 10 years ago

@jsmestad @copiousfreetime I've extracted those few lines from the PR and packed them into a separate gem: https://rubygems.org/gems/stickler-mirror / https://github.com/bascht/stickler-mirror.

It works for our approach, but I'd love to get some feedback. ;-)

copiousfreetime commented 10 years ago

@bascht I'd still like to have it parsed on the server side, or just parse it on the client side, I don't really want to have to include all of bundlers dependencies in stickler just to parse the Gemfile.

As for a plugin system, I don't have anything right now, I haven't done a sweep of ruby plugin systems in a while so I don't know what is really available. There is also which type of plugin, something on the client side or something on the server side.

@jsmestad what is needed is time, as always.

copiousfreetime commented 10 years ago

Maybe I should say what I would like to have done here to get it into stickler.

  1. Since it should really only need to parse the Gemfile.lock, that should be easy enough to do natively without needing to depend on Bundler as a whole. So, a class that parses Gemfile.lock and builds up a list of SpecLite instances.
  2. Start with doing it all on the client side like @bascht already has, but use the list from (1).
  3. Add in a server side handler that will do what is done on the client side but in the background. We'll need to add an api pat for this from the commandline to the server.

If we have (1) and (2) then that should satisfy most of the requirements for the time being and we can push a new release.

copiousfreetime commented 10 years ago

This or something like #13 will be resolved for version 2.4

copiousfreetime commented 10 years ago

@bascht @jsmestad Check out #13 and see if that will work for you.

The list of gems is done on the client side by parsing the Gemfile.lock given on the commandline to --mirror

% ruby -Ilib bin/stickler mirror --help
Pull a specific version of a gem from an upstream gem server
and store it in a stickler server. Either a specific version
must be specificied, or a Gemfile.lock must be used.

Usage: stickler mirror [options] --gem-version x.y.z gem
       stickler mirror [options] Gemfile.lock

  Options:
       --server, -s <s>:   The gem or stickler server URL
            --debug, -d:   Output debug information for the server interaction
     --upstream, -u <s>:   The upstream gem server from which to pull (default: https://rubygems.org)
  --gem-version, -g <s>:   The version of the gem to mirror
     --platform, -p <s>:   The platform of the gem to mirror (default: ruby)
             --help, -h:   Show this message
copiousfreetime commented 10 years ago

Version 2.4 released with this feature included.