From e28947f18d2610e745f02bc9dbead3728c36cdcc Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 26 Aug 2010 21:56:38 -0700 Subject: [PATCH] Use I18n gem for string database. Refactor exceptions to use I18n. --- Gemfile.lock | 2 ++ lib/vagrant.rb | 4 +++ lib/vagrant/command/box.rb | 4 +-- lib/vagrant/command/helpers.rb | 8 ++--- lib/vagrant/command/package.rb | 6 ++-- lib/vagrant/command/ssh.rb | 4 +-- lib/vagrant/command/ssh_config.rb | 4 +-- lib/vagrant/errors.rb | 60 +++++++++++++++++++++++++++---- templates/locales/en.yml | 11 ++++++ test/locales/en.yml | 5 +++ test/test_helper.rb | 3 ++ test/vagrant/errors_test.rb | 27 ++++++++++++++ vagrant.gemspec | 1 + 13 files changed, 119 insertions(+), 20 deletions(-) create mode 100644 templates/locales/en.yml create mode 100644 test/locales/en.yml create mode 100644 test/vagrant/errors_test.rb diff --git a/Gemfile.lock b/Gemfile.lock index 71de2b5db..138cc92b7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -19,6 +19,7 @@ PATH vagrant (0.6.0.dev) archive-tar-minitar (= 0.5.2) erubis (~> 2.6.6) + i18n (~> 0.4.1) json (~> 1.4.6) mario (~> 0.0.6) net-scp (~> 1.0.3) @@ -38,6 +39,7 @@ GEM abstract (>= 1.0.0) ffi (0.6.3) rake (>= 0.8.7) + i18n (0.4.1) json (1.4.6) mario (0.0.6) mocha (0.9.8) diff --git a/lib/vagrant.rb b/lib/vagrant.rb index 9bfb557e9..ac9b5af51 100644 --- a/lib/vagrant.rb +++ b/lib/vagrant.rb @@ -1,4 +1,5 @@ require 'json' +require 'i18n' require 'virtualbox' require 'vagrant/errors' require 'vagrant/util/glob_loader' @@ -23,6 +24,9 @@ module Vagrant end end +# Default I18n to load the en locale +I18n.load_path << File.expand_path("templates/locales/en.yml", Vagrant.source_root) + # Load them up. One day we'll convert this to autoloads. Today # is not that day. Low hanging fruit for anyone wishing to do it. libdir = File.expand_path("lib/vagrant", Vagrant.source_root) diff --git a/lib/vagrant/command/box.rb b/lib/vagrant/command/box.rb index c2e6e7617..cb87c980d 100644 --- a/lib/vagrant/command/box.rb +++ b/lib/vagrant/command/box.rb @@ -11,14 +11,14 @@ module Vagrant desc "remove NAME", "Remove a box from the system" def remove(name) b = Box.find(env, name) - raise BoxNotFound.new("Box '#{name}' could not be found.") if !b + raise BoxNotFound.new(:name => name) if !b b.destroy end desc "repackage NAME", "Repackage an installed box into a `.box` file." def repackage(name) b = Box.find(env, name) - raise BoxNotFound.new("Box '#{name}' could not be found.") if !b + raise BoxNotFound.new(:name => name) if !b b.repackage end diff --git a/lib/vagrant/command/helpers.rb b/lib/vagrant/command/helpers.rb index a14a83658..626dc73cb 100644 --- a/lib/vagrant/command/helpers.rb +++ b/lib/vagrant/command/helpers.rb @@ -4,13 +4,13 @@ module Vagrant # Initializes the environment by pulling the environment out of # the configuration hash and sets up the UI if necessary. def initialize_environment(args, options, config) - raise CLIMissingEnvironment.new("This command requires that a Vagrant environment be properly passed in as the last parameter.") if !config[:env] + raise CLIMissingEnvironment.new if !config[:env] @env = config[:env] @env.ui = UI::Shell.new(@env, shell) if !@env.ui.is_a?(UI::Shell) end def require_environment - raise NoEnvironmentError.new("No Vagrant environment detected. Run `vagrant init` to set one up.") if !env.root_path + raise NoEnvironmentError.new if !env.root_path end # This returns an array of {VM} objects depending on the arguments @@ -22,9 +22,9 @@ module Vagrant if env.multivm? return env.vms.values if !self.name vm = env.vms[self.name.to_sym] - raise VMNotFoundError.new("A VM by the name of `#{self.name}` was not found.") if !vm + raise VMNotFoundError.new(:name => self.name) if !vm else - raise MultiVMEnvironmentRequired.new("A multi-vm environment is required for name specification to a command.") if self.name + raise MultiVMEnvironmentRequired.new if self.name vm = env.vms.values.first end diff --git a/lib/vagrant/command/package.rb b/lib/vagrant/command/package.rb index 36cab487d..e2e025fb3 100644 --- a/lib/vagrant/command/package.rb +++ b/lib/vagrant/command/package.rb @@ -16,14 +16,14 @@ module Vagrant def package_base vm = VM.find(options[:base], env) - raise VMNotFoundError.new("Specified base VM not found: #{options[:base]}") if !vm.created? + raise BaseVMNotFoundError.new(:name => options[:base]) if !vm.created? package_vm(vm) end def package_target - raise MultiVMTargetRequired.new("`vagrant package` requires the name of the VM to package in a multi-vm environment.") if target_vms.length > 1 + raise MultiVMTargetRequired.new(:command => "package") if target_vms.length > 1 vm = target_vms.first - raise VMNotCreatedError.new("The VM must be created to package it. Run `vagrant up` first.") if !vm.created? + raise VMNotCreatedError.new if !vm.created? package_vm(vm) end diff --git a/lib/vagrant/command/ssh.rb b/lib/vagrant/command/ssh.rb index c4859fb27..d7405b2cd 100644 --- a/lib/vagrant/command/ssh.rb +++ b/lib/vagrant/command/ssh.rb @@ -25,14 +25,14 @@ module Vagrant end def ssh_connect - raise VMNotCreatedError.new("The VM must be created for SSH to work. Please run `vagrant up`.") if !ssh_vm.created? + raise VMNotCreatedError.new if !ssh_vm.created? ssh_vm.ssh.connect end def ssh_vm @ssh_vm ||= begin vm = self.name.nil? && env.multivm? ? env.primary_vm : nil - raise MultiVMTargetRequired.new("A target or primary VM must be specified for SSH in a multi-vm environment.") if !vm && target_vms.length > 1 + raise MultiVMTargetRequired.new(:command => "ssh") if !vm && target_vms.length > 1 vm = target_vms.first if !vm vm end diff --git a/lib/vagrant/command/ssh_config.rb b/lib/vagrant/command/ssh_config.rb index ad7ca8a58..07424dc2e 100644 --- a/lib/vagrant/command/ssh_config.rb +++ b/lib/vagrant/command/ssh_config.rb @@ -6,9 +6,9 @@ module Vagrant register "ssh_config" def execute - raise MultiVMTargetRequired.new("Please specify a single VM to get SSH config info.") if target_vms.length > 1 + raise MultiVMTargetRequired.new(:command => "ssh_config") if target_vms.length > 1 vm = target_vms.first - raise VMNotCreatedError.new("The VM must be created to get the SSH info.") if !vm.created? + raise VMNotCreatedError.new if !vm.created? env.ui.info Util::TemplateRenderer.render("ssh_config", { :host_key => options[:host] || "vagrant", diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index f4ad6fc77..135d08126 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -1,15 +1,61 @@ module Vagrant + # Main superclass of any errors in Vagrant. This provides some + # convenience methods for setting the status code and error key. + # The status code is used by the `vagrant` executable as the + # error code, and the error key is used as a default message from + # I18n. class VagrantError < StandardError def self.status_code(code = nil) define_method(:status_code) { code } end + + def self.error_key(key=nil) + define_method(:error_key) { key } + end + + def initialize(message=nil, *args) + message = I18n.t("vagrant.errors.#{error_key}", message) if respond_to?(:error_key) + super + end end - class CLIMissingEnvironment < VagrantError; status_code(1); end - class BoxNotFound < VagrantError; status_code(2); end - class NoEnvironmentError < VagrantError; status_code(3); end - class VMNotFoundError < VagrantError; status_code(4); end - class MultiVMEnvironmentRequired < VagrantError; status_code(5); end - class VMNotCreatedError < VagrantError; status_code(6); end - class MultiVMTargetRequired < VagrantError; status_code(7); end + class BaseVMNotFound < VagrantError + status_code(6) + error_key(:base_vm_not_found) + end + + class BoxNotFound < VagrantError + status_code(2) + error_key(:box_not_found) + end + + class CLIMissingEnvironment < VagrantError + status_code(1) + error_key(:cli_missing_environment) + end + + class MultiVMEnvironmentRequired < VagrantError + status_code(5) + error_key(:multi_vm_required) + end + + class MultiVMTargetRequired < VagrantError + status_code(7) + error_key(:multi_vm_target_required) + end + + class NoEnvironmentError < VagrantError + status_code(3) + error_key(:no_environment) + end + + class VMNotCreatedError < VagrantError + status_code(6) + error_key(:vm_creation_required) + end + + class VMNotFoundError < VagrantError + status_code(4) + error_key(:vm_not_found) + end end diff --git a/templates/locales/en.yml b/templates/locales/en.yml new file mode 100644 index 000000000..4a02864a8 --- /dev/null +++ b/templates/locales/en.yml @@ -0,0 +1,11 @@ +en: + vagrant: + errors: + base_vm_not_found: The base VM with the name '%{name}' was not found. + box_not_found: Box '%{name}' could not be found. + cli_missing_env: This command requires that a Vagrant environment be properly passed in as the last parameter. + multi_vm_required: A multi-vm environment is required for name specification to this command. + multi_vm_target_required: `vagrant %{command}` requires a specific VM name to target in a multi-VM environment. + no_env: No Vagrant environment detected. Run `vagrant init` to set one up. + vm_creation_required: VM must be created before running this command. Run `vagrant up` first. + vm_not_found: A VM by the name of %{name} was not found. diff --git a/test/locales/en.yml b/test/locales/en.yml new file mode 100644 index 000000000..9e6528136 --- /dev/null +++ b/test/locales/en.yml @@ -0,0 +1,5 @@ +en: + vagrant: + errors: + test_key: This is a test key + test_key_with_interpolation: This is a test key that says %{key} \ No newline at end of file diff --git a/test/test_helper.rb b/test/test_helper.rb index 078353b57..07079bef5 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -10,6 +10,9 @@ require 'mocha' # Add this folder to the load path for "test_helper" $:.unshift(File.dirname(__FILE__)) +# Add the I18n locale for tests +I18n.load_path << File.expand_path("../locales/en.yml", __FILE__) + class Test::Unit::TestCase # Mocks an environment, setting it up with the given config. def mock_environment diff --git a/test/vagrant/errors_test.rb b/test/vagrant/errors_test.rb new file mode 100644 index 000000000..5f2e5cce7 --- /dev/null +++ b/test/vagrant/errors_test.rb @@ -0,0 +1,27 @@ +require "test_helper" + +class ErrorsTest < Test::Unit::TestCase + setup do + @super = Vagrant::VagrantError + end + + should "set the given status code" do + klass = Class.new(@super) { status_code(4) } + assert_equal 4, klass.new.status_code + end + + should "use the given message if no set error key" do + klass = Class.new(@super) + assert_equal "foo", klass.new("foo").message + end + + should "use the translation from I18n if specified" do + klass = Class.new(@super) { error_key(:test_key) } + assert_equal I18n.t("vagrant.errors.test_key"), klass.new.message + end + + should "use the translation with the options specified if key given" do + klass = Class.new(@super) { error_key(:test_key_with_interpolation) } + assert_equal I18n.t("vagrant.errors.test_key_with_interpolation", :key => "yo"), klass.new(:key => "yo").message + end +end diff --git a/vagrant.gemspec b/vagrant.gemspec index 824c03138..950c7fc39 100644 --- a/vagrant.gemspec +++ b/vagrant.gemspec @@ -19,6 +19,7 @@ Gem::Specification.new do |s| s.add_dependency "mario", "~> 0.0.6" s.add_dependency "net-ssh", "~> 2.0.23" s.add_dependency "net-scp", "~> 1.0.3" + s.add_dependency "i18n", "~> 0.4.1" s.add_dependency "thor" s.add_dependency "radar" s.add_dependency "virtualbox", "~> 0.7.3"