vpm 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|