Skip to content

Commit

Permalink
feat(config): build config files if source files changed
Browse files Browse the repository at this point in the history
  • Loading branch information
lotem committed Feb 12, 2018
1 parent e596155 commit 0d79712
Showing 1 changed file with 53 additions and 16 deletions.
69 changes: 53 additions & 16 deletions src/rime/lever/deployment_tasks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -314,20 +314,14 @@ bool SchemaUpdate::Run(Deployer* deployer) {
LOG(ERROR) << "invalid schema definition in '" << schema_file_ << "'.";
return false;
}
fs::path shared_data_path(deployer->shared_data_dir);
fs::path user_data_path(deployer->user_data_dir);
fs::path destination_path(user_data_path / (schema_id + ".schema.yaml"));
fs::path trash = user_data_path / "trash";
if (TrashCustomizedCopy(source_path,
destination_path,
"schema/version",
trash)) {
LOG(INFO) << "patched copy of schema '" << schema_id
<< "' is moved to trash";
}

// TODO: compile the config file if needs update

the<DeploymentTask> config_file_update(
new ConfigFileUpdate(schema_id + ".schema.yaml", "schema/version"));
if (!config_file_update->Run(deployer)) {
return false;
}
// reload compiled config
config.reset(Config::Require("schema")->Create(schema_id));
string dict_name;
if (!config->GetString("translator/dictionary", &dict_name)) {
// not requiring a dictionary
Expand All @@ -340,16 +334,20 @@ bool SchemaUpdate::Run(Deployer* deployer) {
LOG(ERROR) << "Error creating dictionary '" << dict_name << "'.";
return false;
}

LOG(INFO) << "preparing dictionary '" << dict_name << "'.";
fs::path user_data_path(deployer->user_data_dir);
if (!MaybeCreateDirectory(user_data_path / "build")) {
return false;
}
DictCompiler dict_compiler(dict.get(), "build/");
if (verbose_) {
dict_compiler.set_options(DictCompiler::kRebuild | DictCompiler::kDump);
}
// TODO: use compiled schema instead of the YAML file alone
if (!dict_compiler.Compile(schema_file_)) {
ResourceResolver resolver({"compiled_schema", "build/", ".schema.yaml"});
resolver.set_root_path(user_data_path);
auto compiled_schema = resolver.ResolvePath(schema_id).string();
if (!dict_compiler.Compile(compiled_schema)) {
LOG(ERROR) << "dictionary '" << dict_name << "' failed to compile.";
return false;
}
Expand All @@ -368,6 +366,38 @@ ConfigFileUpdate::ConfigFileUpdate(TaskInitializer arg) {
}
}

static bool ConfigNeedsUpdate(Config* config) {
auto build_info = (*config)["__build_info"];
if (!build_info.IsMap()) {
LOG(INFO) << "missing build info";
return true;
}
auto timestamps = build_info["timestamps"];
if (!timestamps.IsMap()) {
LOG(INFO) << "missing timestamps";
return true;
}
the<ResourceResolver> resolver(
Service::instance().CreateResourceResolver({
"config_source_file", "", ".yaml"
}));
for (auto entry : *timestamps.AsMap()) {
fs::path source_file_path = resolver->ResolvePath(entry.first);
if (!fs::exists(source_file_path)) {
LOG(INFO) << "source file not exists: " << source_file_path.string();
return true;
}
auto value = As<ConfigValue>(entry.second);
int recorded_time = 0;
if (!value || !value->GetInt(&recorded_time) ||
recorded_time != (int) fs::last_write_time(source_file_path)) {
LOG(INFO) << "timestamp mismatch: " << source_file_path.string();
return true;
}
}
return false;
}

bool ConfigFileUpdate::Run(Deployer* deployer) {
fs::path shared_data_path(deployer->shared_data_dir);
fs::path user_data_path(deployer->user_data_dir);
Expand All @@ -385,7 +415,14 @@ bool ConfigFileUpdate::Run(Deployer* deployer) {
trash)) {
LOG(INFO) << "patched copy of '" << file_name_ << "' is moved to trash.";
}
// TODO: compile the config file if needs update
// build the config file if needs update
the<Config> config(Config::Require("config")->Create(file_name_));
if (ConfigNeedsUpdate(config.get())) {
if (!MaybeCreateDirectory(user_data_path / "build")) {
return false;
}
config.reset(Config::Require("config_builder")->Create(file_name_));
}
return true;
}

Expand Down

0 comments on commit 0d79712

Please sign in to comment.