Plan app export targets in app core

This commit is contained in:
2026-06-02 22:50:42 +02:00
parent 5841878df9
commit b349f24931
11 changed files with 434 additions and 24 deletions

View File

@@ -1,3 +1,4 @@
#include "app_core/document_export.h"
#include "app_core/document_route.h"
#include "app_core/document_session.h"
#include "assets/image_format.h"
@@ -102,6 +103,15 @@ struct PlanDocumentFileArgs {
bool target_exists = false;
};
struct PlanExportTargetArgs {
std::string kind;
std::string work_directory;
std::string directory;
std::string document_name;
std::string extension;
std::string suffix;
};
struct SimulateAppSessionArgs {
bool has_canvas = true;
bool new_document = false;
@@ -362,6 +372,7 @@ void print_help()
<< " inspect-project --path FILE\n"
<< " classify-open --path FILE\n"
<< " plan-document-file --work-dir DIR --name NAME [--target-exists]\n"
<< " plan-export-target --kind file|collection|stem|name --doc-name NAME [--work-dir DIR] [--directory DIR] [--extension EXT] [--suffix SUFFIX]\n"
<< " load-project --path FILE\n"
<< " parse-layout --path FILE\n"
<< " record-render [--width N] [--height N] [--exercise-clear]\n"
@@ -1261,6 +1272,155 @@ int plan_document_file(int argc, char** argv)
return 0;
}
pp::foundation::Status parse_plan_export_target_args(
int argc,
char** argv,
PlanExportTargetArgs& args)
{
for (int i = 2; i < argc; ++i) {
const std::string_view key(argv[i]);
auto read_value = [&](std::string& output) -> pp::foundation::Status {
if (i + 1 >= argc) {
return pp::foundation::Status::invalid_argument("missing value for option");
}
output = argv[++i];
return pp::foundation::Status::success();
};
if (key == "--kind") {
const auto status = read_value(args.kind);
if (!status.ok()) {
return status;
}
} else if (key == "--work-dir") {
const auto status = read_value(args.work_directory);
if (!status.ok()) {
return status;
}
} else if (key == "--directory") {
const auto status = read_value(args.directory);
if (!status.ok()) {
return status;
}
} else if (key == "--doc-name") {
const auto status = read_value(args.document_name);
if (!status.ok()) {
return status;
}
} else if (key == "--extension") {
const auto status = read_value(args.extension);
if (!status.ok()) {
return status;
}
} else if (key == "--suffix") {
const auto status = read_value(args.suffix);
if (!status.ok()) {
return status;
}
} else {
return pp::foundation::Status::invalid_argument("unknown option");
}
}
if (args.kind.empty()) {
return pp::foundation::Status::invalid_argument("kind must not be empty");
}
if (args.document_name.empty()) {
return pp::foundation::Status::invalid_argument("document name must not be empty");
}
if ((args.kind == "file" || args.kind == "collection") && args.work_directory.empty()) {
return pp::foundation::Status::invalid_argument("work directory must not be empty");
}
if (args.kind == "stem" && args.directory.empty()) {
return pp::foundation::Status::invalid_argument("directory must not be empty");
}
if (args.kind == "file" && args.extension.empty()) {
return pp::foundation::Status::invalid_argument("extension must not be empty");
}
if ((args.kind == "collection" || args.kind == "name") && args.suffix.empty()) {
return pp::foundation::Status::invalid_argument("suffix must not be empty");
}
if (args.kind != "file" && args.kind != "collection" && args.kind != "stem" && args.kind != "name") {
return pp::foundation::Status::invalid_argument("unknown export target kind");
}
return pp::foundation::Status::success();
}
int plan_export_target(int argc, char** argv)
{
PlanExportTargetArgs args;
const auto status = parse_plan_export_target_args(argc, argv, args);
if (!status.ok()) {
print_error("plan-export-target", status.message);
return 2;
}
if (args.kind == "file") {
const auto target = pp::app::make_document_export_file_target(
args.work_directory,
args.document_name,
args.extension);
if (!target) {
print_error("plan-export-target", target.status().message);
return 2;
}
std::cout << "{\"ok\":true,\"command\":\"plan-export-target\""
<< ",\"kind\":\"file\",\"target\":{\"path\":\"" << json_escape(target.value().path)
<< "\",\"suggestedName\":\"" << json_escape(target.value().suggested_name)
<< "\"}}\n";
return 0;
}
if (args.kind == "collection") {
const auto target = pp::app::make_document_export_collection_target(
args.work_directory,
args.document_name,
args.suffix);
if (!target) {
print_error("plan-export-target", target.status().message);
return 2;
}
std::cout << "{\"ok\":true,\"command\":\"plan-export-target\""
<< ",\"kind\":\"collection\",\"target\":{\"directory\":\"" << json_escape(target.value().directory)
<< "\",\"stemPath\":\"" << json_escape(target.value().stem_path)
<< "\"}}\n";
return 0;
}
if (args.kind == "stem") {
const auto target = pp::app::make_document_export_stem_target(args.directory, args.document_name);
if (!target) {
print_error("plan-export-target", target.status().message);
return 2;
}
std::cout << "{\"ok\":true,\"command\":\"plan-export-target\""
<< ",\"kind\":\"stem\",\"target\":{\"stemPath\":\"" << json_escape(target.value().stem_path)
<< "\"}}\n";
return 0;
}
const auto target = pp::app::make_document_export_suggested_name(args.document_name, args.suffix);
if (!target) {
print_error("plan-export-target", target.status().message);
return 2;
}
std::cout << "{\"ok\":true,\"command\":\"plan-export-target\""
<< ",\"kind\":\"name\",\"target\":{\"suggestedName\":\"" << json_escape(target.value().name)
<< "\"}}\n";
return 0;
}
pp::foundation::Status parse_simulate_app_session_args(
int argc,
char** argv,
@@ -3243,6 +3403,10 @@ int main(int argc, char** argv)
return plan_document_file(argc, argv);
}
if (command == "plan-export-target") {
return plan_export_target(argc, argv);
}
if (command == "load-project") {
return load_project(argc, argv);
}