vpm 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.rvmrc +1 -0
- data/Gemfile.lock +13 -5
- data/README.md +13 -11
- data/Rakefile +26 -6
- data/bin/vpm +1 -1
- data/lib/transaction.rb +27 -0
- data/lib/vpm.rb +52 -16
- data/lib/vpm/command_options.rb +15 -0
- data/lib/vpm/command_options/abstract_command_options.rb +25 -0
- data/lib/vpm/command_options/install.rb +18 -0
- data/lib/vpm/command_options/list.rb +9 -0
- data/lib/vpm/commands.rb +18 -0
- data/lib/vpm/commands/install.rb +37 -0
- data/lib/vpm/commands/install_all_plugins.rb +8 -0
- data/lib/vpm/commands/invalid_command.rb +10 -0
- data/lib/vpm/commands/list.rb +8 -0
- data/lib/vpm/commands/setup.rb +63 -0
- data/lib/vpm/git.rb +17 -0
- data/lib/vpm/manifest_parser.rb +19 -1
- data/lib/vpm/plugin.rb +29 -5
- data/lib/vpm/plugins.rb +55 -0
- data/lib/vpm/runner.rb +55 -0
- data/lib/vpm/tasks.rb +7 -0
- data/lib/vpm/tasks/clone_pathogen.rb +13 -0
- data/lib/vpm/tasks/create_autoload_dir.rb +5 -0
- data/lib/vpm/tasks/create_bundle_dir.rb +5 -0
- data/lib/vpm/tasks/create_directory.rb +16 -0
- data/lib/vpm/tasks/create_our_rc_file.rb +16 -0
- data/lib/vpm/tasks/inject_our_load_script.rb +28 -0
- data/lib/vpm/tasks/move_pathogen_file.rb +17 -0
- data/lib/vpm/version.rb +1 -1
- data/spec/commands/install_spec.rb +10 -0
- data/spec/manifest_parser_spec.rb +3 -13
- data/spec/plugins_spec.rb +41 -0
- data/spec/spec_helper.rb +2 -4
- data/spec/tasks/create_bundle_dir_spec.rb +26 -0
- data/spec/tasks/create_directory_spec.rb +33 -0
- data/spec/tasks/create_our_rc_file_spec.rb +31 -0
- data/spec/tasks/inject_our_load_script_spec.rb +39 -0
- data/spec/tasks/move_pathogen_file_spec.rb +42 -0
- data/spec/transaction_spec.rb +65 -0
- data/vpm.gemspec +6 -4
- metadata +63 -17
- data/lib/vpm/git_plugin.rb +0 -22
- data/spec/git_plugin_spec.rb +0 -12
- data/spec/vpm_test.rb +0 -13
data/lib/vpm/git.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module VPM
|
2
|
+
module Git
|
3
|
+
def self.clone(repo, dir)
|
4
|
+
`git clone #{repo} #{dir}`
|
5
|
+
$?.to_i == 0
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.checkout_tag(tag)
|
9
|
+
`git checkout -b #{tag} #{tag}`
|
10
|
+
$?.to_i == 0
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.current_revision
|
14
|
+
`git rev-parse --verify HEAD`.strip
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/vpm/manifest_parser.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
module VPM
|
2
2
|
class ManifestParser
|
3
|
+
def self.parse(content)
|
4
|
+
self.new.parse(content)
|
5
|
+
end
|
6
|
+
|
3
7
|
def initialize
|
4
8
|
@plugins = {}
|
5
9
|
end
|
@@ -10,7 +14,21 @@ module VPM
|
|
10
14
|
end
|
11
15
|
|
12
16
|
def plugin(name, options = {})
|
13
|
-
|
17
|
+
# FIXME hardcode to install for now
|
18
|
+
options = VPM::CommandOptions.parse!("install", options_to_args(options))
|
19
|
+
type = options.delete(:type)
|
20
|
+
@plugins[name] = Plugin.new(name, type, options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def options_to_args(options)
|
24
|
+
args = []
|
25
|
+
|
26
|
+
if options[:git]
|
27
|
+
args += ["--git", options[:git]]
|
28
|
+
args += ["--tag", options[:tag]] if options[:tag]
|
29
|
+
end
|
30
|
+
|
31
|
+
args
|
14
32
|
end
|
15
33
|
|
16
34
|
def plugins
|
data/lib/vpm/plugin.rb
CHANGED
@@ -1,16 +1,40 @@
|
|
1
1
|
module VPM
|
2
2
|
class Plugin
|
3
|
-
|
3
|
+
def self.from_hash(hash)
|
4
|
+
self.new(hash[:name], hash[:type], hash[:options])
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_reader :name, :type, :options
|
4
8
|
|
5
|
-
def initialize(name, options = {})
|
9
|
+
def initialize(name, type, options = {})
|
6
10
|
@name = name
|
11
|
+
@type = type
|
7
12
|
@options = options
|
8
13
|
end
|
9
14
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
15
|
+
def run_command(command)
|
16
|
+
result = false
|
17
|
+
plugins = VPM.plugins
|
18
|
+
if command == "install"
|
19
|
+
result = VPM::Commands::Install.run(self) unless plugins.installed?(name)
|
20
|
+
plugins.plugin_installed(self) if result
|
21
|
+
end
|
22
|
+
|
23
|
+
result
|
24
|
+
end
|
25
|
+
|
26
|
+
["install", "update", "remove"].each do |cmd|
|
27
|
+
define_method(cmd) do
|
28
|
+
run_command(cmd)
|
13
29
|
end
|
14
30
|
end
|
31
|
+
|
32
|
+
def to_hash
|
33
|
+
{
|
34
|
+
:name => name,
|
35
|
+
:type => type,
|
36
|
+
:options => options
|
37
|
+
}
|
38
|
+
end
|
15
39
|
end
|
16
40
|
end
|
data/lib/vpm/plugins.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module VPM
|
4
|
+
class Plugins
|
5
|
+
attr_reader :all, :installed_plugins, :removed_plugins
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@all = []
|
9
|
+
@installed_plugins = []
|
10
|
+
@removed_plugins = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def installed?(plugin_name)
|
14
|
+
all.find { |p| p.name == plugin_name }
|
15
|
+
end
|
16
|
+
|
17
|
+
def changed?
|
18
|
+
installed_plugins.any? || removed_plugins.any?
|
19
|
+
end
|
20
|
+
|
21
|
+
def plugin_installed(plugin)
|
22
|
+
all << plugin
|
23
|
+
installed_plugins << plugin
|
24
|
+
end
|
25
|
+
|
26
|
+
def plugin_removed(plugin)
|
27
|
+
all.delete(plugin)
|
28
|
+
removed_plugins << plugin
|
29
|
+
end
|
30
|
+
|
31
|
+
def load(content)
|
32
|
+
deserialized_content = YAML::load(content)
|
33
|
+
@all = deserialized_content ? deserialized_content.collect { |hash| Plugin.from_hash(hash) } : []
|
34
|
+
end
|
35
|
+
|
36
|
+
def dump(io = nil)
|
37
|
+
YAML.dump(@all.collect(&:to_hash), io)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.load_from_file(file_path)
|
41
|
+
plugins = self.new
|
42
|
+
File.open(file_path) do |f|
|
43
|
+
plugins.load(f)
|
44
|
+
end
|
45
|
+
|
46
|
+
plugins
|
47
|
+
end
|
48
|
+
|
49
|
+
def save_to_file(file_path = VPM.plugins_file)
|
50
|
+
File.open(file_path, 'w' ) do |out|
|
51
|
+
dump(out)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/vpm/runner.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
module VPM
|
2
|
+
module Runner
|
3
|
+
def self.autorun
|
4
|
+
return if installed_at_exit?
|
5
|
+
at_exit { exit run(ARGV).to_i }
|
6
|
+
@installed_at_exit = true
|
7
|
+
end
|
8
|
+
AT_EXIT_HOOK_BACKTRACE_LINE = "#{__FILE__}:#{__LINE__ - 2}:in `autorun'"
|
9
|
+
|
10
|
+
def self.installed_at_exit?
|
11
|
+
@installed_at_exit ||= false
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.run(args)
|
15
|
+
command = args[0]
|
16
|
+
|
17
|
+
# TODO: extract out into CommandLine.run(args)
|
18
|
+
result = false
|
19
|
+
if command.nil?
|
20
|
+
result = install_all_plugins
|
21
|
+
else
|
22
|
+
result = run_command(command, args)
|
23
|
+
end
|
24
|
+
|
25
|
+
result ? 0 : 1
|
26
|
+
|
27
|
+
ensure
|
28
|
+
VPM.plugins.save_to_file if VPM.plugins.changed?
|
29
|
+
end
|
30
|
+
|
31
|
+
# TODO: Make this part of `vpm install`
|
32
|
+
def self.install_all_plugins
|
33
|
+
vim_plugins_file = File.join(File.expand_path('.'), 'VimPlugins')
|
34
|
+
content = File.read(vim_plugins_file)
|
35
|
+
plugins = ManifestParser.parse(content)
|
36
|
+
plugins.each(&:install)
|
37
|
+
true
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.run_command(command, args)
|
41
|
+
parser = CommandOptions.parser(command)
|
42
|
+
options = parser.parse!(args)
|
43
|
+
|
44
|
+
plugin_name = args[1]
|
45
|
+
unless plugin_name
|
46
|
+
puts parser.opts_parser
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
|
50
|
+
type = options.delete(:type)
|
51
|
+
plugin = Plugin.new(plugin_name, type, options)
|
52
|
+
plugin.run_command(command)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/vpm/tasks.rb
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
this_directory = File.expand_path File.dirname(__FILE__)
|
2
|
+
tasks_directory = File.join(this_directory, "tasks")
|
3
|
+
|
4
|
+
require File.join(tasks_directory, "create_directory.rb")
|
5
|
+
Dir.glob(File.join(tasks_directory, "**", "*.rb")).each do |filename|
|
6
|
+
require filename
|
7
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class ClonePathogen
|
2
|
+
def initialize(base_dir)
|
3
|
+
@destination = File.join(base_dir, 'pathogen')
|
4
|
+
end
|
5
|
+
|
6
|
+
def perform
|
7
|
+
Kernel.system "git clone https://github.com/tpope/vim-pathogen.git #{@destination}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def undo
|
11
|
+
FileUtils.rm_r @destination
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateDirectory
|
2
|
+
def initialize(directory)
|
3
|
+
@destination = directory
|
4
|
+
end
|
5
|
+
|
6
|
+
def perform
|
7
|
+
@dir_already_exists = Dir.exists? @destination
|
8
|
+
return true if @dir_already_exists
|
9
|
+
FileUtils.mkdir_p @destination
|
10
|
+
end
|
11
|
+
|
12
|
+
def undo
|
13
|
+
return if @dir_already_exists
|
14
|
+
FileUtils.rm_r @destination
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateOurRCFile
|
2
|
+
def initialize
|
3
|
+
@destination = VPM.vpmrc_path
|
4
|
+
end
|
5
|
+
|
6
|
+
def perform
|
7
|
+
File.open(@destination, "w") do |file|
|
8
|
+
file.puts "call pathogen#infect()"
|
9
|
+
end
|
10
|
+
return true
|
11
|
+
end
|
12
|
+
|
13
|
+
def undo
|
14
|
+
FileUtils.rm @destination
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class InjectOurLoadScript
|
2
|
+
def initialize(backup_dir)
|
3
|
+
@text = "source #{VPM.vpmrc_path}"
|
4
|
+
@backup_path = File.join(backup_dir, "vimrc_backup_#{Time.now.to_i}")
|
5
|
+
end
|
6
|
+
|
7
|
+
def perform
|
8
|
+
FileUtils.touch VPM.vimrc_path
|
9
|
+
create_file unless File.read(VPM.vimrc_path).include? @text
|
10
|
+
return true
|
11
|
+
end
|
12
|
+
|
13
|
+
def undo
|
14
|
+
FileUtils.cp(@backup_path, VPM.vimrc_path)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def create_file
|
20
|
+
FileUtils.cp(VPM.vimrc_path, @backup_path)
|
21
|
+
File.open(VPM.vimrc_path, "w") do |file|
|
22
|
+
file.puts @text
|
23
|
+
File.open(@backup_path, "r").each_line do |old_vimrc|
|
24
|
+
file.puts old_vimrc
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class MovePathogenFile
|
2
|
+
def initialize(base_dir)
|
3
|
+
@source_file = File.join(base_dir, "pathogen", "autoload", "pathogen.vim")
|
4
|
+
@destination = File.join(VPM.vim_dir_path, "autoload", "pathogen.vim")
|
5
|
+
end
|
6
|
+
|
7
|
+
def perform
|
8
|
+
@file_already_exists = File.exists? @destination
|
9
|
+
return true if @file_already_exists
|
10
|
+
FileUtils.mv(@source_file, @destination)
|
11
|
+
end
|
12
|
+
|
13
|
+
def undo
|
14
|
+
return if @file_already_exists
|
15
|
+
FileUtils.rm @destination
|
16
|
+
end
|
17
|
+
end
|
data/lib/vpm/version.rb
CHANGED
@@ -5,7 +5,7 @@ describe VPM::ManifestParser do
|
|
5
5
|
parser = VPM::ManifestParser.new
|
6
6
|
parser.parse "plugin 'command-t', :git => 'https://github.com/agitrepo.git', :tag => '1.0.2'"
|
7
7
|
|
8
|
-
parser.plugins.size.
|
8
|
+
parser.plugins.size.should == 1
|
9
9
|
end
|
10
10
|
|
11
11
|
it "parses multiple plugins" do
|
@@ -16,7 +16,7 @@ describe VPM::ManifestParser do
|
|
16
16
|
plugin 'surround', :git => 'http://anothersite.com/repo.git'
|
17
17
|
END
|
18
18
|
|
19
|
-
parser.plugins.size.
|
19
|
+
parser.plugins.size.should == 3
|
20
20
|
end
|
21
21
|
|
22
22
|
it "ignores duplicate entries" do
|
@@ -26,16 +26,6 @@ describe VPM::ManifestParser do
|
|
26
26
|
plugin 'command-t', :git => 'https://github.com/agitrepo.git', :tag => '1.0.2'
|
27
27
|
END
|
28
28
|
|
29
|
-
parser.plugins.size.
|
30
|
-
end
|
31
|
-
|
32
|
-
it "parses to the right class of Plugin" do
|
33
|
-
parser = VPM::ManifestParser.new
|
34
|
-
parser.parse <<-END
|
35
|
-
plugin 'command-t', :git => 'https://github.com/agitrepo.git', :tag => '1.0.2'
|
36
|
-
plugin 'command-t', :git => 'https://github.com/agitrepo.git', :tag => '1.0.2'
|
37
|
-
END
|
38
|
-
|
39
|
-
parser.plugins.first.must_be_kind_of VPM::GitPlugin
|
29
|
+
parser.plugins.size.should == 1
|
40
30
|
end
|
41
31
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe VPM::Plugins do
|
3
|
+
it "dumps plugins as YAML" do
|
4
|
+
plugins = VPM::Plugins.new
|
5
|
+
plugins.plugin_installed(VPM::Plugin.new("command-t", :git, :remote => "http://xxx.git", :tag => "1.2.0"))
|
6
|
+
plugins.dump.should == YAML.dump([{:name => "command-t", :type => :git, :options => {:remote => "http://xxx.git", :tag => "1.2.0"}}])
|
7
|
+
end
|
8
|
+
|
9
|
+
it "loads plugins from YAML" do
|
10
|
+
plugins_yaml = <<-EOS
|
11
|
+
---
|
12
|
+
- :name: command-t
|
13
|
+
:type: :git
|
14
|
+
:options:
|
15
|
+
:remote: http://xxx.git
|
16
|
+
:tag: 1.2.0
|
17
|
+
EOS
|
18
|
+
plugins = VPM::Plugins.new
|
19
|
+
plugins.load(plugins_yaml)
|
20
|
+
plugins.all.size.should == 1
|
21
|
+
|
22
|
+
plugin = plugins.all.first
|
23
|
+
plugin.name.should == 'command-t'
|
24
|
+
plugin.type.should == :git
|
25
|
+
plugin.options.size.should == 2
|
26
|
+
plugin.options[:remote].should == 'http://xxx.git'
|
27
|
+
plugin.options[:tag].should == '1.2.0'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns empty when content to deserialize is empty" do
|
31
|
+
plugins = VPM::Plugins.new
|
32
|
+
plugins.load("")
|
33
|
+
plugins.all.should be_empty
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns empty when loading from an empty file" do
|
37
|
+
FileUtils.touch('foo')
|
38
|
+
plugins = VPM::Plugins.load_from_file('foo')
|
39
|
+
plugins.all.should be_empty
|
40
|
+
end
|
41
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CreateBundleDir do
|
4
|
+
before do
|
5
|
+
@task = CreateBundleDir.new
|
6
|
+
end
|
7
|
+
|
8
|
+
context "#perform" do
|
9
|
+
it "works even if the directory already exists" do
|
10
|
+
Dir.exists?(VPM.bundle_dir_path).should be_true
|
11
|
+
@task.perform
|
12
|
+
Dir.exists?(VPM.bundle_dir_path).should be_true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "#undo" do
|
17
|
+
it "removes #{VPM.bundle_dir_path} if this task created it" do
|
18
|
+
FileUtils.rmdir VPM.bundle_dir_path
|
19
|
+
Dir.exists?(VPM.bundle_dir_path).should be_false
|
20
|
+
@task.perform
|
21
|
+
Dir.exists?(VPM.bundle_dir_path).should be_true
|
22
|
+
@task.undo
|
23
|
+
Dir.exists?(VPM.bundle_dir_path).should be_false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|