Skip to content

Commit

Permalink
Fulfill the config subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
yanecc committed May 8, 2024
1 parent b35e261 commit 530d921
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 97 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,27 @@ version Print the version
`-h`: Show this help<br>
`-v`: Print MockGPT's version

## Config subcommand

```
Usage: mockgpt config [rm] <name> <value>
Example:
mockgpt config [all]
mockgpt config init
mockgpt config port
mockgpt config port 8080
mockgpt config rm port gpt
Options:
rm Reset a configuration to the default value
all Display all configurations, same as mockgpt config
init Initialize the configuration file if not exist
-h, --help Show this help for config
```

The config subcommand provides functions to display, modify, and delete (reset) configurations, making it easy to modify the configuration file. It is recommended to run `mockgpt config init` before starting the service for the first time, which will generate the configuration file mocker.json in the user's home directory. You could move the file to the program directory if you want to keep it there.

# Usage

1. Start Ollama and MockGPT services.
Expand Down
21 changes: 21 additions & 0 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,27 @@ version Print the version
`-h`:使用帮助<br>
`-v`:打印MockGPT的版本

## Config 子命令

```
Usage: mockgpt config [rm] <name> <value>
Example:
mockgpt config [all]
mockgpt config init
mockgpt config port
mockgpt config port 8080
mockgpt config rm port gpt
Options:
rm Reset a configuration to the default value
all Display all configurations, same as mockgpt config
init Initialize the configuration file if not exist
-h, --help Show this help for config
```

config子命令提供了展示、修改、删除(重置)配置的功能,用于便捷地修改配置文件。建议在首次启动服务前运行`mockgpt config init`,这将在用户主目录生成配置文件`mocker.json`。如果需要,也可以将配置文件移动到程序目录。

# 使用方法

1. 启动Ollama及MockGPT服务
Expand Down
95 changes: 0 additions & 95 deletions src/mockgpt.cr
Original file line number Diff line number Diff line change
@@ -1,101 +1,6 @@
require "grip"
require "uri"
require "json"
require "colorize"
require "option_parser"
require "./mockgpt/*"
require "./mockgpt/struct/*"

homePath = "#{Path.home}/mocker.json"
exePath = "#{File.dirname Process.executable_path.not_nil!}/mocker.json"
confPath = File.exists?(exePath) ? exePath : homePath
if File.file?(confPath)
mocker = JSON.parse(File.read(confPath))
Mocker.host = mocker["host"].as_s if mocker["host"]?
Mocker.port = mocker["port"].as_i if mocker["port"]?
Mocker.model = mocker["model"].as_s if mocker["model"]?
Mocker.gpt = mocker["gpt"].as_s if mocker["gpt"]?
end

OptionParser.parse do |parser|
parser.banner = "Usage: mockgpt <subcommand>/<options> <arguments>"
parser.on("config", "Display the configuration in effect") do
parser.on("-h", "--help", "Show config help") do
puts CONFIG_HELP
exit
end
parser.unknown_args do |args, options|
if args.size > 2
STDERR.puts "Too many arguments: #{args}", parser
exit(1)
end
case args[0]? || "all"
when "all"
puts "Host \t: #{Mocker.host}"
puts "Port \t: #{Mocker.port}"
puts "Model\t: #{Mocker.model}"
puts "GPT \t: #{Mocker.gpt}"
when "host"
puts Mocker.host
when "port"
puts Mocker.port
when "model"
puts Mocker.model
when "gpt"
puts Mocker.gpt
when "init"
puts "Config file initialized."
when "rm"
args[1]? && case args[1]
when "host"
puts Mocker.host
when "port"
puts Mocker.port
when "model"
puts Mocker.model
when "gpt"
puts Mocker.gpt
else
STDERR.puts "Undefined option: #{args[1]}", CONFIG_HELP
end
else
STDERR.puts "Undefined option: #{args[1]}", CONFIG_HELP
end
exit
end
end
parser.on("upgrade", "Upgrade to the latest version") do
url = "https://github.com/yanecc/MockGPT/tags"
pattern = /href="\/yanecc\/MockGPT\/releases\/tag\/([0-9.]+)"/
latestVersion = Utils.getLatestVersion(url, pattern)
if latestVersion == VERSION
puts "Already up to date."
else
Commands.upgrade if Utils.confirmUpgrade latestVersion
end
exit
end
parser.on("version", "Print the version") do
puts COMMANDS_VERSION
exit
end
parser.on("-b HOST", "--binding HOST", "Bind to the specified host") { |_host| Mocker.host = _host }
parser.on("-p PORT", "--port PORT", "Run on the specified port") { |_port| Mocker.port = _port.to_i }
parser.on("-m MODEL", "--mocker MODEL", "Employ the specified model") { |_model| Mocker.model = _model }
parser.on("-h", "--help", "Show this help") do
puts parser
exit
end
parser.on("-v", "--version", "Print the version") do
puts COMMANDS_VERSION
exit
end
parser.invalid_option do |flag|
STDERR.puts "ERROR: #{flag} is not a valid option."
STDERR.puts parser
exit 1
end
end

mockgpt = Application.new(Mocker.host, Mocker.port)
mockgpt.run
67 changes: 67 additions & 0 deletions src/mockgpt/config.cr
Original file line number Diff line number Diff line change
@@ -1,6 +1,73 @@
require "colorize"

module Mocker
class_property host : String = "localhost"
class_property port : Int32 = 3000
class_property model : String = "llama3"
class_property gpt : String = "gpt-4"
class_property executable = Path[Process.executable_path.not_nil!].stem
end

module Config
extend self

def init(path : Path)
config = self.parse
if File.exists? path
puts "Config file already exists at #{path}"
else
File.write(path, config.to_pretty_json)
puts "Config file created at #{path}"
end
end

def parse
return {
"host" => Mocker.host,
"port" => Mocker.port,
"model" => Mocker.model,
"gpt" => Mocker.gpt,
}
end

def parse(path : Path)
if File.file? path
configHash = Hash(String, String | Int32).from_json File.read(path)
else
self.parse
end
end

def display
puts "Host \t: #{Mocker.host}"
puts "Port \t: #{Mocker.port}"
puts "Model\t: #{Mocker.model}"
puts "GPT \t: #{Mocker.gpt}"
end

def display(key : String)
config = self.parse
puts "#{key} \t: #{config[key]}"
end

def remove(path : Path, keys : Array(String))
config = self.parse path
if File.exists? path
File.write(path, config.reject!(keys).to_pretty_json)
puts "#{keys} got reset."
else
puts "Please create a config file first.", ">> #{Mocker.executable} config init".colorize.bright.light_cyan
end
end

def set(path : Path, key : String, value : String | Int32)
config = self.parse path
if File.exists? path
config[key] = value
File.write(path, config.to_pretty_json)
puts "#{key} got set to #{value}."
else
puts "Please create a config file first.", ">> #{Mocker.executable} config init".colorize.bright.light_cyan
end
end
end
5 changes: 3 additions & 2 deletions src/mockgpt/constants.cr
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ Usage: mockgpt config [rm] <name> <value>
Example:
mockgpt config [all]
mockgpt config init
mockgpt config port
mockgpt config port 8080
mockgpt config rm port
mockgpt config rm port gpt
Options:
rm \t Reset a configuration to the default value
all \t Display all configurations, same as mockgpt config
init \t Initialize the configuration file if not exist
init \t Generate the configuration file if not exist
-h, --help \t Show this help for config
CONFIG
88 changes: 88 additions & 0 deletions src/mockgpt/options.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
require "option_parser"

homePath = Path.home.join "mocker.json"
exePath = Path[File.dirname Process.executable_path.not_nil!].join "mocker.json"
confPath = File.exists?(exePath) ? exePath : homePath
if File.file?(confPath)
mocker = JSON.parse(File.read(confPath))
Mocker.host = mocker["host"].as_s if mocker["host"]?
Mocker.port = mocker["port"].as_i if mocker["port"]?
Mocker.model = mocker["model"].as_s if mocker["model"]?
Mocker.gpt = mocker["gpt"].as_s if mocker["gpt"]?
end

OptionParser.parse do |parser|
parser.banner = "Usage: #{Mocker.executable} <subcommand>/<options> <arguments>"
parser.on("config", "Display the configuration in effect") do
parser.on("-h", "--help", "Show config help") do
puts CONFIG_HELP
exit
end
parser.on("init", "Generate the configuration file") do
Config.init confPath
exit
end
parser.on("rm", "Reset a configuration to the default value") do
parser.unknown_args do |args, _|
Config.remove(confPath, args)
exit
end
end
parser.unknown_args do |args, options|
if args.size > 2
STDERR.puts "Too many arguments: #{args}", parser
exit(1)
end
case args[0]? || "all"
when "all"
Config.display
when "host", "model", "gpt"
if args[1]?
Config.set confPath, args[0], args[1]
else
Config.display args[0]
end
when "port"
if args[1]?
Config.set confPath, args[0], args[1].to_i
else
Config.display args[0]
end
else
STDERR.puts "Undefined option: #{args[0]}", CONFIG_HELP
end
exit
end
end
parser.on("upgrade", "Upgrade to the latest version") do
url = "https://github.com/yanecc/MockGPT/tags"
pattern = /href="\/yanecc\/MockGPT\/releases\/tag\/([0-9.]+)"/
latestVersion = Utils.getLatestVersion(url, pattern)
if latestVersion == VERSION
puts "Already up to date."
else
Commands.upgrade if Utils.confirmUpgrade latestVersion
end
exit
end
parser.on("version", "Print the version") do
puts COMMANDS_VERSION
exit
end
parser.on("-b HOST", "--binding HOST", "Bind to the specified host") { |_host| Mocker.host = _host }
parser.on("-p PORT", "--port PORT", "Run on the specified port") { |_port| Mocker.port = _port.to_i }
parser.on("-m MODEL", "--mocker MODEL", "Employ the specified model") { |_model| Mocker.model = _model }
parser.on("-h", "--help", "Show this help") do
puts parser
exit
end
parser.on("-v", "--version", "Print the version") do
puts COMMANDS_VERSION
exit
end
parser.invalid_option do |flag|
STDERR.puts "ERROR: #{flag} is not a valid option."
STDERR.puts parser
exit 1
end
end

0 comments on commit 530d921

Please sign in to comment.