Skip to content

Commit

Permalink
feat: Add support for the move command
Browse files Browse the repository at this point in the history
Move command allows for moving a package to a different pack or between start/opt
  • Loading branch information
pusewicz committed Mar 16, 2024
1 parent 9284d7c commit 0cc2388
Show file tree
Hide file tree
Showing 11 changed files with 251 additions and 7 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,25 @@ To use the gem, you can run the following command:

# Will install to the default `plugins` pack directory under `start`
$ vimpk install dense-analysis/ale
Installed dense-analysis/ale to /Users/johndoe/.vim/pack/plugins/start/ale. Took 0.767983 seconds.

# Will install to the `colors` pack directory under `opt`
$ vimpk install sainnhe/sonokai --pack colors --opt
Installed sainnhe/sonokai to /Users/johndoe/.vim/pack/colors/opt/sonokai. Took 0.844782 seconds.

#### Move a plugin

# Will move to the `linting` pack directory under `start`
$ vimpk move ale --pack linting
Moved ale to /Users/johndoe/.vim/pack/linting/start/ale.

# Will move to `opt`
$ vimpk move ale --opt
Moved ale to /Users/johndoe/.vim/pack/plugins/opt/ale.

# Will move to `start`
$ vimpk move ale --start
Moved ale to /Users/johndoe/.vim/pack/plugins/start/ale.

#### Update all plugins

Expand Down
7 changes: 6 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
require "bundler/gem_tasks"
require "minitest/test_task"

Minitest::TestTask.create
Minitest::TestTask.create(:test) do |t|
t.libs << "test"
t.libs << "lib"
t.warning = true
t.test_globs = ["test/**/test_*.rb"]
end

if RUBY_VERSION >= "2.7"
require "standard/rake"
Expand Down
109 changes: 109 additions & 0 deletions bin/bundle
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

#
# This file was generated by Bundler.
#
# The application 'bundle' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require "rubygems"

m = Module.new do
module_function

def invoked_as_script?
File.expand_path($0) == File.expand_path(__FILE__)
end

def env_var_version
ENV["BUNDLER_VERSION"]
end

def cli_arg_version
return unless invoked_as_script? # don't want to hijack other binstubs
return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
bundler_version = nil
update_index = nil
ARGV.each_with_index do |a, i|
if update_index && update_index.succ == i && a.match?(Gem::Version::ANCHORED_VERSION_PATTERN)
bundler_version = a
end
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
bundler_version = $1
update_index = i
end
bundler_version
end

def gemfile
gemfile = ENV["BUNDLE_GEMFILE"]
return gemfile if gemfile && !gemfile.empty?

File.expand_path("../Gemfile", __dir__)
end

def lockfile
lockfile =
case File.basename(gemfile)
when "gems.rb" then gemfile.sub(/\.rb$/, ".locked")
else "#{gemfile}.lock"
end
File.expand_path(lockfile)
end

def lockfile_version
return unless File.file?(lockfile)
lockfile_contents = File.read(lockfile)
return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
Regexp.last_match(1)
end

def bundler_requirement
@bundler_requirement ||=
env_var_version ||
cli_arg_version ||
bundler_requirement_for(lockfile_version)
end

def bundler_requirement_for(version)
return "#{Gem::Requirement.default}.a" unless version

bundler_gem_version = Gem::Version.new(version)

bundler_gem_version.approximate_recommendation
end

def load_bundler!
ENV["BUNDLE_GEMFILE"] ||= gemfile

activate_bundler
end

def activate_bundler
gem_error = activation_error_handling do
gem "bundler", bundler_requirement
end
return if gem_error.nil?
require_error = activation_error_handling do
require "bundler/version"
end
return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
exit 42
end

def activation_error_handling
yield
nil
rescue StandardError, LoadError => e
e
end
end

m.load_bundler!

if m.invoked_as_script?
load Gem.bin_path("bundler", "bundle")
end
27 changes: 27 additions & 0 deletions bin/rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

#
# This file was generated by Bundler.
#
# The application 'rake' is installed as part of a gem, and
# this file is here to facilitate running it.
#

ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)

bundle_binstub = File.expand_path("bundle", __dir__)

if File.file?(bundle_binstub)
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
load(bundle_binstub)
else
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
end
end

require "rubygems"
require "bundler/setup"

load Gem.bin_path("rake", "rake")
27 changes: 27 additions & 0 deletions bin/standardrb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

#
# This file was generated by Bundler.
#
# The application 'standardrb' is installed as part of a gem, and
# this file is here to facilitate running it.
#

ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)

bundle_binstub = File.expand_path("bundle", __dir__)

if File.file?(bundle_binstub)
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
load(bundle_binstub)
else
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
end
end

require "rubygems"
require "bundler/setup"

load Gem.bin_path("standard", "standardrb")
1 change: 1 addition & 0 deletions lib/vimpk.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class Error < StandardError; end
autoload :Git, "vimpk/git"
autoload :Install, "vimpk/install"
autoload :Job, "vimpk/job"
autoload :Move, "vimpk/move"
autoload :Options, "vimpk/options"
autoload :Remove, "vimpk/remove"
autoload :ThreadPool, "vimpk/thread_pool"
Expand Down
17 changes: 14 additions & 3 deletions lib/vimpk/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def initialize(argv)
@command = determine_command
rescue OptionParser::MissingArgument, OptionParser::InvalidOption => e
puts e.message
abort("Use --help for usage information")
abort "Use --help for usage information"
end

def call
Expand All @@ -31,12 +31,15 @@ def determine_command
case name
when "i", "install"
:install_command
when "mv", "move"
:move_command
when "u", "update"
:update_command
when "rm", "remove"
:remove_command
else
raise ArgumentError, "Unknown command: #{name}"
puts colorize("Unknown command: #{name}", color: :red)
abort "Use --help for usage information"
end
end

Expand All @@ -55,6 +58,14 @@ def install_command(package = nil)
puts colorize("Error: #{e.message}", color: :red)
end

def move_command(name = nil)
move = Move.new(name, @options[:path], @options[:pack], @options[:type])
move.call
puts colorize("Moved #{name} to #{move.dest}.", color: :green)
rescue Move::PackageNotFoundError, Move::MultiplePackagesFoundError, ArgumentError => e
abort colorize(e.message, color: :red)
end

def update_command
update = Update.new(@options[:path])
puts "Updating #{update.plugins.size} packages in #{@options[:path]}…"
Expand Down Expand Up @@ -106,7 +117,7 @@ def remove_command(name = nil)
Remove.new(name, @options[:path]).call

puts colorize("Package #{name} removed.", color: :green)
rescue ArgumentError, VimPK::Remove::PackageNotFound => e
rescue ArgumentError, VimPK::Remove::PackageNotFoundError => e
abort colorize(e.message, color: :red)
end
end
Expand Down
41 changes: 41 additions & 0 deletions lib/vimpk/move.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require "fileutils"

module VimPK
class Move
PackageNotFoundError = Class.new(StandardError)
MultiplePackagesFoundError = Class.new(StandardError)

attr_reader :dest

def initialize(name, path, pack = nil, type = nil)
@name = name || raise(ArgumentError, "Package name is required")
raise ArgumentError, "New pack or type is required" unless pack || type
@path = path
@pack = pack
@type = type
end

def call
glob = Dir.glob(File.join(@path, "*", "{start,opt}", @name))

if glob.empty?
raise PackageNotFoundError, "Package #{@name} not found in #{@path}."
elsif glob.size > 1
raise MultiplePackagesFoundError, "Multiple packages #{@name} found in #{glob.join(" and ")}."
else
source = glob.first
current_type = File.basename(File.dirname(source))
current_pack = File.basename(File.dirname(File.dirname(source)))
@dest = File.join(@path, @pack || current_pack, @type || current_type, @name)

if File.exist?(dest)
raise ArgumentError, "Package #{@name} already exists in #{dest}."
else
FileUtils.mkdir_p(File.dirname(dest))
end

FileUtils.mv(source, dest)
end
end
end
end
1 change: 1 addition & 0 deletions lib/vimpk/options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def initialize(argv)
parser.separator ""
parser.separator "Commands:"
parser.separator " i|install REPO/NAME [--opt|--start] [--pack=PATH] [--path=PATH] Install a package"
parser.separator " mv|move Move a package"
parser.separator " u|update Update all packages"
parser.separator " rm|remove NAME Remove all occurrences of a package"
end
Expand Down
4 changes: 2 additions & 2 deletions lib/vimpk/remove.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module VimPK
class Remove
PackageNotFound = Class.new(StandardError)
PackageNotFoundError = Class.new(StandardError)

def initialize(name, path)
@name = name || raise(ArgumentError, "Package name is required")
Expand All @@ -13,7 +13,7 @@ def call
glob = Dir.glob(File.join(@path, "*", "{start,opt}", @name))

if glob.empty?
raise PackageNotFound, "Package #{@name} not found in #{@path}."
raise PackageNotFoundError, "Package #{@name} not found in #{@path}."
else
glob.each do |dir|
FileUtils.rm_rf(dir)
Expand Down
8 changes: 7 additions & 1 deletion test/test_cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@ class TestCLI < Minitest::Test
def test_valid_command
assert_equal :install_command, VimPK::CLI.new(["i"]).command
assert_equal :install_command, VimPK::CLI.new(["install"]).command
assert_equal :move_command, VimPK::CLI.new(["mv"]).command
assert_equal :move_command, VimPK::CLI.new(["move"]).command
assert_equal :update_command, VimPK::CLI.new(["u"]).command
assert_equal :update_command, VimPK::CLI.new(["update"]).command
assert_equal :remove_command, VimPK::CLI.new(["rm"]).command
assert_equal :remove_command, VimPK::CLI.new(["remove"]).command
end

def test_invalid_command
assert_raises(ArgumentError) { VimPK::CLI.new(["foo"]) }
out, _err = capture_io do
VimPK::CLI.new(["foo"])
end

assert_equal(/Unknown command: foo/, out)
end
end

0 comments on commit 0cc2388

Please sign in to comment.