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.
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