vimpk 0.1.0 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c7dead9ffe26e414571f4abe1cefd9f4062c7d371fb2a04659c05387af8c5bd
4
- data.tar.gz: 249aad7c6ef651efed1ad2a449a79f0cffdd386973750209a2ff312ebba081e0
3
+ metadata.gz: 1fb0dfb2236f49356b5b50889c8f063c70952ba85fce011400943acc449ca8c5
4
+ data.tar.gz: 513194b7c2e2bc8b3a3c48393addf328f10834f53568721673484fcd9569343c
5
5
  SHA512:
6
- metadata.gz: 806ad154df6624026c2055b08290fc300b544df9c8c68873cfadeb81099ec52a714519ac35e690ce2b686bbe541317b28d4ecfd11aeb47d75ef81af30e836378
7
- data.tar.gz: a3d1730a8cb5f1e54f7e26bc991e2263aace1d563610f3259f78acbe96c3c484a3b9d6d86fa2ab5a8ca7fe6c1cbe6f1c3f0758ebd829f4e91f7723409e539167
6
+ metadata.gz: a2c7c9684d5d750c00f31f314d0fe80f3f1cfa6bfa9bcfb135ea39880bd1b2b9ffba8d790550ca563ba74290992f47c77e9b23c20838e82bab21c712a416e95e
7
+ data.tar.gz: c56b63a7ad96710c7b6fc76a71ba69db43b99d4cba37b12c8a5f60c98dbe9e227556b1a97e6cefa194b29ce8482ea69ec815b3c29a67bcedcbf83b4c688b304a
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,112 @@
2
2
 
3
3
  module VimPK
4
4
  class CLI
5
- def self.start(args)
6
- VimPK::Update.run
5
+ include Colorizer
6
+
7
+ attr_reader :command
8
+
9
+ def initialize(argv)
10
+ @argv = argv
11
+ @parser = Options.new(argv)
12
+ @options = @parser.parse
13
+ @command = determine_command
14
+ rescue OptionParser::MissingArgument, OptionParser::InvalidOption => e
15
+ puts e.message
16
+ abort("Use --help for usage information")
17
+ end
18
+
19
+ def call
20
+ if @command
21
+ send(@command, *@argv)
22
+ else
23
+ puts @parser.parser
24
+ end
25
+ end
26
+
27
+ def determine_command
28
+ return nil if @argv.empty?
29
+
30
+ name = @argv.shift&.downcase
31
+ case name
32
+ when "i", "install"
33
+ :install_command
34
+ when "u", "update"
35
+ :update_command
36
+ when "rm", "remove"
37
+ :remove_command
38
+ else
39
+ raise ArgumentError, "Unknown command: #{name}"
40
+ end
41
+ end
42
+
43
+ def install_command(package = nil)
44
+ time = Time.now
45
+ install = Install.new(package, @options[:path], @options[:pack], @options[:type])
46
+ puts "Installing #{package} to #{install.dest}…"
47
+ install.call
48
+ puts colorize("Installed #{package} to #{install.dest}. Took #{Time.now - time} seconds.", color: :green)
49
+ rescue Git::GitError => e
50
+ puts colorize("Error: #{e.message}", color: :red)
51
+ abort e.output.lines.map { |line| " #{line}" }.join
52
+ rescue Install::PackageExistsError => e
53
+ puts colorize("Error: #{e.message}", color: :red)
54
+ rescue ArgumentError => e
55
+ puts colorize("Error: #{e.message}", color: :red)
56
+ end
57
+
58
+ def update_command
59
+ update = Update.new(@options[:path])
60
+ puts "Updating #{update.plugins.size} packages in #{@options[:path]}…"
61
+ start_time = Time.now
62
+ update.call
63
+
64
+ statuses = {}
65
+
66
+ while (log = update.logs.pop)
67
+ basename = log[:basename]
68
+ statuses[basename] = log[:log]
69
+ end
70
+
71
+ basenames = update.plugins.map { |dir| File.basename(dir) }.sort_by(&:downcase)
72
+
73
+ max_name_length = statuses.keys.map(&:length).max
74
+
75
+ basenames.each do |basename|
76
+ if statuses[basename]
77
+ formatted_name = basename.rjust(max_name_length)
78
+ formatted_status = colorize("Updated!", color: :green)
79
+ puts "#{formatted_name}: #{formatted_status}"
80
+ end
81
+ end
82
+
83
+ if statuses.size < update.jobs.size
84
+ puts "The remaining #{update.jobs.size - statuses.size} plugins are up to date."
85
+ end
86
+
87
+ puts colorize("Finished updating #{update.jobs.size} plugins. Took #{Time.now - start_time} seconds.")
88
+
89
+ if statuses.size.nonzero?
90
+ print "Display diffs? (Y/n) "
91
+
92
+ answer = $stdin.getch
93
+
94
+ if answer.downcase == "y" || answer == "\r"
95
+ puts
96
+ puts "Displaying diffs…"
97
+
98
+ statuses.each do |basename, status|
99
+ puts status.lines.map { |line| "#{basename}: #{colorize_diff line}" }.join
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ def remove_command(name = nil)
106
+ Remove.new(name, @options[:path]).call
107
+
108
+ puts colorize("Package #{name} removed.", color: :green)
109
+ rescue ArgumentError, VimPK::Remove::PackageNotFound => e
110
+ abort colorize(e.message, color: :red)
7
111
  end
8
112
  end
9
113
  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,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+
5
+ module VimPK
6
+ class Options
7
+ attr_reader :options, :parser
8
+
9
+ DEFAULT_PATH = File.expand_path("~/.vim/pack").freeze
10
+ DEFAULT_TYPE = "start"
11
+ DEFAULT_PACK = "plugins"
12
+
13
+ DefaultOptions = Struct.new(:path, :pack, :type)
14
+
15
+ def initialize(argv)
16
+ @argv = argv
17
+ @options = DefaultOptions.new(DEFAULT_PATH, DEFAULT_PACK, DEFAULT_TYPE)
18
+
19
+ @parser = OptionParser.new do |parser|
20
+ parser.banner = "Usage: #{parser.program_name} [options] [command [options]"
21
+ parser.separator ""
22
+ parser.separator "Options:"
23
+
24
+ parser.on("--pack=PATH", String, "Name of the pack (#{DEFAULT_PACK})") do |pack|
25
+ @options[:pack] = pack
26
+ end
27
+
28
+ parser.on("--path=PATH", String, "Path to Vim's pack directory (#{DEFAULT_PATH})") do |path|
29
+ path = File.expand_path(path)
30
+ unless File.directory?(path)
31
+ abort("Error: #{path} is not a directory")
32
+ end
33
+ @options[:path] = path
34
+ end
35
+
36
+ parser.on("--opt", "Install package as an optional plugin") do
37
+ @options[:type] = "opt"
38
+ end
39
+
40
+ parser.on("--start", "Install package as a start plugin (default)") do
41
+ @options[:type] = "start"
42
+ end
43
+
44
+ parser.on("-h", "--help", "Show this help message") do
45
+ puts parser
46
+ exit
47
+ end
48
+
49
+ parser.on("-v", "--version", "Show version") do
50
+ puts VimPK::VERSION
51
+ exit
52
+ end
53
+
54
+ parser.separator ""
55
+ parser.separator "Commands:"
56
+ parser.separator " i|install REPO/NAME [--opt|--start] [--pack=PATH] [--path=PATH] Install a package"
57
+ parser.separator " u|update Update all packages"
58
+ parser.separator " rm|remove NAME Remove all occurrences of a package"
59
+ end
60
+ end
61
+
62
+ def parse
63
+ @parser.permute!(@argv)
64
+ @options
65
+ end
66
+ end
67
+ 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.2"
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 :Git, "vimpk/git"
16
+ autoload :Install, "vimpk/install"
17
+ autoload :Job, "vimpk/job"
18
+ autoload :Options, "vimpk/options"
19
+ autoload :Remove, "vimpk/remove"
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.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Usewicz
@@ -19,18 +19,18 @@ extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
21
  - LICENSE.txt
22
- - README.md
23
- - Rakefile
24
- - Steepfile
25
22
  - exe/vimpk
26
23
  - lib/vimpk.rb
27
24
  - lib/vimpk/cli.rb
28
25
  - lib/vimpk/colorizer.rb
26
+ - lib/vimpk/git.rb
27
+ - lib/vimpk/install.rb
29
28
  - lib/vimpk/job.rb
29
+ - lib/vimpk/options.rb
30
+ - lib/vimpk/remove.rb
30
31
  - lib/vimpk/thread_pool.rb
31
32
  - lib/vimpk/update.rb
32
33
  - lib/vimpk/version.rb
33
- - sig/vimpk.rbs
34
34
  homepage: https://github.com/pusewicz/vimpk
35
35
  licenses:
36
36
  - MIT
@@ -39,6 +39,7 @@ metadata:
39
39
  homepage_uri: https://github.com/pusewicz/vimpk
40
40
  source_code_uri: https://github.com/pusewicz/vimpk
41
41
  changelog_uri: https://github.com/pusewicz/vimpk/blob/main/CHANGELOG.md
42
+ github_repo: https://github.com/pusewicz/vimpk.git
42
43
  post_install_message:
43
44
  rdoc_options: []
44
45
  require_paths:
@@ -47,7 +48,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
47
48
  requirements:
48
49
  - - ">="
49
50
  - !ruby/object:Gem::Version
50
- version: 3.0.0
51
+ version: 2.6.0
51
52
  required_rubygems_version: !ruby/object:Gem::Requirement
52
53
  requirements:
53
54
  - - ">="
data/README.md DELETED
@@ -1,33 +0,0 @@
1
- # VimPK
2
-
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/vimpk`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- ## Installation
6
-
7
- Install the gem by executing:
8
-
9
- $ gem install vimpk
10
-
11
- ## Usage
12
-
13
- To use the gem, you can run the following command:
14
-
15
- $ vimpk
16
-
17
- ## Development
18
-
19
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
20
-
21
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
22
-
23
- ## Contributing
24
-
25
- Bug reports and pull requests are welcome on GitHub at https://github.com/pusewicz/vimpk. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/pusewicz/vimpk/blob/main/CODE_OF_CONDUCT.md).
26
-
27
- ## License
28
-
29
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
30
-
31
- ## Code of Conduct
32
-
33
- Everyone interacting in the Vimpk project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/pusewicz/vimpk/blob/main/CODE_OF_CONDUCT.md).
data/Rakefile DELETED
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "minitest/test_task"
5
-
6
- Minitest::TestTask.create
7
-
8
- require "standard/rake"
9
-
10
- task default: %i[test standard]
data/Steepfile DELETED
@@ -1,29 +0,0 @@
1
- # D = Steep::Diagnostic
2
- #
3
- # target :lib do
4
- # signature "sig"
5
- #
6
- # check "lib" # Directory name
7
- # check "Gemfile" # File name
8
- # check "app/models/**/*.rb" # Glob
9
- # # ignore "lib/templates/*.rb"
10
- #
11
- # # library "pathname" # Standard libraries
12
- # # library "strong_json" # Gems
13
- #
14
- # # configure_code_diagnostics(D::Ruby.default) # `default` diagnostics setting (applies by default)
15
- # # configure_code_diagnostics(D::Ruby.strict) # `strict` diagnostics setting
16
- # # configure_code_diagnostics(D::Ruby.lenient) # `lenient` diagnostics setting
17
- # # configure_code_diagnostics(D::Ruby.silent) # `silent` diagnostics setting
18
- # # configure_code_diagnostics do |hash| # You can setup everything yourself
19
- # # hash[D::Ruby::NoMethod] = :information
20
- # # end
21
- # end
22
-
23
- # target :test do
24
- # signature "sig", "sig-private"
25
- #
26
- # check "test"
27
- #
28
- # # library "pathname" # Standard libraries
29
- # end
data/sig/vimpk.rbs DELETED
@@ -1,4 +0,0 @@
1
- module Vimpk
2
- VERSION: String
3
- # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
- end