vimpk 0.1.0 → 0.1.2

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