vpm 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.gitignore +1 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile.lock +13 -5
  4. data/README.md +13 -11
  5. data/Rakefile +26 -6
  6. data/bin/vpm +1 -1
  7. data/lib/transaction.rb +27 -0
  8. data/lib/vpm.rb +52 -16
  9. data/lib/vpm/command_options.rb +15 -0
  10. data/lib/vpm/command_options/abstract_command_options.rb +25 -0
  11. data/lib/vpm/command_options/install.rb +18 -0
  12. data/lib/vpm/command_options/list.rb +9 -0
  13. data/lib/vpm/commands.rb +18 -0
  14. data/lib/vpm/commands/install.rb +37 -0
  15. data/lib/vpm/commands/install_all_plugins.rb +8 -0
  16. data/lib/vpm/commands/invalid_command.rb +10 -0
  17. data/lib/vpm/commands/list.rb +8 -0
  18. data/lib/vpm/commands/setup.rb +63 -0
  19. data/lib/vpm/git.rb +17 -0
  20. data/lib/vpm/manifest_parser.rb +19 -1
  21. data/lib/vpm/plugin.rb +29 -5
  22. data/lib/vpm/plugins.rb +55 -0
  23. data/lib/vpm/runner.rb +55 -0
  24. data/lib/vpm/tasks.rb +7 -0
  25. data/lib/vpm/tasks/clone_pathogen.rb +13 -0
  26. data/lib/vpm/tasks/create_autoload_dir.rb +5 -0
  27. data/lib/vpm/tasks/create_bundle_dir.rb +5 -0
  28. data/lib/vpm/tasks/create_directory.rb +16 -0
  29. data/lib/vpm/tasks/create_our_rc_file.rb +16 -0
  30. data/lib/vpm/tasks/inject_our_load_script.rb +28 -0
  31. data/lib/vpm/tasks/move_pathogen_file.rb +17 -0
  32. data/lib/vpm/version.rb +1 -1
  33. data/spec/commands/install_spec.rb +10 -0
  34. data/spec/manifest_parser_spec.rb +3 -13
  35. data/spec/plugins_spec.rb +41 -0
  36. data/spec/spec_helper.rb +2 -4
  37. data/spec/tasks/create_bundle_dir_spec.rb +26 -0
  38. data/spec/tasks/create_directory_spec.rb +33 -0
  39. data/spec/tasks/create_our_rc_file_spec.rb +31 -0
  40. data/spec/tasks/inject_our_load_script_spec.rb +39 -0
  41. data/spec/tasks/move_pathogen_file_spec.rb +42 -0
  42. data/spec/transaction_spec.rb +65 -0
  43. data/vpm.gemspec +6 -4
  44. metadata +63 -17
  45. data/lib/vpm/git_plugin.rb +0 -22
  46. data/spec/git_plugin_spec.rb +0 -12
  47. 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
@@ -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
- @plugins[name] = Plugin.create(name, options)
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
- attr_reader :name, :options
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 self.create(name, options)
11
- if options.has_key?(:git)
12
- GitPlugin.new(name, options)
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
@@ -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,5 @@
1
+ class CreateAutoloadDir < CreateDirectory
2
+ def initialize
3
+ super File.join(VPM.vim_dir_path, "autoload")
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class CreateBundleDir < CreateDirectory
2
+ def initialize
3
+ super VPM.bundle_dir_path
4
+ end
5
+ 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
@@ -1,3 +1,3 @@
1
1
  module VPM
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ module VPM::Commands
4
+ describe Install do
5
+ it "intalls a plugin" do
6
+ Install::GitInstall.should_receive(:run)
7
+ Install.run(VPM::Plugin.new("command-t", :git, :remote => "https://xxx.git"))
8
+ end
9
+ end
10
+ end
@@ -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.must_equal 1
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.must_equal 3
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.must_equal 1
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
@@ -1,7 +1,5 @@
1
1
  $:.unshift File.expand_path('../../lib', __FILE__)
2
2
 
3
- require 'minitest/autorun'
4
- begin; require 'turn'; rescue LoadError; end
5
-
6
-
3
+ require 'rspec'
7
4
  require 'vpm'
5
+ require 'fakefs'
@@ -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