mj 0.8.0 → 0.9.0

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: 8b15f4c4efd81a03bf545e20a2bebb6beff7a12612c470173073f35c5b67cab2
4
- data.tar.gz: 6c61d4acd6cc0d8590835bfd038fe0e291df05fd3100db7fff41f189eeade3fe
3
+ metadata.gz: 40c3258afb7e8d688b06de487bb9286f0acb6999355a7156b099a77095206cc5
4
+ data.tar.gz: 301506dcf36dee5629e0912a6fd5d89e6d130f73daab6255a86aefc802e14763
5
5
  SHA512:
6
- metadata.gz: 7d1017ad9f4b623c86d864e16c5110b9ecc1e131bbe96e27f23e0782b79ce209257972837a857a6557877a484dd0de834c2bf0c5be6c38d2ff5c67866243872c
7
- data.tar.gz: 77da1cdfb825c43e50d8ae4cf7b203f585fc7c4be33c1121ad47e46c30befe773ec9cfe345a980112e02b625e0f3a82bd4158ef5d15438e8f46f46816b416529
6
+ metadata.gz: 32a385ff987a4ff7ebb24b4b4329bdbbe018194e976aea69c4dc650cf66679e690d609550f8be34a914adb480a82751241d1f4090921a8319176bcacb3a0c6c5
7
+ data.tar.gz: b2ef3335c6cab5e6d6da130755130f07b5e829dd1a703e6f4ecda2a5b8098a61c427d18a68923ff262a352b0ac7b15cbbc53b655a7211f0d0be891d2e51e75cf
data/Gemfile.lock CHANGED
@@ -1,97 +1,101 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mj (0.8.0)
4
+ mj (0.9.0)
5
+ colorize
5
6
  koine-rest_client
6
7
  mj-hash_utils
7
8
  ruby-openai (~> 6.2.0)
8
9
  thor (~> 1.2.1)
10
+ uri (~> 0.13.0)
9
11
 
10
12
  GEM
11
13
  remote: https://rubygems.org/
12
14
  specs:
13
- addressable (2.8.6)
14
- public_suffix (>= 2.0.2, < 6.0)
15
+ addressable (2.8.7)
16
+ public_suffix (>= 2.0.2, < 7.0)
15
17
  ast (2.4.2)
16
18
  awesome_print (1.9.2)
19
+ bigdecimal (3.1.8)
17
20
  coderay (1.1.3)
21
+ colorize (1.1.0)
22
+ csv (3.3.0)
18
23
  diff-lcs (1.5.1)
19
- docile (1.4.0)
24
+ docile (1.4.1)
20
25
  event_stream_parser (0.3.0)
21
- faraday (2.9.0)
26
+ faraday (2.10.1)
22
27
  faraday-net_http (>= 2.0, < 3.2)
28
+ logger
23
29
  faraday-multipart (1.0.4)
24
30
  multipart-post (~> 2)
25
- faraday-net_http (3.1.0)
31
+ faraday-net_http (3.1.1)
26
32
  net-http
27
- httparty (0.21.0)
33
+ httparty (0.22.0)
34
+ csv
28
35
  mini_mime (>= 1.0.0)
29
36
  multi_xml (>= 0.5.2)
30
- json (2.7.1)
37
+ json (2.7.2)
31
38
  koine-rest_client (1.1.1)
32
39
  addressable (>= 2.3)
33
40
  httparty (>= 0.17.0)
34
41
  koine-test_runner (0.4.0)
35
42
  language_server-protocol (3.17.0.3)
36
- method_source (1.0.0)
43
+ logger (1.6.0)
44
+ method_source (1.1.0)
37
45
  mini_mime (1.1.5)
38
46
  mj-hash_utils (0.1.0)
39
- multi_xml (0.6.0)
40
- multipart-post (2.4.0)
47
+ multi_xml (0.7.1)
48
+ bigdecimal (~> 3.1)
49
+ multipart-post (2.4.1)
41
50
  net-http (0.4.1)
42
51
  uri
43
- parallel (1.24.0)
44
- parser (3.3.0.5)
52
+ parallel (1.26.1)
53
+ parser (3.3.4.2)
45
54
  ast (~> 2.4.1)
46
55
  racc
47
56
  pry (0.14.2)
48
57
  coderay (~> 1.1)
49
58
  method_source (~> 1.0)
50
- public_suffix (5.0.4)
51
- racc (1.7.3)
59
+ public_suffix (6.0.1)
60
+ racc (1.8.1)
52
61
  rainbow (3.1.1)
53
- rake (13.1.0)
54
- regexp_parser (2.9.0)
55
- rexml (3.2.6)
62
+ rake (13.2.1)
63
+ regexp_parser (2.9.2)
64
+ rexml (3.3.4)
65
+ strscan
56
66
  rspec (3.13.0)
57
67
  rspec-core (~> 3.13.0)
58
68
  rspec-expectations (~> 3.13.0)
59
69
  rspec-mocks (~> 3.13.0)
60
70
  rspec-core (3.13.0)
61
71
  rspec-support (~> 3.13.0)
62
- rspec-expectations (3.13.0)
72
+ rspec-expectations (3.13.1)
63
73
  diff-lcs (>= 1.2.0, < 2.0)
64
74
  rspec-support (~> 3.13.0)
65
- rspec-mocks (3.13.0)
75
+ rspec-mocks (3.13.1)
66
76
  diff-lcs (>= 1.2.0, < 2.0)
67
77
  rspec-support (~> 3.13.0)
68
78
  rspec-support (3.13.1)
69
- rubocop (1.62.0)
79
+ rubocop (1.65.1)
70
80
  json (~> 2.3)
71
81
  language_server-protocol (>= 3.17.0)
72
82
  parallel (~> 1.10)
73
83
  parser (>= 3.3.0.2)
74
84
  rainbow (>= 2.2.2, < 4.0)
75
- regexp_parser (>= 1.8, < 3.0)
85
+ regexp_parser (>= 2.4, < 3.0)
76
86
  rexml (>= 3.2.5, < 4.0)
77
87
  rubocop-ast (>= 1.31.1, < 2.0)
78
88
  ruby-progressbar (~> 1.7)
79
89
  unicode-display_width (>= 2.4.0, < 3.0)
80
- rubocop-ast (1.31.2)
81
- parser (>= 3.3.0.4)
82
- rubocop-capybara (2.20.0)
83
- rubocop (~> 1.41)
84
- rubocop-factory_bot (2.25.1)
85
- rubocop (~> 1.41)
86
- rubocop-performance (1.20.2)
90
+ rubocop-ast (1.32.0)
91
+ parser (>= 3.3.1.0)
92
+ rubocop-performance (1.21.1)
87
93
  rubocop (>= 1.48.1, < 2.0)
88
- rubocop-ast (>= 1.30.0, < 2.0)
94
+ rubocop-ast (>= 1.31.1, < 2.0)
89
95
  rubocop-rake (0.6.0)
90
96
  rubocop (~> 1.0)
91
- rubocop-rspec (2.27.1)
92
- rubocop (~> 1.40)
93
- rubocop-capybara (~> 2.17)
94
- rubocop-factory_bot (~> 2.22)
97
+ rubocop-rspec (3.0.4)
98
+ rubocop (~> 1.61)
95
99
  ruby-openai (6.2.0)
96
100
  event_stream_parser (>= 0.3.0, < 1.0.0)
97
101
  faraday (>= 1)
@@ -104,11 +108,13 @@ GEM
104
108
  simplecov-html (0.12.3)
105
109
  simplecov-lcov (0.8.0)
106
110
  simplecov_json_formatter (0.1.4)
111
+ strscan (3.1.0)
107
112
  thor (1.2.2)
108
113
  unicode-display_width (2.5.0)
109
114
  uri (0.13.0)
110
115
 
111
116
  PLATFORMS
117
+ arm64-darwin-23
112
118
  ruby
113
119
 
114
120
  DEPENDENCIES
@@ -127,4 +133,4 @@ DEPENDENCIES
127
133
  uri (~> 0.13)
128
134
 
129
135
  BUNDLED WITH
130
- 2.3.16
136
+ 2.5.17
data/README.md CHANGED
@@ -16,11 +16,11 @@ gem 'mj'
16
16
 
17
17
  And then execute:
18
18
 
19
- $ bundle install
19
+ bundle install
20
20
 
21
21
  Or install it yourself as:
22
22
 
23
- $ gem install mj
23
+ gem install mj
24
24
 
25
25
  ## Usage
26
26
 
@@ -28,10 +28,21 @@ Or install it yourself as:
28
28
  mj help
29
29
  ```
30
30
 
31
+ ### Git
32
+
33
+ ```
34
+ bundle exec mj git checkout partial-branch-name # it will create a local branch if that is remote only
35
+ bundle exec mj git checkout partial-branch-name --dry-run # if you want to see the command before executing
36
+ ```
37
+
38
+ ```
39
+
31
40
  ### ChatGPT
32
41
 
33
42
  ```
43
+
34
44
  bundle exec mj chatgpt ask "Who won the World Cup in 1994?" --request-file samples/chatgpt/football-team.yml | jq
45
+
35
46
  ```
36
47
 
37
48
  Where the config file looks like:
@@ -113,7 +124,6 @@ query QueryAccountUsers(
113
124
  }
114
125
  ```
115
126
 
116
-
117
127
  ### Alternative file
118
128
 
119
129
  Examples:
@@ -180,7 +190,6 @@ end
180
190
 
181
191
  This way I can use `<leader>a{direction}`, where `k` is `next`, and `j` is `previous` alternative file.
182
192
 
183
-
184
193
  ## Development
185
194
 
186
195
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -189,7 +198,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
189
198
 
190
199
  ## Contributing
191
200
 
192
- Bug reports and pull requests are welcome on GitHub at https://github.com/mjacobus/mj. 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/mjacobus/mj/blob/main/CODE_OF_CONDUCT.md).
201
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/mjacobus/mj>. 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/mjacobus/mj/blob/main/CODE_OF_CONDUCT.md).
193
202
 
194
203
  ## License
195
204
 
@@ -13,10 +13,8 @@ module Mj
13
13
 
14
14
  def resolve(file)
15
15
  file = AlternativeFile::CurrentFile.new(file.to_s)
16
- resolved = []
17
-
18
- @stack.each do |resolver|
19
- resolved.push(resolver.resolve(file))
16
+ resolved = @stack.map do |resolver|
17
+ resolver.resolve(file)
20
18
  end
21
19
 
22
20
  AlternativeFile::Candidates.new(resolved.flatten.compact)
data/lib/mj/cli.rb CHANGED
@@ -5,6 +5,7 @@ require_relative "version"
5
5
  require_relative "alternative_file/thor_command"
6
6
  require_relative "graphql/thor_command"
7
7
  require_relative "chatgpt/thor_command"
8
+ require_relative "git/thor_command"
8
9
 
9
10
  module Mj
10
11
  class Cli < Thor
@@ -25,5 +26,8 @@ module Mj
25
26
 
26
27
  desc "chatgpt", "CLI client for ChatGPT"
27
28
  subcommand "chatgpt", ChatGpt::ThorCommand
29
+
30
+ desc "git", "Git utilities"
31
+ subcommand "git", Git::ThorCommand
28
32
  end
29
33
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "local_branch"
4
+ require_relative "remote_branch"
5
+
6
+ module Mj
7
+ module Git
8
+ class Branches
9
+ include Enumerable
10
+
11
+ def self.from_branch_names(branch_names)
12
+ branches = branch_names.map do |branch|
13
+ branch = branch.sub("*", "").strip
14
+
15
+ if branch.start_with?("remotes/")
16
+ next RemoteBranch.new(branch)
17
+ end
18
+
19
+ next LocalBranch.new(branch)
20
+ end
21
+
22
+ new(branches)
23
+ end
24
+
25
+ def to_local
26
+ self.class.new(map(&:to_local))
27
+ end
28
+
29
+ def uniq
30
+ branches = {}
31
+ each do |branch|
32
+ branches[branch.name] ||= branch
33
+ end
34
+
35
+ self.class.new(branches.values)
36
+ end
37
+
38
+ def initialize(branches)
39
+ @branches = branches
40
+ end
41
+
42
+ def each(&block)
43
+ @branches.each(&block)
44
+ end
45
+
46
+ def length
47
+ @branches.length
48
+ end
49
+
50
+ def matching(pattern)
51
+ self.class.new(@branches.select { |branch| branch.name.match?(pattern) })
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open3"
4
+
5
+ module Mj
6
+ module Git
7
+ class CommandExecuter
8
+ Error = Class.new(RuntimeError)
9
+
10
+ def execute(command)
11
+ stdout_str, stderr_str, status = Open3.capture3(command)
12
+
13
+ if status.success?
14
+ return stdout_str.split("\n")
15
+ end
16
+
17
+ raise Error, "Command '#{command}' exited with (#{status.exitstatus}): #{stderr_str.strip}"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mj
4
+ module Git
5
+ module Commands
6
+ class CheckoutCommand
7
+ attr_reader :branch
8
+
9
+ def initialize(branch:, options: {})
10
+ @branch = branch
11
+ @options = options
12
+ end
13
+
14
+ def dry_run?
15
+ @options[:dry_run]
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../branches"
4
+ require "colorize"
5
+
6
+ module Mj
7
+ module Git
8
+ module Commands
9
+ class CheckoutCommandHandler
10
+ def initialize(stdout:, command_executer: CommandExecuter.new)
11
+ @stdout = stdout
12
+ @command_executer = command_executer
13
+ end
14
+
15
+ def handle(command)
16
+ branches = @command_executer.execute("git branch -a")
17
+ branches = Git::Branches.from_branch_names(branches).matching(command.branch)
18
+
19
+ if branches.to_local.uniq.length > 1
20
+ warn_multiple_matches(branches)
21
+ end
22
+
23
+ winner = branches.min_by(&:length)
24
+
25
+ puts(winner.checkout_command, color: :green)
26
+
27
+ if command.dry_run?
28
+ return
29
+ end
30
+
31
+ @command_executer.execute(winner.checkout_command)
32
+ end
33
+
34
+ private
35
+
36
+ def warn_multiple_matches(branches)
37
+ puts("Multiple branches found:", color: :blue)
38
+
39
+ branches.each do |branch|
40
+ puts("\t#{branch.name}", color: :yellow)
41
+ end
42
+ puts("\n")
43
+ end
44
+
45
+ def puts(string, color: nil)
46
+ if color
47
+ string = string.colorize(color)
48
+ end
49
+
50
+ @stdout.puts(string)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mj
4
+ module Git
5
+ class LocalBranch
6
+ attr_reader :name
7
+
8
+ def initialize(name)
9
+ @name = name
10
+ end
11
+
12
+ def length
13
+ @name.length
14
+ end
15
+
16
+ def checkout_command
17
+ "git checkout #{name}"
18
+ end
19
+
20
+ def to_local
21
+ self
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mj
4
+ module Git
5
+ class RemoteBranch
6
+ attr_reader :name
7
+
8
+ def initialize(name)
9
+ @name = name
10
+ end
11
+
12
+ def checkout_command
13
+ "git checkout -b #{local_branch_name} #{name}"
14
+ end
15
+
16
+ def length
17
+ @name.length
18
+ end
19
+
20
+ def to_local
21
+ LocalBranch.new(local_branch_name)
22
+ end
23
+
24
+ private
25
+
26
+ def local_branch_name
27
+ pattern = %r{^remotes/\w+/}
28
+ name.sub(pattern, "")
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "commands/checkout_command_handler"
4
+ require_relative "commands/checkout_command"
5
+ require_relative "command_executer"
6
+
7
+ module Mj
8
+ module Git
9
+ class ThorCommand < Thor
10
+ desc "checkout <branch>", "Partial branch"
11
+ option :dry_run, type: :boolean, banner: "Just outputs, does not checkout", aliases: :d
12
+ def checkout(branch)
13
+ command = Commands::CheckoutCommand.new(branch: branch, options: options)
14
+ handler = Commands::CheckoutCommandHandler.new(stdout: $stdout)
15
+ handler.handle(command)
16
+ end
17
+ end
18
+ end
19
+ end
data/lib/mj/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mj
4
- VERSION = "0.8.0"
4
+ VERSION = "0.9.0"
5
5
  end
data/mj.gemspec CHANGED
@@ -31,10 +31,12 @@ Gem::Specification.new do |spec|
31
31
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
32
32
  spec.require_paths = ["lib"]
33
33
 
34
+ spec.add_dependency "colorize"
34
35
  spec.add_dependency "koine-rest_client"
35
36
  spec.add_dependency "mj-hash_utils"
36
37
  spec.add_dependency "ruby-openai", "~> 6.2.0"
37
38
  spec.add_dependency "thor", "~> 1.2.1"
39
+ spec.add_dependency "uri", "~> 0.13.0"
38
40
 
39
41
  # For more information and examples about making a new gem, check out our
40
42
  # guide at: https://bundler.io/guides/creating_gem.html
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mj
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcelo Jacobus
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-03-08 00:00:00.000000000 Z
11
+ date: 2024-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colorize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: koine-rest_client
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +80,20 @@ dependencies:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
82
  version: 1.2.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: uri
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.13.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.13.0
69
97
  description: A collection of useful commands for my personal use
70
98
  email:
71
99
  - marcelo.jacobus@gmail.com
@@ -105,6 +133,13 @@ files:
105
133
  - lib/mj/chatgpt/request.rb
106
134
  - lib/mj/chatgpt/thor_command.rb
107
135
  - lib/mj/cli.rb
136
+ - lib/mj/git/branches.rb
137
+ - lib/mj/git/command_executer.rb
138
+ - lib/mj/git/commands/checkout_command.rb
139
+ - lib/mj/git/commands/checkout_command_handler.rb
140
+ - lib/mj/git/local_branch.rb
141
+ - lib/mj/git/remote_branch.rb
142
+ - lib/mj/git/thor_command.rb
108
143
  - lib/mj/graphql/client.rb
109
144
  - lib/mj/graphql/commands/query_file_command.rb
110
145
  - lib/mj/graphql/commands/query_file_command_handler.rb