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 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: p> pundle obsolète # {gemname} code> programmatiquement?
6 Réponses :
BUNDLE CHECK CODE> Listez les gemmes à ce jour, vous voudrez peut-être l'utiliser. P>
Ma question concerne la gestion de l'intérieur rubis, par programme.
Il n'y a pas de moyen programmatique d'utilisation de la commande Il convient d'être assez simple d'écrire votre propre méthode pour refléter ce que la méthode code> code> à cli.rb fait, cependant. Voir le code en surbrillance ici: Lien vers la méthode obsolète Bundler Source . Supprimer les lignes avec à valeurdée code> à 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 CODE> TESTS
). P>
Bundler.ui code> et renvoie true / False en fonction de la valeur de
out_count code> p> p>
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.
hmmm, sonne comme si vous pouviez souhaiter Bundle Afficher code> ou
gem env code> p>
décevant, cela semble étonnamment difficile. P>
Il y a un couple de Ouvrir Problèmes à Bundler où la ligne officielle semble être: p>
À ce stade, il n'y a pas d'API de rubis documenté. C'est quelque chose qui figure sur notre liste, cependant. P> blockQuote>
regarder via le code source Bundler cli.rb a >, il est assez clair que cela va être délicat d'appeler de rubis ou de reproduire le code de manière sensée. P>
Les méthodes d'appel de CLI seront difficiles, car elles sont saupoudrées avec Appels pour quitter . P>
reproduire le code ne semble pas amusant non plus, car il y a beaucoup de logique baundler là-bas. P>
bonne chance! p>
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
J'ai eu une erreur lors de l'exécution de cela. De plus, obsolète code> a un sournois
sortie 1 code> 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.
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"}
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 code> 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 Code> 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é.