vimpk 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c7dead9ffe26e414571f4abe1cefd9f4062c7d371fb2a04659c05387af8c5bd
4
- data.tar.gz: 249aad7c6ef651efed1ad2a449a79f0cffdd386973750209a2ff312ebba081e0
3
+ metadata.gz: b51ebecfb9301fe09e702bcb2dfed7efb76ecaf3f21480af3fd75cf6b16f34cf
4
+ data.tar.gz: 2286aac5e850c870cad840020904a1aef54c320b30f861d647dc9b2dbeec0b26
5
5
  SHA512:
6
- metadata.gz: 806ad154df6624026c2055b08290fc300b544df9c8c68873cfadeb81099ec52a714519ac35e690ce2b686bbe541317b28d4ecfd11aeb47d75ef81af30e836378
7
- data.tar.gz: a3d1730a8cb5f1e54f7e26bc991e2263aace1d563610f3259f78acbe96c3c484a3b9d6d86fa2ab5a8ca7fe6c1cbe6f1c3f0758ebd829f4e91f7723409e539167
6
+ metadata.gz: 7c4a3c50e3b85fa7b58ce0cda77de43925a64a1326a67a33f27f9e6fc0eb00954ac8d1b84decb2c31471232c7269d26bfdbb97f23ff25bf54e7b31b1b33b7f75
7
+ data.tar.gz: d71de4cf60fdc354ae6613dfb5bd152becb4bcd50b72e72726afa15c6bb3febe3c2f6d39a2329cf5138a72dc5d6c5ee0dc2d1a9b61c11b2e73a87726b3c81555
data/exe/vimpk CHANGED
@@ -4,4 +4,4 @@ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
4
4
 
5
5
  require "vimpk"
6
6
 
7
- VimPK::CLI.start(ARGV)
7
+ VimPK::CLI.new(ARGV).call
data/lib/vimpk/cli.rb CHANGED
@@ -2,8 +2,106 @@
2
2
 
3
3
  module VimPK
4
4
  class CLI
5
- def self.start(args)
6
- VimPK::Update.run
5
+ include Colorizer
6
+
7
+ def initialize(args)
8
+ @args = args
9
+ @parser = VimPK::Options.new(args)
10
+ @options = @parser.options
11
+ @command = determine_command
12
+ end
13
+
14
+ def call
15
+ if @command
16
+ send(@command, *@args)
17
+ else
18
+ puts @parser.parser
19
+ end
20
+ end
21
+
22
+ def determine_command
23
+ return nil if @args.empty?
24
+
25
+ case @args.shift&.downcase
26
+ when "i", "install"
27
+ :install_command
28
+ when "u", "update"
29
+ :update_command
30
+ when "rm", "remove"
31
+ :remove_command
32
+ else
33
+ raise "Unknown command: #{name}"
34
+ end
35
+ end
36
+
37
+ def install_command(package = nil)
38
+ time = Time.now
39
+ install = Install.new(package, @options[:path], @options[:pack], @options[:type])
40
+ puts "Installing #{package} to #{install.dest}…"
41
+ install.call
42
+ puts colorize("Installed #{package} to #{install.dest}. Took #{Time.now - time} seconds.", color: :green)
43
+ rescue Git::GitError => e
44
+ puts colorize("Error: #{e.message}", color: :red)
45
+ abort e.output.lines.map { |line| " #{line}" }.join
46
+ rescue Install::PackageExistsError => e
47
+ puts colorize("Error: #{e.message}", color: :red)
48
+ rescue ArgumentError => e
49
+ puts colorize("Error: #{e.message}", color: :red)
50
+ end
51
+
52
+ def update_command
53
+ update = Update.new(@options[:path])
54
+ puts "Updating #{update.plugins.size} packages in #{@options[:path]}…"
55
+ start_time = Time.now
56
+ update.call
57
+
58
+ statuses = {}
59
+
60
+ while (log = update.logs.pop)
61
+ basename = log[:basename]
62
+ statuses[basename] = log[:log]
63
+ end
64
+
65
+ basenames = update.plugins.map { |dir| File.basename(dir) }.sort_by(&:downcase)
66
+
67
+ max_name_length = statuses.keys.map(&:length).max
68
+
69
+ basenames.each do |basename|
70
+ if statuses[basename]
71
+ formatted_name = basename.rjust(max_name_length)
72
+ formatted_status = colorize("Updated!", color: :green)
73
+ puts "#{formatted_name}: #{formatted_status}"
74
+ end
75
+ end
76
+
77
+ if statuses.size < update.jobs.size
78
+ puts "The remaining #{update.jobs.size - statuses.size} plugins are up to date."
79
+ end
80
+
81
+ puts colorize("Finished updating #{update.jobs.size} plugins. Took #{Time.now - start_time} seconds.")
82
+
83
+ if statuses.size.nonzero?
84
+ print "Display diffs? (Y/n) "
85
+
86
+ answer = $stdin.getch
87
+
88
+ if answer.downcase == "y" || answer == "\r"
89
+ puts
90
+ puts "Displaying diffs…"
91
+
92
+ statuses.each do |basename, status|
93
+ puts status.lines.map { |line| "#{basename}: #{colorize_diff line}" }.join
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ def remove_command(name = nil)
100
+ Remove.new(name, @options[:path]).call
101
+
102
+ puts colorize("Package #{name} removed.", color: :green)
103
+ rescue ArgumentError, VimPK::Remove::PackageNotFound => e
104
+ abort colorize(e.message, color: :red)
7
105
  end
8
106
  end
9
107
  end
@@ -31,6 +31,10 @@ module VimPK
31
31
  "\e[31m#{text}\e[0m"
32
32
  when :blue
33
33
  "\e[34m#{text}\e[0m"
34
+ when :yellow
35
+ "\e[33m#{text}\e[0m"
36
+ else
37
+ raise ArgumentError, "Unknown color: #{color}"
34
38
  end
35
39
  end
36
40
  end
data/lib/vimpk/git.rb ADDED
@@ -0,0 +1,43 @@
1
+ module VimPK
2
+ module Git
3
+ module_function
4
+
5
+ class GitError < StandardError
6
+ attr_reader :output
7
+
8
+ def initialize(message, output)
9
+ super(message)
10
+ @output = output
11
+ end
12
+ end
13
+
14
+ def branch(dir: Dir.pwd)
15
+ command("rev-parse --abbrev-ref HEAD", dir: dir)
16
+ end
17
+
18
+ def log(branch, dir: Dir.pwd)
19
+ command("log -p --full-diff HEAD..origin/#{branch}", dir: dir)
20
+ end
21
+
22
+ def fetch(branch, dir: Dir.pwd)
23
+ command("fetch origin #{branch}", dir: dir)
24
+ end
25
+
26
+ def pull(dir: Dir.pwd)
27
+ command("pull --rebase", dir: dir)
28
+ end
29
+
30
+ def clone(source, dest, dir: Dir.pwd)
31
+ out = command("clone #{source} #{dest}", dir: dir)
32
+ if $?.exitstatus != 0
33
+ raise GitError.new("Failed to clone #{source} to #{dest}", out)
34
+ end
35
+ end
36
+
37
+ def command(args, dir: Dir.pwd)
38
+ IO.popen("git -C #{dir} #{args}", dir: dir, err: [:child, :out]) do |io|
39
+ io.read.chomp
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ module VimPK
2
+ class Install
3
+ include VimPK::Colorizer
4
+
5
+ PackageExistsError = Class.new(StandardError)
6
+
7
+ attr_reader :dest
8
+
9
+ def initialize(package, path, pack, type)
10
+ @package = package || raise(ArgumentError, "Package name is required")
11
+ @path = path
12
+ @pack = pack
13
+ @type = type
14
+ @dest = File.join(@path, @pack, @type, File.basename(@package))
15
+ @source = "https://github.com/#{package}.git"
16
+ @git = Git
17
+ end
18
+
19
+ def call
20
+ raise PackageExistsError, "Package #{@package} already exists at #{@dest}" if File.exist?(@dest)
21
+
22
+ Git.clone(@source, @dest, dir: @path)
23
+ end
24
+ end
25
+ end
data/lib/vimpk/job.rb CHANGED
@@ -1,34 +1,22 @@
1
1
  module VimPK
2
2
  class Job
3
- def initialize(dir, updates, output)
3
+ def initialize(dir, logs)
4
4
  @dir = dir
5
5
  @basename = File.basename(dir)
6
- @updates = updates
7
- @output = output
6
+ @logs = logs
7
+ @git = Git
8
8
  end
9
9
 
10
10
  def call
11
- branch = git("rev-parse --abbrev-ref HEAD", dir: @dir)
12
- git("fetch origin #{branch}", dir: @dir)
13
- log = git("log -p --full-diff HEAD..origin/#{branch}", dir: @dir)
11
+ branch = Git.branch(dir: @dir)
12
+ Git.fetch(branch, dir: @dir)
13
+ log = Git.log(branch, dir: @dir)
14
14
 
15
- if log.empty?
16
- puts("Already up to date.")
17
- else
18
- git("pull --rebase", dir: @dir)
19
- @updates << {basename: @basename, log: log}
20
- puts "Updated!"
21
- end
22
- end
23
-
24
- def puts(message = "\n")
25
- @output << {@basename => message}
26
- end
27
-
28
- private
15
+ unless log.empty?
16
+ @logs << {basename: @basename, log: log}
29
17
 
30
- def git(command, dir:)
31
- IO.popen("git -C #{dir} #{command}", dir: dir, err: [:child, :out]) { |io| io.read.chomp }
18
+ Git.pull(dir: @dir)
19
+ end
32
20
  end
33
21
  end
34
22
  end
@@ -0,0 +1,65 @@
1
+ require "optparse"
2
+
3
+ module VimPK
4
+ class Options
5
+ attr_reader :options, :parser
6
+
7
+ DEFAULT_PATH = File.expand_path("~/.vim/pack").freeze
8
+ DEFAULT_TYPE = "start".freeze
9
+ DEFAULT_PACK = "plugins".freeze
10
+
11
+ DefaultOptions = Struct.new(:path, :pack, :type)
12
+
13
+ def initialize(args)
14
+ @options = DefaultOptions.new(DEFAULT_PATH, DEFAULT_PACK, DEFAULT_TYPE)
15
+ @parser = OptionParser.new do |parser|
16
+ parser.banner = "Usage: #{parser.program_name} [options] [command [options]"
17
+ parser.separator ""
18
+ parser.separator "Options:"
19
+
20
+ parser.on("--pack=PATH", String, "Name of the pack (#{DEFAULT_PACK})") do |pack|
21
+ @options[:pack] = pack
22
+ end
23
+
24
+ parser.on("--path=PATH", String, "Path to Vim's pack directory (#{DEFAULT_PATH})") do |path|
25
+ path = File.expand_path(path)
26
+ unless File.directory?(path)
27
+ abort("Error: #{path} is not a directory")
28
+ end
29
+ @options[:path] = path
30
+ end
31
+
32
+ parser.on("--opt", "Install package as an optional plugin") do
33
+ @options[:type] = "opt"
34
+ end
35
+
36
+ parser.on("--start", "Install package as a start plugin (default)") do
37
+ @options[:type] = "start"
38
+ end
39
+
40
+ parser.on("-h", "--help", "Show this help message") do
41
+ puts parser
42
+ exit
43
+ end
44
+
45
+ parser.on("-v", "--version", "Show version") do
46
+ puts VimPK::VERSION
47
+ exit
48
+ end
49
+
50
+ parser.separator ""
51
+ parser.separator "Commands:"
52
+ parser.separator " i|install REPO/NAME [--opt|--start] [--pack=PATH] [--path=PATH] Install a package"
53
+ parser.separator " u|update Update all packages"
54
+ parser.separator " rm|remove NAME Remove all occurrences of a package"
55
+
56
+ begin
57
+ parser.permute!(args)
58
+ rescue OptionParser::MissingArgument, OptionParser::InvalidOption => e
59
+ puts e.message
60
+ abort("Use --help for usage information")
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,24 @@
1
+ require "fileutils"
2
+
3
+ module VimPK
4
+ class Remove
5
+ PackageNotFound = Class.new(StandardError)
6
+
7
+ def initialize(name, path)
8
+ @name = name || raise(ArgumentError, "Package name is required")
9
+ @path = path
10
+ end
11
+
12
+ def call
13
+ glob = Dir.glob(File.join(@path, "*", "{start,opt}", @name))
14
+
15
+ if glob.empty?
16
+ raise PackageNotFound, "Package #{@name} not found in #{@path}."
17
+ else
18
+ glob.each do |dir|
19
+ FileUtils.rm_rf(dir)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
data/lib/vimpk/update.rb CHANGED
@@ -2,71 +2,23 @@ module VimPK
2
2
  class Update
3
3
  include VimPK::Colorizer
4
4
 
5
- def self.run
6
- new.update
7
- end
5
+ attr_reader :jobs, :logs, :plugins
8
6
 
9
- def initialize(path = "~/.vim/pack")
10
- @before = Time.now
7
+ def initialize(path)
11
8
  @pack_dir = File.expand_path(path)
12
- @updates = Queue.new
13
- @output = Queue.new
9
+ @logs = Queue.new
14
10
  @pool = ThreadPool.new
15
- @dirs = Dir.glob(File.join(@pack_dir, "*", "{start,opt}", "*", ".git")).sort
16
- @basenames = @dirs.map { |dir| File.basename(File.dirname(dir)) }
17
- @longest_name = @basenames.map(&:length).max
18
- end
19
-
20
- def format_name(name)
21
- name.rjust(@longest_name)
11
+ @plugins = Dir.glob(File.join(@pack_dir, "*", "{start,opt}", "*", ".git")).sort.map(&File.method(:dirname))
12
+ @jobs = []
22
13
  end
23
14
 
24
- def update
25
- puts "Updating #{@dirs.size} plugins in #{@pack_dir}"
26
-
27
- jobs = @dirs.map do |git_dir|
28
- plugin_dir = File.dirname(git_dir)
29
- @pool.schedule Job.new(plugin_dir, @updates, @output)
15
+ def call
16
+ @jobs = @plugins.map do |dir|
17
+ @pool.schedule Job.new(dir, @logs)
30
18
  end
31
19
 
32
20
  @pool.shutdown
33
- @output.close
34
-
35
- while (message = @output.pop)
36
- case message
37
- when String
38
- Kernel.puts message
39
- when Hash
40
- basename = message.keys.first
41
- message = message.values.first
42
- message = case message
43
- when "Updated!" then colorize(message, color: :green)
44
- when "Already up to date." then colorize(message, color: :blue)
45
- else message
46
- end
47
- puts "#{format_name(basename)}: #{message}"
48
- end
49
- end
50
-
51
- puts
52
- puts colorize("Done updating #{jobs.size} plugins. Took #{Time.now - @before} seconds.")
53
-
54
- if @updates.size.nonzero?
55
- print "Display diffs? (Y/n) "
56
-
57
- answer = $stdin.getch
58
-
59
- if answer.downcase == "y" || answer == "\r"
60
- puts
61
- puts "Displaying diffs…"
62
-
63
- @updates.size.times do
64
- update = @updates.pop
65
- next if update[:log].empty?
66
- puts update[:log].lines.map { |line| "#{format_name(update[:basename])}: #{colorize_diff line}" }.join
67
- end
68
- end
69
- end
21
+ @logs.close
70
22
  end
71
23
  end
72
24
  end
data/lib/vimpk/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module VimPK
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
data/lib/vimpk.rb CHANGED
@@ -11,8 +11,12 @@ module VimPK
11
11
  class Error < StandardError; end
12
12
 
13
13
  autoload :CLI, "vimpk/cli"
14
- autoload :ThreadPool, "vimpk/thread_pool"
15
- autoload :Job, "vimpk/job"
16
14
  autoload :Colorizer, "vimpk/colorizer"
15
+ autoload :Remove, "vimpk/remove"
16
+ autoload :Git, "vimpk/git"
17
+ autoload :Install, "vimpk/install"
18
+ autoload :Job, "vimpk/job"
19
+ autoload :Options, "vimpk/options"
20
+ autoload :ThreadPool, "vimpk/thread_pool"
17
21
  autoload :Update, "vimpk/update"
18
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vimpk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Usewicz
@@ -26,7 +26,11 @@ files:
26
26
  - lib/vimpk.rb
27
27
  - lib/vimpk/cli.rb
28
28
  - lib/vimpk/colorizer.rb
29
+ - lib/vimpk/git.rb
30
+ - lib/vimpk/install.rb
29
31
  - lib/vimpk/job.rb
32
+ - lib/vimpk/options.rb
33
+ - lib/vimpk/remove.rb
30
34
  - lib/vimpk/thread_pool.rb
31
35
  - lib/vimpk/update.rb
32
36
  - lib/vimpk/version.rb
@@ -39,6 +43,7 @@ metadata:
39
43
  homepage_uri: https://github.com/pusewicz/vimpk
40
44
  source_code_uri: https://github.com/pusewicz/vimpk
41
45
  changelog_uri: https://github.com/pusewicz/vimpk/blob/main/CHANGELOG.md
46
+ github_repo: ssh://github.com/pusewicz/vimpk
42
47
  post_install_message:
43
48
  rdoc_options: []
44
49
  require_paths: