patcmd 0.1.0 → 0.1.1

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: df47864b3b6c9a8606d01d8c3ea358f27af72fe692323922ea69d2f8ef4fd9b1
4
- data.tar.gz: a3aaabeaf982f67f7ee4ec58627b74f79841c9667c4cd7797d12e2e8377b078f
3
+ metadata.gz: e08b470213e3e2014f9dbb67081a5bedc21eb0a6914039ebfa5d95cfbc8aa21c
4
+ data.tar.gz: 968f2c23d043c84887920498c2075ee0e327de83a6f4c43c53ab24b421cec8f6
5
5
  SHA512:
6
- metadata.gz: 49aaa3694b43c32251556f93b4a27c787809df5e580191c41ef51c9b0d2fe04c1921ac7290d847ed2096f0a64cc0a83079af804543d3fffe1fb3943b705f98e9
7
- data.tar.gz: fca5cbe7172f95b3903f47796f8f36a535d463f7e0b04a28f30eb097744ebd4e3d4e0bb4288b1ef7320aef151bbe934ef1d0ec3370a3f1afd0c3cd01c8cb8690
6
+ metadata.gz: 13b6bd069fa64889bb29aff3f5a6c46ea6a4eb7a0fd6e60eda28d1863391748911a840e9a376269d873424b7ba080dd69814b7f98c08368741444a5638546b0a
7
+ data.tar.gz: 26c39484a084cd4908c0a56dc0d5eff01af124b5f029d0c7ad0b818369e2ea684480e29e9885819434c270bfc299e7d43474de4dd05b448b8207f2c0290b2bf8
data/.rubocop.yml CHANGED
@@ -4,6 +4,8 @@ inherit_gem:
4
4
  AllCops:
5
5
  TargetRubyVersion: 3.0
6
6
  Exclude:
7
+ - 'Gemfile'
8
+ - 'Rakefile'
7
9
  - '.git/**/*'
8
10
 
9
11
  Style/StringLiterals:
@@ -0,0 +1,32 @@
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "type": "ruby_lsp",
6
+ "name": "RSpec: Run Current Spec File",
7
+ "request": "launch",
8
+ "program": "${workspaceFolder}/bin/rspec ${file}",
9
+ "env": {
10
+ "RAILS_ENV": "test"
11
+ }
12
+ },
13
+ {
14
+ "type": "ruby_lsp",
15
+ "name": "RSpec: Run All Specs",
16
+ "request": "launch",
17
+ "program": "${workspaceFolder}/bin/rspec",
18
+ "env": {
19
+ "RAILS_ENV": "test"
20
+ }
21
+ },
22
+ {
23
+ "type": "ruby_lsp",
24
+ "name": "RSpec: Run Test at Cursor",
25
+ "request": "launch",
26
+ "program": "${workspaceFolder}/bin/rspec ${file}:${lineNumber}",
27
+ "env": {
28
+ "RAILS_ENV": "test"
29
+ }
30
+ }
31
+ ]
32
+ }
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Patcmd
4
+ module CLI
5
+ class CommandRunner
6
+ def initialize(task, options, env_vars)
7
+ @task = task
8
+ @options = options
9
+ @env_vars = env_vars
10
+ @logger = Logger.new(verbose: options[:verbose])
11
+ end
12
+
13
+ def execute
14
+ command = prepare_command
15
+ path = PathResolver.expand(@task.path)
16
+
17
+ unless Dir.exist?(path)
18
+ @logger.error("Path not found: #{path}")
19
+ exit(1)
20
+ end
21
+
22
+ @logger.info("Executing '#{@task.description}' in #{path}")
23
+ @logger.info("Command: #{command}") if @options[:verbose]
24
+ @logger.info("Environment Variables: #{@env_vars}") if @options[:verbose] && @env_vars.any?
25
+
26
+ Dir.chdir(path) do
27
+ result = system(@env_vars, command)
28
+ unless result
29
+ @logger.error("Command execution failed.")
30
+ exit(1)
31
+ end
32
+ end
33
+ @logger.success("Command executed successfully.")
34
+ rescue KeyError => e
35
+ @logger.error("Missing option for command substitution: #{e.message}")
36
+ exit(1)
37
+ end
38
+
39
+ private
40
+
41
+ def prepare_command
42
+ substitution_vars = @options[:options] ? @options[:options].transform_keys(&:to_sym) : {}
43
+ cmd = @task.command % substitution_vars
44
+ args = @task.args.map { |arg| arg % substitution_vars }
45
+ ([cmd] + args).join(" ")
46
+ end
47
+ end
48
+ end
49
+ end
@@ -2,38 +2,32 @@
2
2
 
3
3
  module Patcmd
4
4
  module CLI
5
- class AddCommand < BaseCommand
6
- default_task :add
5
+ module Commands
6
+ class AddCommand < BaseCommand
7
+ default_task :add
7
8
 
8
- desc "add", "Add a new task to the config"
9
- method_option :name, aliases: "-n", required: true, desc: "Task name"
10
- method_option :description, aliases: "-d", required: true, desc: "Task description"
11
- method_option :category, aliases: "-c", required: true, desc: "Category name"
12
- method_option :path, aliases: "-p", required: true, desc: "Execution path"
13
- method_option :action, aliases: "-a", required: true, desc: "Action name"
14
- method_option :command, aliases: "-m", required: true, desc: "Command to execute"
15
- method_option :args, aliases: "-g", type: :array, default: [], desc: "Arguments for the command"
16
- method_option :environments, aliases: "-e", type: :hash, default: {}, desc: "Environment variables"
17
- def add
18
- task = build_task_from_options
19
- validate_task(task)
20
- config_manager.add_task(task)
21
- puts "Added task '#{task["name"]}' under category '#{task["category"]}' with action '#{task["action"]}'."
22
- end
23
-
24
- private
9
+ desc "add", "Add a new task to the config"
10
+ method_option :name, aliases: "-n", required: true, desc: "Task name"
11
+ method_option :description, aliases: "-d", required: true, desc: "Task description"
12
+ method_option :category, aliases: "-c", required: true, desc: "Category name"
13
+ method_option :path, aliases: "-p", required: true, desc: "Execution path"
14
+ method_option :action, aliases: "-a", required: true, desc: "Action name"
15
+ method_option :command, aliases: "-m", required: true, desc: "Command to execute"
16
+ method_option :args, aliases: "-g", type: :array, default: [], desc: "Arguments for the command"
17
+ method_option :environments, aliases: "-e", type: :hash, default: {}, desc: "Environment variables"
25
18
 
26
- def build_task_from_options
27
- {
28
- "name" => options[:name],
29
- "description" => options[:description],
30
- "category" => options[:category],
31
- "path" => options[:path],
32
- "action" => options[:action],
33
- "command" => options[:command],
34
- "args" => options[:args],
35
- "environments" => options[:environments],
36
- }
19
+ def add
20
+ task = Services::TaskBuilder.build_from_options(options)
21
+ Services::TaskValidator.validate(task)
22
+ config_manager.add_task(task)
23
+ Presenters::TaskPresenter.new($stdout).display(task)
24
+ logger.success(
25
+ "Added task '#{task["name"]}' under category '#{task["category"]}' with action '#{task["action"]}'.",
26
+ )
27
+ rescue Services::TaskValidator::ValidationError => e
28
+ logger.error("Error: #{e.message}")
29
+ exit(1)
30
+ end
37
31
  end
38
32
  end
39
33
  end
@@ -2,23 +2,23 @@
2
2
 
3
3
  module Patcmd
4
4
  module CLI
5
- class BaseCommand < Thor
6
- include Helpers::TaskHelper
7
- include Helpers::Logger
5
+ module Commands
6
+ class BaseCommand < Thor
7
+ CONFIG_PATH = File.expand_path("~/.patcmd/config.yml")
8
8
 
9
- CONFIG_PATH = File.expand_path("~/.patcmd/config.yml")
9
+ # Define global options
10
+ class_option :config, type: :string, default: CONFIG_PATH, desc: "Path to configuration file"
10
11
 
11
- # Define global options
12
- class_option :config, type: :string, default: CONFIG_PATH, desc: "Path to configuration file"
12
+ def initialize(*args)
13
+ super
14
+ @config_manager = ConfigurationManager.new(options[:config])
15
+ @logger = Logger.new(verbose: options[:verbose])
16
+ end
13
17
 
14
- def initialize(*args)
15
- super
16
- @config_manager = ConfigurationManager.new(options[:config])
17
- end
18
-
19
- private
18
+ private
20
19
 
21
- attr_reader :config_manager
20
+ attr_reader :config_manager, :logger
21
+ end
22
22
  end
23
23
  end
24
24
  end
@@ -1,25 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "base_command"
4
- require_relative "init_command"
5
- require_relative "add_command"
6
- require_relative "list_command"
7
- require_relative "exec_command"
3
+ require "patcmd/cli/commands/base_command"
4
+ require "patcmd/cli/commands/init_command"
5
+ require "patcmd/cli/commands/add_command"
6
+ require "patcmd/cli/commands/list_command"
7
+ require "patcmd/cli/commands/exec_command"
8
8
 
9
9
  module Patcmd
10
10
  module CLI
11
- class Core < Thor
12
- class << self
13
- # Ensure the CLI exits with a non-zero status code on failure
14
- def exit_on_failure?
15
- true
11
+ module Commands
12
+ class Core < Thor
13
+ class << self
14
+ # Ensure the CLI exits with a non-zero status code on failure
15
+ def exit_on_failure?
16
+ true
17
+ end
16
18
  end
17
- end
18
19
 
19
- register InitCommand, "init", "init", "Initialize the PatCmd configuration"
20
- register AddCommand, "add", "add", "Add a new task to the config"
21
- register ListCommand, "list", "list", "List all configured tasks"
22
- register ExecCommand, "exec", "exec CATEGORY NAME ACTION", "Execute a defined task"
20
+ register InitCommand, "init", "init", "Initialize the PatCmd configuration"
21
+ register AddCommand, "add", "add", "Add a new task to the config"
22
+ register ListCommand, "list", "list", "List all configured tasks"
23
+ register ExecCommand, "exec", "exec CATEGORY NAME ACTION", "Execute a defined task"
24
+ end
23
25
  end
24
26
  end
25
27
  end
@@ -2,18 +2,20 @@
2
2
 
3
3
  module Patcmd
4
4
  module CLI
5
- class ExecCommand < BaseCommand
6
- default_task :exec
5
+ module Commands
6
+ class ExecCommand < BaseCommand
7
+ default_task :exec
7
8
 
8
- desc "exec CATEGORY NAME ACTION", "Execute a defined task"
9
- def exec(category, name, action)
10
- task = config_manager.find_task(category, name, action)
11
- if task
12
- executor = TaskExecutor.new(task, options)
13
- executor.execute
14
- else
15
- puts "Task not found for category '#{category}', name '#{name}', and action '#{action}'."
16
- exit(1)
9
+ desc "exec CATEGORY NAME ACTION", "Execute a defined task"
10
+ def exec(category, name, action)
11
+ task = config_manager.find_task(category, name, action)
12
+ if task
13
+ executor = TaskExecutor.new(task, options)
14
+ executor.execute
15
+ else
16
+ puts "Task not found for category '#{category}', name '#{name}', and action '#{action}'."
17
+ exit(1)
18
+ end
17
19
  end
18
20
  end
19
21
  end
@@ -2,13 +2,15 @@
2
2
 
3
3
  module Patcmd
4
4
  module CLI
5
- class InitCommand < BaseCommand
6
- default_task :init
5
+ module Commands
6
+ class InitCommand < BaseCommand
7
+ default_task :init
7
8
 
8
- desc "init", "Initialize the PatCmd configuration"
9
- def init
10
- config_manager.init_config
11
- puts "Configuration initialized at #{config_manager.config_path}"
9
+ desc "init", "Initialize the PatCmd configuration"
10
+ def init
11
+ config_manager.init_config
12
+ puts "Configuration initialized at #{config_manager.config_path}"
13
+ end
12
14
  end
13
15
  end
14
16
  end
@@ -2,16 +2,22 @@
2
2
 
3
3
  module Patcmd
4
4
  module CLI
5
- class ListCommand < BaseCommand
6
- default_task :list
5
+ module Commands
6
+ class ListCommand < BaseCommand
7
+ default_task :list
7
8
 
8
- desc "list", "List all configured tasks"
9
- def list
10
- tasks = config_manager.all_tasks
11
- if tasks.empty?
12
- puts "No tasks configured."
13
- else
14
- tasks.each { |task| display_task(task) }
9
+ desc "list", "List all configured tasks"
10
+ def list
11
+ tasks = config_manager.all_tasks
12
+ if tasks.empty?
13
+ logger.info("No tasks configured.")
14
+ else
15
+ presenter = Presenters::TaskPresenter.new($stdout)
16
+ tasks.each { |task| presenter.display(task) }
17
+ end
18
+ rescue StandardError => e
19
+ logger.error("An error occurred while listing tasks: #{e.message}")
20
+ exit(1)
15
21
  end
16
22
  end
17
23
  end
@@ -1,14 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "thor"
4
-
5
- require_relative "core"
4
+ require "patcmd/cli/commands/core"
6
5
 
7
6
  module Patcmd
8
7
  module CLI
9
8
  class << self
10
9
  def start(argv)
11
- Core.start(argv)
10
+ Commands::Core.start(argv)
12
11
  end
13
12
  end
14
13
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Patcmd
4
+ module CLI
5
+ class EnvironmentPreparer
6
+ def initialize(options = {})
7
+ @options = options
8
+ end
9
+
10
+ def prepare(env_vars)
11
+ substitution_vars = prepare_substitution_vars
12
+ env_vars.transform_values { |v| v % substitution_vars }
13
+ end
14
+
15
+ private
16
+
17
+ def prepare_substitution_vars
18
+ return {} unless @options[:options]
19
+
20
+ @options[:options].transform_keys(&:to_sym)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Patcmd
4
+ module CLI
5
+ class Logger
6
+ COLORS = {
7
+ info: "\e[34m", # Blue
8
+ success: "\e[32m", # Green
9
+ error: "\e[31m", # Red
10
+ warn: "\e[33m", # Yellow
11
+ reset: "\e[0m", # Reset
12
+ }.freeze
13
+
14
+ def initialize(verbose: false)
15
+ @verbose = verbose
16
+ end
17
+
18
+ def info(message)
19
+ log(:info, message)
20
+ end
21
+
22
+ def success(message)
23
+ log(:success, message)
24
+ end
25
+
26
+ def error(message)
27
+ log(:error, message)
28
+ end
29
+
30
+ def warn(message)
31
+ log(:warn, message)
32
+ end
33
+
34
+ private
35
+
36
+ def log(level, message)
37
+ return unless @verbose || level == :error
38
+
39
+ color = COLORS[level] || COLORS[:info]
40
+ puts "#{color}[#{level.to_s.upcase}]#{COLORS[:reset]} #{message}"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Patcmd
4
+ module CLI
5
+ class PathResolver
6
+ class << self
7
+ def expand(path)
8
+ return if path.nil? || path.strip.empty?
9
+
10
+ # Expand tilde (~) and substitute environment variables
11
+ expanded_path = path.gsub("~", Dir.home)
12
+ expanded_path.gsub!(/\$\{([^\}]+)\}/) { ENV[::Regexp.last_match(1)] || "" }
13
+
14
+ # Ensure the path does not double-resolve
15
+ File.expand_path(expanded_path)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Patcmd
4
+ module CLI
5
+ module Presenters
6
+ class TaskPresenter
7
+ def initialize(output = $stdout)
8
+ @output = output
9
+ end
10
+
11
+ def display(task)
12
+ @output.puts "Category: #{task["category"]}"
13
+ @output.puts " Name: #{task["name"]}"
14
+ @output.puts " Action: #{task["action"]}"
15
+ @output.puts " Description: #{task["description"]}"
16
+ @output.puts " Path: #{task["path"]}"
17
+ @output.puts " Command: #{task["command"]}"
18
+ @output.puts " Args: #{task["args"].join(" ")}" if task["args"]&.any?
19
+ if task["environments"]&.any?
20
+ envs = task["environments"].map { |k, v| "#{k}=#{v}" }.join(", ")
21
+ @output.puts " Environments: #{envs}"
22
+ end
23
+ @output.puts "-" * 40
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Patcmd
4
+ module CLI
5
+ module Presenters
6
+ Dir[File.join(__dir__, "presenters", "*.rb")].each do |file|
7
+ require file
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Patcmd
4
+ module CLI
5
+ module Services
6
+ class TaskBuilder
7
+ class << self
8
+ def build_from_options(options)
9
+ {
10
+ "name" => options[:name],
11
+ "description" => options[:description],
12
+ "category" => options[:category],
13
+ "path" => options[:path],
14
+ "action" => options[:action],
15
+ "command" => options[:command],
16
+ "args" => options[:args],
17
+ "environments" => options[:environments],
18
+ }
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Patcmd
4
+ module CLI
5
+ module Services
6
+ class TaskValidator
7
+ class ValidationError < StandardError; end
8
+
9
+ REQUIRED_FIELDS = ["name", "description", "category", "path", "action", "command"].freeze
10
+
11
+ class << self
12
+ def validate(task)
13
+ missing_fields = REQUIRED_FIELDS.select { |field| task[field].nil? || task[field].strip.empty? }
14
+
15
+ unless missing_fields.empty?
16
+ raise ValidationError, "Missing required fields: #{missing_fields.join(", ")}"
17
+ end
18
+
19
+ unless task["args"].is_a?(Array)
20
+ raise ValidationError, "The 'args' field must be an array."
21
+ end
22
+
23
+ unless task["environments"].is_a?(Hash)
24
+ raise ValidationError, "The 'environments' field must be a hash."
25
+ end
26
+
27
+ true
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Patcmd
4
+ module CLI
5
+ module Services
6
+ Dir[File.join(__dir__, "services", "*.rb")].each do |file|
7
+ require file
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Patcmd
4
+ module CLI
5
+ class Task
6
+ attr_reader :description, :command, :args, :environments, :path
7
+
8
+ def initialize(task)
9
+ @description = task["description"]
10
+ @command = task["command"]
11
+ @args = task["args"] || []
12
+ @environments = task["environments"] || {}
13
+ @path = task["path"]
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,70 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "patcmd/cli/task"
4
+ require "patcmd/cli/environment_preparer"
5
+ require "patcmd/cli/command_runner"
6
+ require "patcmd/cli/path_resolver"
7
+
3
8
  module Patcmd
4
9
  module CLI
5
10
  class TaskExecutor
6
- require "shellwords"
7
-
8
11
  def initialize(task, options)
9
- @task = task
12
+ @task = Task.new(task)
10
13
  @options = options
11
14
  end
12
15
 
13
16
  def execute
14
- command = prepare_command
15
- env_vars = prepare_environment_variables
16
- path = expand_path(@task["path"])
17
-
18
- unless Dir.exist?(path)
19
- puts "Path not found: #{path}"
20
- exit(1)
21
- end
22
-
23
- puts "Executing '#{@task["description"]}' in #{path}"
24
- puts "Command: #{command}" if @options[:verbose]
25
- puts "Environment Variables: #{env_vars}" if @options[:verbose] && env_vars.any?
26
-
27
- Dir.chdir(path) do
28
- result = system(env_vars, command)
29
- unless result
30
- puts "Command execution failed."
31
- exit(1)
32
- end
33
- end
34
- rescue KeyError => e
35
- puts "Missing option for command substitution: #{e.message}"
36
- exit(1)
37
- end
38
-
39
- private
40
-
41
- def prepare_command
42
- cmd = @task["command"]
43
- args = @task["args"] || []
44
-
45
- # Handle command substitution
46
- if @options[:options] && !@options[:options].empty?
47
- substitution_vars = @options[:options].transform_keys(&:to_sym)
48
- cmd %= substitution_vars
49
- args = args.map { |arg| arg % substitution_vars }
50
- end
51
-
52
- ([cmd] + args).join(" ")
53
- end
54
-
55
- def prepare_environment_variables
56
- env_vars = @task["environments"] || {}
57
-
58
- if @options[:options] && !@options[:options].empty?
59
- substitution_vars = @options[:options].transform_keys(&:to_sym)
60
- env_vars = env_vars.transform_values { |v| v % substitution_vars }
61
- end
62
-
63
- env_vars
64
- end
65
-
66
- def expand_path(path)
67
- File.expand_path(path.gsub("~", Dir.home))
17
+ env_vars = EnvironmentPreparer.new(@options).prepare(@task.environments)
18
+ CommandRunner.new(@task, @options, env_vars).execute
68
19
  end
69
20
  end
70
21
  end
data/lib/patcmd/cli.rb CHANGED
@@ -1,6 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "cli/cli"
3
+ require "patcmd/cli/logger"
4
+ require "patcmd/cli/configuration_manager"
5
+ require "patcmd/cli/task_executor"
6
+ require "patcmd/cli/presenters"
7
+ require "patcmd/cli/services"
8
+ require "patcmd/cli/commands"
9
+
4
10
  module Patcmd
5
11
  module CLI
6
12
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Patcmd
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
data/lib/patcmd.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "patcmd/version"
4
- require_relative "patcmd/cli"
3
+ require "patcmd/version"
4
+ require "patcmd/cli"
5
5
 
6
6
  module Patcmd
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: patcmd
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
  - Huy Nguyen
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-12-05 00:00:00.000000000 Z
11
+ date: 2024-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -36,6 +36,7 @@ files:
36
36
  - ".rspec"
37
37
  - ".rubocop.yml"
38
38
  - ".tool-versions"
39
+ - ".vscode/launch.json"
39
40
  - ".vscode/settings.json"
40
41
  - CODE_OF_CONDUCT.md
41
42
  - LICENSE.txt
@@ -44,26 +45,35 @@ files:
44
45
  - bin/patcmd
45
46
  - lib/patcmd.rb
46
47
  - lib/patcmd/cli.rb
47
- - lib/patcmd/cli/cli.rb
48
+ - lib/patcmd/cli/command_runner.rb
49
+ - lib/patcmd/cli/commands.rb
48
50
  - lib/patcmd/cli/commands/add_command.rb
49
51
  - lib/patcmd/cli/commands/base_command.rb
50
- - lib/patcmd/cli/commands/commands.rb
51
52
  - lib/patcmd/cli/commands/core.rb
52
53
  - lib/patcmd/cli/commands/exec_command.rb
53
54
  - lib/patcmd/cli/commands/init_command.rb
54
55
  - lib/patcmd/cli/commands/list_command.rb
55
56
  - lib/patcmd/cli/configuration_manager.rb
56
- - lib/patcmd/cli/helpers/helpers.rb
57
- - lib/patcmd/cli/helpers/logger.rb
58
- - lib/patcmd/cli/helpers/task_helper.rb
57
+ - lib/patcmd/cli/environment_preparer.rb
58
+ - lib/patcmd/cli/logger.rb
59
+ - lib/patcmd/cli/path_resolver.rb
60
+ - lib/patcmd/cli/presenters.rb
61
+ - lib/patcmd/cli/presenters/task_presenter.rb
62
+ - lib/patcmd/cli/services.rb
63
+ - lib/patcmd/cli/services/task_builder.rb
64
+ - lib/patcmd/cli/services/task_validator.rb
65
+ - lib/patcmd/cli/task.rb
59
66
  - lib/patcmd/cli/task_executor.rb
60
67
  - lib/patcmd/version.rb
61
68
  - sig/patcmd.rbs
62
69
  homepage: https://github.com/patrick204nqh/patcmd
63
70
  licenses:
64
71
  - MIT
65
- metadata: {}
66
- post_install_message:
72
+ metadata:
73
+ homepage_uri: https://github.com/patrick204nqh/patcmd
74
+ source_code_uri: https://github.com/patrick204nqh/patcmd
75
+ changelog_uri: https://github.com/patrick204nqh/patcmd/blob/main/CHANGELOG.md
76
+ post_install_message:
67
77
  rdoc_options: []
68
78
  require_paths:
69
79
  - lib
@@ -79,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
89
  version: '0'
80
90
  requirements: []
81
91
  rubygems_version: 3.5.3
82
- signing_key:
92
+ signing_key:
83
93
  specification_version: 4
84
94
  summary: A CLI tool for running tasks quickly.
85
95
  test_files: []
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "configuration_manager"
4
- require_relative "task_executor"
5
- require_relative "helpers/helpers"
6
- require_relative "commands/commands"
7
-
8
- module Patcmd
9
- module CLI
10
- end
11
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "task_helper"
4
- require_relative "logger"
5
-
6
- module Patcmd
7
- module CLI
8
- module Helpers
9
- end
10
- end
11
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Patcmd
4
- module CLI
5
- module Helpers
6
- module Logger
7
- # Logs an informational message with a timestamp.
8
- #
9
- # @param message [String] The message to log.
10
- # @return [void]
11
- def log_info(message)
12
- puts "[INFO] #{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{message}"
13
- end
14
-
15
- # Logs an error message with a timestamp.
16
- #
17
- # @param message [String] The message to log.
18
- # @return [void]
19
- def log_error(message)
20
- puts "[ERROR] #{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{message}"
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Patcmd
4
- module CLI
5
- module Helpers
6
- module TaskHelper
7
- class ValidationError < StandardError; end
8
-
9
- def validate_task(task)
10
- required_fields = ["name", "description", "category", "path", "action", "command"]
11
- missing_fields = required_fields.select { |field| task[field].nil? || task[field].strip.empty? }
12
-
13
- unless missing_fields.empty?
14
- raise ValidationError, "Missing required fields: #{missing_fields.join(", ")}"
15
- exit(1)
16
- end
17
-
18
- unless task["args"].is_a?(Array)
19
- rails(ValidationError, "The 'args' field must be an array.")
20
- exit(1)
21
- end
22
-
23
- unless task["environments"].is_a?(Hash)
24
- rails(ValidationError, "The 'environments' field must be a hash.")
25
- exit(1)
26
- end
27
- end
28
-
29
- def display_task(task)
30
- puts "Category: #{task["category"]}"
31
- puts " Name: #{task["name"]}"
32
- puts " Action: #{task["action"]}"
33
- puts " Description: #{task["description"]}"
34
- puts " Path: #{task["path"]}"
35
- puts " Command: #{task["command"]}"
36
- puts " Args: #{task["args"].join(" ")}" if task["args"].any?
37
- if task["environments"].any?
38
- envs = task["environments"].map { |k, v| "#{k}=#{v}" }.join(", ")
39
- puts " Environments: #{envs}"
40
- end
41
- puts "-" * 40
42
- end
43
- end
44
- end
45
- end
46
- end