smp_tool-cli 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rubocop.yml +16 -0
- data/.vscode/launch.json +21 -0
- data/CHANGELOG.md +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +83 -0
- data/Rakefile +16 -0
- data/exe/smp_tool +16 -0
- data/lib/smp_tool/cli/autoloader.rb +24 -0
- data/lib/smp_tool/cli/commands/base_command.rb +26 -0
- data/lib/smp_tool/cli/commands/delete.rb +28 -0
- data/lib/smp_tool/cli/commands/extract.rb +35 -0
- data/lib/smp_tool/cli/commands/extract_all.rb +28 -0
- data/lib/smp_tool/cli/commands/info.rb +22 -0
- data/lib/smp_tool/cli/commands/input_command.rb +17 -0
- data/lib/smp_tool/cli/commands/new.rb +80 -0
- data/lib/smp_tool/cli/commands/push.rb +29 -0
- data/lib/smp_tool/cli/commands/rename.rb +34 -0
- data/lib/smp_tool/cli/commands/resize.rb +28 -0
- data/lib/smp_tool/cli/commands/squeeze.rb +22 -0
- data/lib/smp_tool/cli/commands/version.rb +19 -0
- data/lib/smp_tool/cli/commands/volume_operation.rb +23 -0
- data/lib/smp_tool/cli/commands.rb +25 -0
- data/lib/smp_tool/cli/executor/base.rb +65 -0
- data/lib/smp_tool/cli/executor/bin_write_mixin.rb +56 -0
- data/lib/smp_tool/cli/executor/creator.rb +30 -0
- data/lib/smp_tool/cli/executor/deleter.rb +16 -0
- data/lib/smp_tool/cli/executor/extracter_base.rb +41 -0
- data/lib/smp_tool/cli/executor/extracter_txt.rb +22 -0
- data/lib/smp_tool/cli/executor/extracter_txt_all.rb +20 -0
- data/lib/smp_tool/cli/executor/informer.rb +78 -0
- data/lib/smp_tool/cli/executor/operator.rb +19 -0
- data/lib/smp_tool/cli/executor/pusher.rb +39 -0
- data/lib/smp_tool/cli/executor/renamer.rb +16 -0
- data/lib/smp_tool/cli/executor/resizer.rb +28 -0
- data/lib/smp_tool/cli/executor/squeezer.rb +16 -0
- data/lib/smp_tool/cli/executor/vol_read_operator.rb +69 -0
- data/lib/smp_tool/cli/executor/vol_read_write_operator.rb +25 -0
- data/lib/smp_tool/cli/executor.rb +10 -0
- data/lib/smp_tool/cli/logger.rb +67 -0
- data/lib/smp_tool/cli/version.rb +7 -0
- data/lib/smp_tool/cli/volume_specs_interface.rb +63 -0
- data/lib/smp_tool/cli.rb +30 -0
- data/sig/smp_tool/cli.rbs +6 -0
- data/smp_tool-cli.gemspec +39 -0
- metadata +172 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: da03ac32fe8ebcf2d0f32f19d49f37b48b7404289bc91cf006e45c4dddc353a1
|
4
|
+
data.tar.gz: 78a43fdd3e6f1f533681e362786ad8059bb07a39703d2e0d6d4dda3f5ffe29da
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a060a0c98f3bef66ef1984f30f0e6098e0219789197009acef2ca157cfa013ee08112df4ef0ea2a0bc6af2fc8b19a690114a7371ae53057c1dd97ad5f7e50c53
|
7
|
+
data.tar.gz: 358a6164fb66b79767900a0f8506304636ce1d67c2201ad2059e39aebe52388dd3dea7fabd34d9e0378c2ab330283a0744b9f6beabd29dd2336c30c5fe61af50
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 3.0
|
3
|
+
|
4
|
+
Style/Documentation:
|
5
|
+
Enabled: false
|
6
|
+
|
7
|
+
Style/StringLiterals:
|
8
|
+
Enabled: true
|
9
|
+
EnforcedStyle: double_quotes
|
10
|
+
|
11
|
+
Style/StringLiteralsInInterpolation:
|
12
|
+
Enabled: true
|
13
|
+
EnforcedStyle: double_quotes
|
14
|
+
|
15
|
+
Layout/LineLength:
|
16
|
+
Max: 120
|
data/.vscode/launch.json
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
{
|
2
|
+
// Use IntelliSense to learn about possible attributes.
|
3
|
+
// Hover to view descriptions of existing attributes.
|
4
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
5
|
+
"version": "0.2.0",
|
6
|
+
"configurations": [
|
7
|
+
{
|
8
|
+
"type": "rdbg",
|
9
|
+
"name": "Debug current file with rdbg",
|
10
|
+
"request": "launch",
|
11
|
+
"script": "${file}",
|
12
|
+
"args": [],
|
13
|
+
"askParameters": true
|
14
|
+
},
|
15
|
+
{
|
16
|
+
"type": "rdbg",
|
17
|
+
"name": "Attach with rdbg",
|
18
|
+
"request": "attach"
|
19
|
+
}
|
20
|
+
]
|
21
|
+
}
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2024 8bit-m8
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# smp_tool/cli
|
2
|
+
|
3
|
+
A Ruby command-line application to work with the Elektronika MK90 volume images.
|
4
|
+
|
5
|
+
## Key features
|
6
|
+
|
7
|
+
* **Supports all common operations**:
|
8
|
+
* creating new volumes;
|
9
|
+
* adding BASIC files to a volume;
|
10
|
+
* deleting BASIC files from a volume;
|
11
|
+
* renaming BASIC files on a volume;
|
12
|
+
* extracting BASIC files from a volume;
|
13
|
+
* changing volume size.
|
14
|
+
|
15
|
+
* **Supports variable volume size: from 4 up to 127 clusters (2048 – 65024 bytes)**
|
16
|
+
|
17
|
+
A standard MPO-10 cartridge has capacity of 20 clusters (10240 bytes), but the tool can create volumes of smaller or larger size. Such volumes can be loaded into a real machine with a modern cartridge such as [azya52/STMP](https://github.com/azya52/STMP) (not tested) or [azya52/PIMP](https://github.com/azya52/PIMP) (seems to work only on BASIC v.1.0 systems, see below). The emulator by Piotr Piatek also supports such volumes.
|
18
|
+
|
19
|
+
* **Supports Elektronika MK90 BASIC v.1.0 and v.2.0 volumes**
|
20
|
+
|
21
|
+
The tool automatically detects the volume version while loading the volume. Manual specification of the target BASIC version requires only to create an empty volume.
|
22
|
+
|
23
|
+
* **Allows to create volumes with the auto-loader**
|
24
|
+
|
25
|
+
Create a volume with the `--bootloader="auto"` option. Then add the `AUTO.BAS` file to the volume files. Mount the volume to the MK90, and select the slot in the main menu. This will automagically load and run any BASIC script defined in the `AUTO.BAS` file. Auto loaders were developed by Piotr Piatek.
|
26
|
+
|
27
|
+
* **Has a special mode that can free one more cluster (512 bytes) to store data**
|
28
|
+
|
29
|
+
Create a volume with the `--n-cls-per-dir-seg=1` option. This will create a volume with a "trimmed" directory segment, allowing to use one more cluster to store data.
|
30
|
+
|
31
|
+
## Known bugs and limitations
|
32
|
+
|
33
|
+
* PIMP cartridge seems to be incompatible with the BASIC v.2.0 system. While the cartridge can run binary code on both version of the system, the access to the volume from the BASIC environment seems to work only on the v.1.0 systems. This is not a bug in the **smp_tool** software but rather a limitation caused by the PIMP design.
|
34
|
+
|
35
|
+
## Prerequisites
|
36
|
+
|
37
|
+
* Ruby ver. >= 3.0.0.
|
38
|
+
|
39
|
+
## Installation
|
40
|
+
|
41
|
+
$ gem install smp_tool-cli
|
42
|
+
|
43
|
+
## Usage
|
44
|
+
|
45
|
+
General syntax is:
|
46
|
+
|
47
|
+
$ smp_tool <command> [options]
|
48
|
+
|
49
|
+
Use the `-h` flag to get the list of available commands:
|
50
|
+
|
51
|
+
$ smp_tool -h
|
52
|
+
|
53
|
+
Call a command with the `-h` flag to get help information about the command:
|
54
|
+
|
55
|
+
$ smp_tool <command> -h
|
56
|
+
|
57
|
+
## Tips
|
58
|
+
|
59
|
+
* To load a program in BASIC 1.0 simply provide a filename in quotes, e.g.: `LOAD "FILE.BAS"`. To load a program in BASIC 2.0 add the parameter `A`, e.g.: `LOAD "FILE.BAS", A`.
|
60
|
+
|
61
|
+
## Development
|
62
|
+
|
63
|
+
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.
|
64
|
+
|
65
|
+
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).
|
66
|
+
|
67
|
+
## Contributing
|
68
|
+
|
69
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/8bit-mate/smp_tool-cli.rb.
|
70
|
+
|
71
|
+
## Special thanks to
|
72
|
+
|
73
|
+
- **[Piotr Piatek](http://www.pisi.com.pl/piotr433/index.htm)**: the indisputable master of the MK90 who developed lots of great software tools and hardware devices for the machine;
|
74
|
+
|
75
|
+
- **[azya52](https://github.com/azya52/)**: the developer of the PIMP cartridge. This device made possible to load large volumes on a real MK90;
|
76
|
+
|
77
|
+
- **[flint-1979](https://phantom.sannata.org/memberlist.php?mode=viewprofile&u=6909)**: testing on the real machines with both BASIC v.1.0 and v.2.0;
|
78
|
+
|
79
|
+
- **[BitSavers project](http://www.bitsavers.org/)**: the largest source of the DEC PDP-11 / RT-11 and other legacy systems documentation.
|
80
|
+
|
81
|
+
## License
|
82
|
+
|
83
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/testtask"
|
5
|
+
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.libs << "test"
|
8
|
+
t.libs << "lib"
|
9
|
+
t.test_files = FileList["test/**/test_*.rb"]
|
10
|
+
end
|
11
|
+
|
12
|
+
require "rubocop/rake_task"
|
13
|
+
|
14
|
+
RuboCop::RakeTask.new
|
15
|
+
|
16
|
+
task default: %i[test rubocop]
|
data/exe/smp_tool
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative "./../lib/smp_tool/cli"
|
5
|
+
|
6
|
+
# DEBUG:
|
7
|
+
# ARGV = "z -i exe/smp0.bin -c -5".split(" ")
|
8
|
+
|
9
|
+
begin
|
10
|
+
Dry::CLI.new(SMPTool::CLI::Commands).call
|
11
|
+
exit 0
|
12
|
+
rescue StandardError => e
|
13
|
+
logger = SMPTool::CLI::Logger.new
|
14
|
+
logger.error(e.message)
|
15
|
+
exit 1
|
16
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
|
5
|
+
module SMPTool
|
6
|
+
module CLI
|
7
|
+
#
|
8
|
+
# Gem's autoloader.
|
9
|
+
#
|
10
|
+
class Autoloader
|
11
|
+
class << self
|
12
|
+
def setup
|
13
|
+
loader = Zeitwerk::Loader.new
|
14
|
+
loader.push_dir(Pathname(__dir__).join("../../")) # lib
|
15
|
+
loader.inflector.inflect(
|
16
|
+
"smp_tool" => "SMPTool",
|
17
|
+
"cli" => "CLI"
|
18
|
+
)
|
19
|
+
loader.setup
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SMPTool
|
4
|
+
module CLI
|
5
|
+
module Commands
|
6
|
+
#
|
7
|
+
# Base class for all commands.
|
8
|
+
#
|
9
|
+
class BaseCommand < Dry::CLI::Command
|
10
|
+
option :verbosity,
|
11
|
+
type: :string,
|
12
|
+
required: false,
|
13
|
+
default: "brief",
|
14
|
+
desc: "Verbosity level: { quiet | brief | verbose | debug }"
|
15
|
+
|
16
|
+
def call(**); end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def _logger(level)
|
21
|
+
Logger.new(level: level)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SMPTool
|
4
|
+
module CLI
|
5
|
+
module Commands
|
6
|
+
#
|
7
|
+
# Delete a file from the volume.
|
8
|
+
#
|
9
|
+
class Delete < VolumeOperation
|
10
|
+
desc "Delete a file from the volume"
|
11
|
+
|
12
|
+
option :filename,
|
13
|
+
required: true,
|
14
|
+
desc: "File to delete",
|
15
|
+
aliases: ["-f"]
|
16
|
+
|
17
|
+
def call(input:, filename:, **options)
|
18
|
+
Executor::Deleter.new(
|
19
|
+
input: input,
|
20
|
+
filename: filename,
|
21
|
+
logger: _logger(options[:verbosity]),
|
22
|
+
**options
|
23
|
+
).call
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SMPTool
|
4
|
+
module CLI
|
5
|
+
module Commands
|
6
|
+
#
|
7
|
+
# Command to extract individual files from the volume.
|
8
|
+
#
|
9
|
+
class Extract < InputCommand
|
10
|
+
desc "Extract individual files from the volume"
|
11
|
+
|
12
|
+
option :dir,
|
13
|
+
required: false,
|
14
|
+
default: Dry::Files.new.pwd,
|
15
|
+
desc: "Output directory",
|
16
|
+
aliases: ["-d"]
|
17
|
+
|
18
|
+
option :f_list,
|
19
|
+
type: :array,
|
20
|
+
required: true,
|
21
|
+
desc: "File(s) to extract",
|
22
|
+
aliases: ["-f"]
|
23
|
+
|
24
|
+
def call(input:, f_list:, **options)
|
25
|
+
Executor::ExtracterTxt.new(
|
26
|
+
input: input,
|
27
|
+
f_list: f_list,
|
28
|
+
logger: _logger(options[:verbosity]),
|
29
|
+
**options
|
30
|
+
).call
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SMPTool
|
4
|
+
module CLI
|
5
|
+
module Commands
|
6
|
+
#
|
7
|
+
# Command to extract all files from the volume.
|
8
|
+
#
|
9
|
+
class ExtractAll < InputCommand
|
10
|
+
desc "Extract all files from the volume"
|
11
|
+
|
12
|
+
option :dir,
|
13
|
+
required: false,
|
14
|
+
default: Dry::Files.new.pwd,
|
15
|
+
desc: "Output directory",
|
16
|
+
aliases: ["-d"]
|
17
|
+
|
18
|
+
def call(input:, **options)
|
19
|
+
Executor::ExtracterTxtAll.new(
|
20
|
+
input: input,
|
21
|
+
logger: _logger(options[:verbosity]),
|
22
|
+
**options
|
23
|
+
).call
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SMPTool
|
4
|
+
module CLI
|
5
|
+
module Commands
|
6
|
+
#
|
7
|
+
# Command to print info about the volume.
|
8
|
+
#
|
9
|
+
class Info < InputCommand
|
10
|
+
desc "Print info about the volume"
|
11
|
+
|
12
|
+
def call(input:, **options)
|
13
|
+
Executor::Informer.new(
|
14
|
+
input: input,
|
15
|
+
logger: _logger(options[:verbosity]),
|
16
|
+
**options
|
17
|
+
).call
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SMPTool
|
4
|
+
module CLI
|
5
|
+
module Commands
|
6
|
+
#
|
7
|
+
# A command with input.
|
8
|
+
#
|
9
|
+
class InputCommand < BaseCommand
|
10
|
+
option :input,
|
11
|
+
required: true,
|
12
|
+
desc: "Input filename",
|
13
|
+
aliases: ["-i"]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SMPTool
|
4
|
+
module CLI
|
5
|
+
module Commands
|
6
|
+
#
|
7
|
+
# Command to create a new volume.
|
8
|
+
#
|
9
|
+
class New < BaseCommand
|
10
|
+
desc "Create a new volume"
|
11
|
+
|
12
|
+
option :output,
|
13
|
+
default: "smp0.bin",
|
14
|
+
required: false,
|
15
|
+
desc: "Output filename",
|
16
|
+
aliases: ["-o"]
|
17
|
+
|
18
|
+
option :basic,
|
19
|
+
required: true,
|
20
|
+
desc: "Target Basic version { 1 | 2 }",
|
21
|
+
aliases: ["-b"]
|
22
|
+
|
23
|
+
option :n_clusters,
|
24
|
+
default: DEF_N_CLUSTERS,
|
25
|
+
required: false,
|
26
|
+
desc: "Number of clusters allocated to the volume",
|
27
|
+
aliases: ["-c"]
|
28
|
+
|
29
|
+
option :n_dir_segs,
|
30
|
+
default: DEF_N_DIR_SEGS,
|
31
|
+
required: false,
|
32
|
+
desc: "Number of directory segments { 1 | 2 }",
|
33
|
+
aliases: ["-d"]
|
34
|
+
|
35
|
+
option :n_cls_per_dir_seg,
|
36
|
+
default: DEF_N_CLS_PER_DIR_SEG,
|
37
|
+
required: false,
|
38
|
+
desc: "Number of clusters per directory segment { 1 | 2 }",
|
39
|
+
aliases: ["-s"]
|
40
|
+
|
41
|
+
option :bootloader,
|
42
|
+
default: DEF_BOOTLOADER,
|
43
|
+
required: false,
|
44
|
+
desc: "Bootloader type { default | auto }",
|
45
|
+
aliases: ["-l"]
|
46
|
+
|
47
|
+
example [
|
48
|
+
"-b 1 # Create a BASIC v.1.0 volume with the default parameters, " \
|
49
|
+
"save result to the `smp0.bin` file (default path)",
|
50
|
+
"-b 2 -o /dir/smp.bin # Create a BASIC v.1.0 volume with the default parameters, " \
|
51
|
+
"save result to the `/dir/smp.bin` file (custom path)",
|
52
|
+
"-b 2 -l auto # Create a BASIC v.2.0 volume with the auto-loader",
|
53
|
+
"-b 1 -c 127 -d 2 # Create the largest possible BASIC v.1.0 volume",
|
54
|
+
"-b 1 -s 1 # Create a BASIC v.1.0 volume with the 'trimmed' directory"
|
55
|
+
]
|
56
|
+
|
57
|
+
def call(output:, basic:, **options)
|
58
|
+
Executor::Creator.new(
|
59
|
+
output: output,
|
60
|
+
volume_specs: _parse_vol_specs(basic, options),
|
61
|
+
logger: _logger(options[:verbosity]),
|
62
|
+
**options
|
63
|
+
).call
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def _parse_vol_specs(basic, options)
|
69
|
+
VolumeSpecsInterface.new(
|
70
|
+
basic: basic,
|
71
|
+
bootloader: options[:bootloader],
|
72
|
+
n_clusters: options[:n_clusters],
|
73
|
+
n_dir_segs: options[:n_dir_segs],
|
74
|
+
n_cls_per_dir_seg: options[:n_cls_per_dir_seg]
|
75
|
+
)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SMPTool
|
4
|
+
module CLI
|
5
|
+
module Commands
|
6
|
+
#
|
7
|
+
# Command to push a file to the volume.
|
8
|
+
#
|
9
|
+
class Push < VolumeOperation
|
10
|
+
desc "Push a list of files to the volume"
|
11
|
+
|
12
|
+
option :f_list,
|
13
|
+
type: :array,
|
14
|
+
required: true,
|
15
|
+
desc: "File(s) to push",
|
16
|
+
aliases: ["-f"]
|
17
|
+
|
18
|
+
def call(input:, f_list:, **options)
|
19
|
+
Executor::Pusher.new(
|
20
|
+
input: input,
|
21
|
+
f_list: f_list,
|
22
|
+
logger: _logger(options[:verbosity]),
|
23
|
+
**options
|
24
|
+
).call
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SMPTool
|
4
|
+
module CLI
|
5
|
+
module Commands
|
6
|
+
#
|
7
|
+
# Command to rename a file on the volume.
|
8
|
+
#
|
9
|
+
class Rename < VolumeOperation
|
10
|
+
desc "Rename a file on the volume"
|
11
|
+
|
12
|
+
option :old_fn,
|
13
|
+
required: true,
|
14
|
+
desc: "File to rename",
|
15
|
+
aliases: ["-o"]
|
16
|
+
|
17
|
+
option :new_fn,
|
18
|
+
required: true,
|
19
|
+
desc: "New filename for the file",
|
20
|
+
aliases: ["-n"]
|
21
|
+
|
22
|
+
def call(input:, new_fn:, old_fn:, **options)
|
23
|
+
Executor::Renamer.new(
|
24
|
+
input: input,
|
25
|
+
old_fn: old_fn,
|
26
|
+
new_fn: new_fn,
|
27
|
+
logger: _logger(options[:verbosity]),
|
28
|
+
**options
|
29
|
+
).call
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SMPTool
|
4
|
+
module CLI
|
5
|
+
module Commands
|
6
|
+
#
|
7
|
+
# Command to change volume size.
|
8
|
+
#
|
9
|
+
class Resize < VolumeOperation
|
10
|
+
desc "Change volume size"
|
11
|
+
|
12
|
+
option :n_clusters,
|
13
|
+
required: true,
|
14
|
+
desc: "Number of clusters to add/trim",
|
15
|
+
aliases: ["-c"]
|
16
|
+
|
17
|
+
def call(input:, n_clusters:, **options)
|
18
|
+
Executor::Resizer.new(
|
19
|
+
input: input,
|
20
|
+
n_clusters: n_clusters,
|
21
|
+
logger: _logger(options[:verbosity]),
|
22
|
+
**options
|
23
|
+
).call
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SMPTool
|
4
|
+
module CLI
|
5
|
+
module Commands
|
6
|
+
#
|
7
|
+
# Command to consolidate all free space at the end of a volume.
|
8
|
+
#
|
9
|
+
class Squeeze < VolumeOperation
|
10
|
+
desc "Consolidate all free space at the end of the volume"
|
11
|
+
|
12
|
+
def call(input:, **options)
|
13
|
+
Executor::Squeezer.new(
|
14
|
+
input: input,
|
15
|
+
logger: _logger(options[:verbosity]),
|
16
|
+
**options
|
17
|
+
).call
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SMPTool
|
4
|
+
module CLI
|
5
|
+
module Commands
|
6
|
+
#
|
7
|
+
# Print version.
|
8
|
+
#
|
9
|
+
class Version < Dry::CLI::Command
|
10
|
+
desc "Print version"
|
11
|
+
|
12
|
+
def call(*)
|
13
|
+
puts "CLI (smp_tool-cli) version: #{SMPTool::CLI::VERSION}"
|
14
|
+
puts "Core lib (smp_tool) version: #{SMPTool::VERSION}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SMPTool
|
4
|
+
module CLI
|
5
|
+
module Commands
|
6
|
+
#
|
7
|
+
# Base class for all commands that do some operation on the volume itself.
|
8
|
+
#
|
9
|
+
class VolumeOperation < InputCommand
|
10
|
+
option :output,
|
11
|
+
required: false,
|
12
|
+
desc: "Output filename",
|
13
|
+
aliases: ["-o"]
|
14
|
+
|
15
|
+
option :apply,
|
16
|
+
type: :boolean,
|
17
|
+
required: false,
|
18
|
+
desc: "Apply result to the input *.bin file",
|
19
|
+
aliases: ["-a"]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SMPTool
|
4
|
+
module CLI
|
5
|
+
#
|
6
|
+
# CLI commands.
|
7
|
+
#
|
8
|
+
module Commands
|
9
|
+
extend Dry::CLI::Registry
|
10
|
+
|
11
|
+
register "new", New, aliases: ["n"]
|
12
|
+
|
13
|
+
register "delete", Delete, aliases: %w[d del]
|
14
|
+
register "extract", Extract, aliases: ["e"]
|
15
|
+
register "extract-all", ExtractAll, aliases: ["x"]
|
16
|
+
register "info", Info, aliases: ["i"]
|
17
|
+
register "push", Push, aliases: ["p"]
|
18
|
+
register "rename", Rename, aliases: ["r"]
|
19
|
+
register "resize", Resize, aliases: ["z"]
|
20
|
+
register "squeeze", Squeeze, aliases: ["s"]
|
21
|
+
|
22
|
+
register "version", Version, aliases: ["-v", "--version"]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|