10
votes

Vérifier la version d'un gemme avec Bundler de l'intérieur Ruby

Y a-t-il un moyen de vérifier que j'ai la dernière version d'un gemme de l'intérieur d'un programme Ruby? C'est-à-dire, est-ce qu'il y a un moyen de faire pundle obsolète # {gemname} programmatiquement?

J'ai essayé de regarder le code source de Bundler mais je n'ai pas pu trouver de manière directe. Actuellement je fais cela, ce qui est fragile, lent et si inélégant: xxx


4 commentaires

Merci gars, de nombreuses réponses confirment mes conclusions: il n'y a pas d'API à faire cela. J'en ai choisi une base en ce sens qu'elle fournit une pièce de code de travail pour atteindre cette tâche.


Je pense que la réponse que vous avez choisie a des gotchas. Il y a une sortie 1 qui mettrait fin à votre exécution de votre programme. Avez-vous été capable de faire fonctionner ce code? J'ai eu une erreur en essayant de l'essayer.


Ils viennent d'introduire le Quitter 1 entre versions 1.2.x et 1.3.x, alors cela nécessite maintenant un peu de correction de singe pour fonctionner.


J'ai extrait BUNDLE 8 / code> dans une méthode réutilisable sans la sortie et les sorties de la console. Je pense que cela devrait être plus propre que le singe patching "sortie" ou échanger le flux de sortie. Voir ma réponse mise à jour pour le lien avec le code testé.


6 Réponses :


0
votes

BUNDLE CHECK Listez les gemmes à ce jour, vous voudrez peut-être l'utiliser.


1 commentaires

Ma question concerne la gestion de l'intérieur rubis, par programme.



4
votes

Il n'y a pas de moyen programmatique d'utilisation de la commande à valeurdée à Bundler, car le code est dans un fichier Thor CLI qui imprime la sortie à l'utilisateur. Les tests de Bundler émettent également la commande au système et vérifient la sortie ( Lien vers Numéro de page TESTS ).

Il convient d'être assez simple d'écrire votre propre méthode pour refléter ce que la méthode à cli.rb fait, cependant. Voir le code en surbrillance ici: Lien vers la méthode obsolète Bundler Source . Supprimer les lignes avec Bundler.ui et renvoie true / False en fonction de la valeur de out_count

Mise à jour : J'ai extraite "paquet à jour" dans une méthode réutilisable sans la sortie de la console et les sorties. Vous pouvez trouver le gist ici: Lien vers Gist . J'ai testé cela sur Bundler 1.3 et il semble fonctionner.


2 commentaires

Malheureusement, cela va finir par être le seul moyen de le faire de manière programmatique. Je suis surpris de la façon dont le Bundler mal écrit est. Pas de séparation des préoccupations du tout; Le code de l'interface utilisateur est complètement étroitement liée à la logique de vérification de la version. C'est un peu triste de regarder.


@Jimstewart, je suis à peu près sûr qu'ils accepteront une contribution avec quelques refacteurs.



0
votes

hmmm, sonne comme si vous pouviez souhaiter Bundle Afficher ou gem env


0 commentaires

0
votes

décevant, cela semble étonnamment difficile.

Il y a un couple de Ouvrir Problèmes à Bundler où la ligne officielle semble être:

À ce stade, il n'y a pas d'API de rubis documenté. C'est quelque chose qui figure sur notre liste, cependant.

regarder via le code source Bundler cli.rb , il est assez clair que cela va être délicat d'appeler de rubis ou de reproduire le code de manière sensée.

Les méthodes d'appel de CLI seront difficiles, car elles sont saupoudrées avec Appels pour quitter .

reproduire le code ne semble pas amusant non plus, car il y a beaucoup de logique baundler là-bas.

bonne chance!


0 commentaires

6
votes

Un moyen d'éviter l'exécution externe:

pour Bundler 1.2.x P>

require 'bundler/cli'
require 'bundler/friendly_errors'

# let's cheat the CLI class with fake exit method
module Bundler
  class CLI 
    desc 'exit', 'fake exit' # this is required by Thor
    def exit(*); end         # simply do nothing
  end 
end

# intercepting $stdout into a StringIO
old_stdout, $stdout = $stdout, StringIO.new 

# running the same code run in the 'bundler outdated' utility
Bundler.with_friendly_errors { Bundler::CLI.start(['outdated', 'rails']) }

# storing the output
output = $stdout.string 

# restoring $stdout
$stdout = old_stdout     


2 commentaires

J'ai eu une erreur lors de l'exécution de cela. De plus, obsolète a un sournois sortie 1 dedans. Je ne pense pas que cela puisse travailler comme ça.


Hmm. Vrai. Cela fonctionne avec Bundler 1.2.3 et des pauses avec 1.3.5.



0
votes

Vérification du code source du dernier code source Bundler

Je pourrais proposer ce p>

https://github.com/carlhuda/bundler/blob/master/lib/bundler/cli.rb#l398 P>

$ irb
1.9.3p327 :001 > require 'bundler'
 => true 
1.9.3p327 :002 > def outdated_gems(gem_name,options={})
1.9.3p327 :003?>   options[:source] ||= 'https://rubygems.org'
1.9.3p327 :004?>   sources = Array(options[:source])
1.9.3p327 :005?>   current_spec= Bundler.load.specs[gem_name].first
1.9.3p327 :006?>   raise "not found in Gemfile" if current_spec.nil?
1.9.3p327 :007?>   definition = Bundler.definition(:gems => [gem_name], :sources => sources)
1.9.3p327 :008?>   options["local"] ? definition.resolve_with_cache! : definition.resolve_remotely!
1.9.3p327 :009?>       active_spec = definition.index[gem_name].sort_by { |b| b.version }
1.9.3p327 :010?>    if !current_spec.version.prerelease? && !options[:pre] && active_spec.size > 1
1.9.3p327 :011?>             active_spec = active_spec.delete_if { |b| b.respond_to?(:version) && b.version.prerelease? }
1.9.3p327 :012?>         end
1.9.3p327 :013?>       active_spec = active_spec.last
1.9.3p327 :014?>       raise "Error" if active_spec.nil?
1.9.3p327 :015?>   outdated = Gem::Version.new(active_spec.version) > Gem::Version.new(current_spec.version)
1.9.3p327 :016?>   {:outdated=>outdated,:current_spec_version=>current_spec.version.to_s,:latest_version=>active_spec.version.to_s}
1.9.3p327 :017?>   end
 => nil 
1.9.3p327 :018 > 
1.9.3p327 :019 >   
1.9.3p327 :020 >   
1.9.3p327 :021 >   
1.9.3p327 :022 >   outdated_gems('rake')
 => {:outdated=>true, :current_spec_version=>"10.0.3", :latest_version=>"10.0.4"} 


0 commentaires