Skip to content

Commit a31b2f5

Browse files
committed
add script command
1 parent 9cbd632 commit a31b2f5

6 files changed

Lines changed: 92 additions & 3 deletions

File tree

RELEASE.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ The macOS version is a universal binary, codesigned and notarized.
44

55
Changes:
66

7+
0.3.0:
8+
- Slightly change behaviour of `--output-folder`: now, if the input files are within the CWD, the output files will be put into the output folder with the same structure of subfolders.
9+
- Add `script` command to run a series of subcommands.
10+
711
0.2.0:
812
- Rename subcommand `remove-silence` to `trim-silence`
913
- Change `norm` subcommand to take a `--mode` argument; one of `peak` or `rms` rather than `--rms` flag. Default mode is `peak`.

code/common/common.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,24 @@ std::unique_ptr<FILE, void (*)(FILE *)> OpenFile(const fs::path &path, const cha
162162
return {nullptr, SafeFClose};
163163
}
164164

165+
std::string ReadEntireFile(const fs::path &path) {
166+
std::string result {};
167+
auto f = OpenFile(path, "rb");
168+
if (!f) return result;
169+
170+
fseek(f.get(), 0, SEEK_END);
171+
const auto size = ftell(f.get());
172+
fseek(f.get(), 0, SEEK_SET);
173+
174+
result.resize(size);
175+
auto const num_read = fread(result.data(), 1, size, f.get());
176+
if (num_read != (size_t)size) {
177+
WarningWithNewLine("Signet", {}, "could not read file {} for reason: {}", path, strerror(errno));
178+
return {};
179+
}
180+
return result;
181+
}
182+
165183
TEST_CASE("Common") {
166184
{
167185
REQUIRE(GetFreqWithCentDifference(100, 1200) == 200);

code/common/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,4 @@ double GetFreqWithCentDifference(double starting_hz, double cents);
112112

113113
std::unique_ptr<FILE, void (*)(FILE *)> OpenFile(const fs::path &path, const char *mode);
114114
FILE *OpenFileRaw(const fs::path &path, const char *mode, std::error_code *ec = nullptr);
115+
std::string ReadEntireFile(const fs::path &path);

code/signet/signet_interface.cpp

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,12 @@ int SignetInterface::Main(const int argc, const char *const argv[]) {
120120
[](const CLI::App *a, const CLI::App *b) { return a->get_name() < b->get_name(); });
121121

122122
std::map<std::string, std::vector<std::string>> command_categories;
123-
command_categories["Signet Utility"] = {"undo", "clear-backup", "make-docs"};
123+
command_categories["Signet Utility"] = {"undo", "clear-backup", "make-docs", "script"};
124124
command_categories["Filepath"] = {"rename", "move", "folderise"};
125125
command_categories["Audio"] = {
126-
"add-loop", "auto-tune", "fade", "fix-pitch-drift", "gain", "highpass", "lowpass", "norm",
127-
"pan", "reverse", "seamless-loop", "trim", "trim-silence", "tune", "zcross-offset",
126+
"add-loop", "auto-tune", "fade", "fix-pitch-drift", "gain", "highpass",
127+
"lowpass", "norm", "pan", "reverse", "seamless-loop", "trim",
128+
"trim-silence", "tune", "zcross-offset",
128129
};
129130
command_categories["File Data"] = {"convert", "embed-sampler-info"};
130131
command_categories["Info"] = {"detect-pitch", "print-info"};
@@ -302,6 +303,58 @@ int SignetInterface::Main(const int argc, const char *const argv[]) {
302303
}
303304
}
304305

306+
{
307+
auto script = app.add_subcommand(
308+
"script",
309+
"Run a script file containing a list of commands to run. The script file should be a text file with one command per line. The commands should be in the same format as you would use on the command line. Empty lines or lines starting with # are ignored.");
310+
script->add_option("script-file", m_script_filepath, "The filepath for the script file.")
311+
->check(CLI::ExistingPath);
312+
script->final_callback([&]() {
313+
auto file_data = ReadEntireFile(m_script_filepath);
314+
if (file_data.empty()) {
315+
throw CLI::ParseError("script file not accessible or empty", 1);
316+
}
317+
318+
Replace(file_data, "\r\n", "\n");
319+
Replace(file_data, "\r", "\n");
320+
auto lines = Split(file_data, "\n", false);
321+
322+
for (auto line : lines) {
323+
while (line.size() && std::isspace(line.front()))
324+
line.remove_prefix(1);
325+
while (line.size() && std::isspace(line.back()))
326+
line.remove_suffix(1);
327+
328+
if (line.empty()) continue;
329+
if (line[0] == '#') continue;
330+
331+
std::string_view command_name {};
332+
{
333+
size_t pos = 0;
334+
while (pos < line.size() && !std::isspace(line[pos])) {
335+
++pos;
336+
}
337+
command_name = line.substr(0, pos);
338+
}
339+
340+
bool found = false;
341+
for (auto subcommand : app.get_subcommands({})) {
342+
if (subcommand == script) continue;
343+
if (subcommand->get_name() != command_name) continue;
344+
345+
subcommand->clear();
346+
subcommand->parse(std::string(line.substr(command_name.size())));
347+
found = true;
348+
break;
349+
}
350+
351+
if (!found) {
352+
WarningWithNewLine("Signet", {}, "Unknown command: {}", command_name);
353+
}
354+
}
355+
});
356+
}
357+
305358
const auto PrintSuccess = []() {
306359
fmt::print(fmt::fg(fmt::terminal_color::green), "Signet completed successfully.\n");
307360
};

code/signet/signet_interface.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class SignetInterface final {
3636
AudioFiles m_input_audio_files {};
3737
bool m_recursive_directory_search {};
3838
fs::path m_make_docs_filepath {};
39+
fs::path m_script_filepath {};
3940
std::optional<fs::path> m_output_path {};
4041
std::optional<fs::path> m_single_output_file {};
4142
};

docs/usage.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ This is an auto-generated file based on the output of `signet --help`. It contai
5050
- [Signet Utility Commands](#Signet-Utility-Commands)
5151
- [clear-backup](#sound-clear-backup)
5252
- [make-docs](#sound-make-docs)
53+
- [script](#sound-script)
5354
- [undo](#sound-undo)
5455

5556
# General Usage
@@ -806,6 +807,17 @@ Creates a Github flavour markdown file containing the full CLI - based on runnin
806807
`output-file TEXT REQUIRED`
807808
The filepath for the generated markdown file.
808809

810+
## :sound: script
811+
### Description:
812+
Run a script file containing a list of commands to run. The script file should be a text file with one command per line. The commands should be in the same format as you would use on the command line. Empty lines or lines starting with # are ignored.
813+
814+
### Usage:
815+
`script` `[script-file]`
816+
817+
### POSITIONALS:
818+
`script-file TEXT:PATH(existing)`
819+
The filepath for the script file.
820+
809821
## :sound: undo
810822
### Description:
811823
Undo any changes made by the last run of Signet; files that were overwritten are restored, new files that were created are destroyed, and files that were renamed are un-renamed. You can only undo once - you cannot keep going back in history.

0 commit comments

Comments
 (0)