@@ -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+
371401bool 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