Skip to content

Commit 0d79712

Browse files
committed
feat(config): build config files if source files changed
1 parent e596155 commit 0d79712

File tree

1 file changed

+53
-16
lines changed

1 file changed

+53
-16
lines changed

src/rime/lever/deployment_tasks.cc

+53-16
Original file line numberDiff line numberDiff line change
@@ -314,20 +314,14 @@ bool SchemaUpdate::Run(Deployer* deployer) {
314314
LOG(ERROR) << "invalid schema definition in '" << schema_file_ << "'.";
315315
return false;
316316
}
317-
fs::path shared_data_path(deployer->shared_data_dir);
318-
fs::path user_data_path(deployer->user_data_dir);
319-
fs::path destination_path(user_data_path / (schema_id + ".schema.yaml"));
320-
fs::path trash = user_data_path / "trash";
321-
if (TrashCustomizedCopy(source_path,
322-
destination_path,
323-
"schema/version",
324-
trash)) {
325-
LOG(INFO) << "patched copy of schema '" << schema_id
326-
<< "' is moved to trash";
327-
}
328-
329-
// TODO: compile the config file if needs update
330317

318+
the<DeploymentTask> config_file_update(
319+
new ConfigFileUpdate(schema_id + ".schema.yaml", "schema/version"));
320+
if (!config_file_update->Run(deployer)) {
321+
return false;
322+
}
323+
// reload compiled config
324+
config.reset(Config::Require("schema")->Create(schema_id));
331325
string dict_name;
332326
if (!config->GetString("translator/dictionary", &dict_name)) {
333327
// not requiring a dictionary
@@ -340,16 +334,20 @@ bool SchemaUpdate::Run(Deployer* deployer) {
340334
LOG(ERROR) << "Error creating dictionary '" << dict_name << "'.";
341335
return false;
342336
}
337+
343338
LOG(INFO) << "preparing dictionary '" << dict_name << "'.";
339+
fs::path user_data_path(deployer->user_data_dir);
344340
if (!MaybeCreateDirectory(user_data_path / "build")) {
345341
return false;
346342
}
347343
DictCompiler dict_compiler(dict.get(), "build/");
348344
if (verbose_) {
349345
dict_compiler.set_options(DictCompiler::kRebuild | DictCompiler::kDump);
350346
}
351-
// TODO: use compiled schema instead of the YAML file alone
352-
if (!dict_compiler.Compile(schema_file_)) {
347+
ResourceResolver resolver({"compiled_schema", "build/", ".schema.yaml"});
348+
resolver.set_root_path(user_data_path);
349+
auto compiled_schema = resolver.ResolvePath(schema_id).string();
350+
if (!dict_compiler.Compile(compiled_schema)) {
353351
LOG(ERROR) << "dictionary '" << dict_name << "' failed to compile.";
354352
return false;
355353
}
@@ -368,6 +366,38 @@ ConfigFileUpdate::ConfigFileUpdate(TaskInitializer arg) {
368366
}
369367
}
370368

369+
static bool ConfigNeedsUpdate(Config* config) {
370+
auto build_info = (*config)["__build_info"];
371+
if (!build_info.IsMap()) {
372+
LOG(INFO) << "missing build info";
373+
return true;
374+
}
375+
auto timestamps = build_info["timestamps"];
376+
if (!timestamps.IsMap()) {
377+
LOG(INFO) << "missing timestamps";
378+
return true;
379+
}
380+
the<ResourceResolver> resolver(
381+
Service::instance().CreateResourceResolver({
382+
"config_source_file", "", ".yaml"
383+
}));
384+
for (auto entry : *timestamps.AsMap()) {
385+
fs::path source_file_path = resolver->ResolvePath(entry.first);
386+
if (!fs::exists(source_file_path)) {
387+
LOG(INFO) << "source file not exists: " << source_file_path.string();
388+
return true;
389+
}
390+
auto value = As<ConfigValue>(entry.second);
391+
int recorded_time = 0;
392+
if (!value || !value->GetInt(&recorded_time) ||
393+
recorded_time != (int) fs::last_write_time(source_file_path)) {
394+
LOG(INFO) << "timestamp mismatch: " << source_file_path.string();
395+
return true;
396+
}
397+
}
398+
return false;
399+
}
400+
371401
bool ConfigFileUpdate::Run(Deployer* deployer) {
372402
fs::path shared_data_path(deployer->shared_data_dir);
373403
fs::path user_data_path(deployer->user_data_dir);
@@ -385,7 +415,14 @@ bool ConfigFileUpdate::Run(Deployer* deployer) {
385415
trash)) {
386416
LOG(INFO) << "patched copy of '" << file_name_ << "' is moved to trash.";
387417
}
388-
// TODO: compile the config file if needs update
418+
// build the config file if needs update
419+
the<Config> config(Config::Require("config")->Create(file_name_));
420+
if (ConfigNeedsUpdate(config.get())) {
421+
if (!MaybeCreateDirectory(user_data_path / "build")) {
422+
return false;
423+
}
424+
config.reset(Config::Require("config_builder")->Create(file_name_));
425+
}
389426
return true;
390427
}
391428

0 commit comments

Comments
 (0)