From 9e2b7fb69020b7ec050eaed9ede5ed6a31ef8b40 Mon Sep 17 00:00:00 2001 From: sophia Date: Mon, 27 Apr 2020 10:19:42 -0400 Subject: [PATCH] Autocomplete command --- lib/vagrant/cli.rb | 12 ---- lib/vagrant/util/install_cli_autocomplete.rb | 16 +++++ .../commands/autocomplete/command/install.rb | 34 ++++++++++ plugins/commands/autocomplete/command/root.rb | 64 +++++++++++++++++++ plugins/commands/autocomplete/plugin.rb | 18 ++++++ .../autocomplete/commands/install_test.rb | 29 +++++++++ 6 files changed, 161 insertions(+), 12 deletions(-) create mode 100644 plugins/commands/autocomplete/command/install.rb create mode 100644 plugins/commands/autocomplete/command/root.rb create mode 100644 plugins/commands/autocomplete/plugin.rb create mode 100644 test/unit/plugins/commands/autocomplete/commands/install_test.rb diff --git a/lib/vagrant/cli.rb b/lib/vagrant/cli.rb index 06c7f8f20..9421c9c2b 100644 --- a/lib/vagrant/cli.rb +++ b/lib/vagrant/cli.rb @@ -2,7 +2,6 @@ require 'log4r' require 'optparse' require 'vagrant/util/experimental' -require 'vagrant/util/install_cli_autocomplete' module Vagrant # Manages the command line interface to Vagrant. @@ -31,17 +30,6 @@ module Vagrant return 0 end - if @main_args.include?("-install-autocomplete") - # Install autocomplete scripts - written_paths = Vagrant::Util::InstallCLIAutocomplete.install - if written_paths && written_paths.length > 0 - @env.ui.info(I18n.t("vagrant.autocomplete.installed", paths: written_paths.join("\n- "))) - else - @env.ui.info(I18n.t("vagrant.autocomplete.not_installed")) - end - return 0 - end - if @sub_command == "login" $stderr.puts "WARNING: This command has been deprecated and aliased to `vagrant cloud auth login`" end diff --git a/lib/vagrant/util/install_cli_autocomplete.rb b/lib/vagrant/util/install_cli_autocomplete.rb index a45d623a2..83469ca33 100644 --- a/lib/vagrant/util/install_cli_autocomplete.rb +++ b/lib/vagrant/util/install_cli_autocomplete.rb @@ -16,6 +16,12 @@ module Vagrant @logger = Log4r::Logger.new("vagrant::util::install_shell_config") end + # Searches a users home dir for a shell config file based on a + # given home dir and a configured set of config paths. If there + # are multiple config paths, it will return the first match. + # + # @param [string] path to users home dir + # @return [string] path to shell config file if exists def shell_installed(home) @logger.info("Searching for config in home #{home}") @config_paths.each do |path| @@ -28,6 +34,11 @@ module Vagrant return nil end + # Searches a given file for the existence of a set prepend string. + # This can be used to find if vagrant has inserted some strings to a file + # + # @param [string] path to a file (config file) + # @return [boolean] true if the prepend string is found in the file def is_installed(path) File.foreach(path) do |line| if line.include?(@prepend_string) @@ -38,6 +49,11 @@ module Vagrant return false end + # Given a path to the users home dir, will install some given strings + # marked by a prepend and append string + # + # @param [string] path to users home dir + # @return [string] path to shell config file that was modified if exists def install(home) path = shell_installed(home) if path && !is_installed(path) diff --git a/plugins/commands/autocomplete/command/install.rb b/plugins/commands/autocomplete/command/install.rb new file mode 100644 index 000000000..97e8f791e --- /dev/null +++ b/plugins/commands/autocomplete/command/install.rb @@ -0,0 +1,34 @@ +require 'optparse' + +require 'vagrant/util/install_cli_autocomplete' + +module VagrantPlugins + module CommandAutocomplete + module Command + class Install < Vagrant.plugin("2", :command) + def execute + options = {} + + opts = OptionParser.new do |o| + o.banner = "Usage: vagrant autocomplete install [-h]" + end + + # Parse the options + argv = parse_options(opts) + return if !argv + raise Vagrant::Errors::CLIInvalidUsage, help: opts.help.chomp if argv.length > 0 + + written_paths = Vagrant::Util::InstallCLIAutocomplete.install + if written_paths && written_paths.length > 0 + @env.ui.info(I18n.t("vagrant.autocomplete.installed", paths: written_paths.join("\n- "))) + else + @env.ui.info(I18n.t("vagrant.autocomplete.not_installed")) + end + + # Success, exit status 0 + 0 + end + end + end + end +end diff --git a/plugins/commands/autocomplete/command/root.rb b/plugins/commands/autocomplete/command/root.rb new file mode 100644 index 000000000..4f1d58201 --- /dev/null +++ b/plugins/commands/autocomplete/command/root.rb @@ -0,0 +1,64 @@ +require "optparse" +require 'vagrant/util/install_cli_autocomplete' + +module VagrantPlugins + module CommandAutocomplete + module Command + class Root < Vagrant.plugin("2", :command) + def self.synopsis + "manages autocomplete: installation, removal, etc." + end + + def initialize(argv, env) + super + + @main_args, @sub_command, @sub_args = split_main_and_subcommand(argv) + + @subcommands = Vagrant::Registry.new + @subcommands.register(:install) do + require File.expand_path("../install", __FILE__) + Install + end + end + + def execute + if @main_args.include?("-h") || @main_args.include?("--help") + # Print the help for all the box commands. + return help + end + + # If we reached this far then we must have a subcommand. If not, + # then we also just print the help and exit. + command_class = @subcommands.get(@sub_command.to_sym) if @sub_command + return help if !command_class || !@sub_command + @logger.debug("Invoking command class: #{command_class} #{@sub_args.inspect}") + + # Initialize and execute the command class + command_class.new(@sub_args, @env).execute + end + + def help + opts = OptionParser.new do |opts| + opts.banner = "Usage: vagrant autoinstall " + opts.separator "" + opts.separator "Available subcommands:" + + # Add the available subcommands as separators in order to print them + # out as well. + keys = [] + @subcommands.each { |key, value| keys << key.to_s } + + keys.sort.each do |key| + opts.separator " #{key}" + end + + opts.separator "" + opts.separator "For help on any individual subcommand run `vagrant autoinstall -h`" + end + + @env.ui.info(opts.help, prefix: false) + end + end + end + end +end diff --git a/plugins/commands/autocomplete/plugin.rb b/plugins/commands/autocomplete/plugin.rb new file mode 100644 index 000000000..46255e217 --- /dev/null +++ b/plugins/commands/autocomplete/plugin.rb @@ -0,0 +1,18 @@ +require "vagrant" + + +module VagrantPlugins + module CommandAutocomplete + class Plugin < Vagrant.plugin("2") + name "autocomplete command" + description <<-DESC + The `autocomplete` manipulates Vagrant the autocomplete feature. + DESC + + command("autocomplete") do + require File.expand_path("../command/root", __FILE__) + Command::Root + end + end + end +end diff --git a/test/unit/plugins/commands/autocomplete/commands/install_test.rb b/test/unit/plugins/commands/autocomplete/commands/install_test.rb new file mode 100644 index 000000000..5ed2b3b9d --- /dev/null +++ b/test/unit/plugins/commands/autocomplete/commands/install_test.rb @@ -0,0 +1,29 @@ +require File.expand_path("../../../../../base", __FILE__) + +require Vagrant.source_root.join("plugins/commands/autocomplete/command/install") + +describe VagrantPlugins::CommandAutocomplete::Command::Install do + include_context "unit" + + let(:argv) { [] } + let(:iso_env) do + # We have to create a Vagrantfile so there is a root path + env = isolated_environment + env.vagrantfile("") + env.create_vagrant_env + end + + subject { described_class.new(argv, iso_env) } + + let(:action_runner) { double("action_runner") } + + before do + allow(iso_env).to receive(:action_runner).and_return(action_runner) + end + + context "with no arguments" do + it "returns without errors" do + expect(subject.execute).to be(0) + end + end +end