Skip to content

Commit 285fbcc

Browse files
committed
feat(detect_modifications): quick test based on last write time of files
1 parent 97cd661 commit 285fbcc

File tree

4 files changed

+71
-3
lines changed

4 files changed

+71
-3
lines changed

src/rime/lever/deployment_tasks.cc

+54
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//
55
// 2011-12-10 GONG Chen <[email protected]>
66
//
7+
#include <algorithm>
78
#include <boost/algorithm/string.hpp>
89
#include <boost/filesystem.hpp>
910
#include <boost/uuid/random_generator.hpp>
@@ -30,6 +31,51 @@ namespace fs = boost::filesystem;
3031

3132
namespace rime {
3233

34+
DetectModifications::DetectModifications(TaskInitializer arg) {
35+
try {
36+
data_dirs_ = boost::any_cast<vector<string>>(arg);
37+
}
38+
catch (const boost::bad_any_cast&) {
39+
LOG(ERROR) << "DetectModifications: invalid arguments.";
40+
}
41+
}
42+
43+
bool DetectModifications::Run(Deployer* deployer) {
44+
time_t last_modified = 0;
45+
try {
46+
for (auto dir : data_dirs_) {
47+
fs::path p = fs::canonical(dir);
48+
last_modified = (std::max)(last_modified, fs::last_write_time(p));
49+
if (fs::is_directory(p)) {
50+
for (fs::directory_iterator iter(p), end; iter != end; ++iter) {
51+
fs::path entry(iter->path());
52+
if (fs::is_regular_file(fs::canonical(entry)) &&
53+
entry.extension().string() == ".yaml" &&
54+
entry.filename().string() != "user.yaml") {
55+
last_modified =
56+
(std::max)(last_modified, fs::last_write_time(entry));
57+
}
58+
}
59+
}
60+
}
61+
} catch(const fs::filesystem_error& ex) {
62+
LOG(ERROR) << "Error reading file information: " << ex.what();
63+
return true;
64+
}
65+
66+
// TODO: store as 64-bit number to avoid the year 2038 problem
67+
int last_build_time = 0;
68+
{
69+
the<Config> user_config(Config::Require("config")->Create("user"));
70+
user_config->GetInt("var/last_build_time", &last_build_time);
71+
}
72+
if (last_modified > (time_t)last_build_time) {
73+
LOG(INFO) << "modifications detected. workspace needs update.";
74+
return true;
75+
}
76+
return false;
77+
}
78+
3379
bool InstallationUpdate::Run(Deployer* deployer) {
3480
LOG(INFO) << "updating rime installation info.";
3581
fs::path shared_data_path(deployer->shared_data_dir);
@@ -188,6 +234,11 @@ bool WorkspaceUpdate::Run(Deployer* deployer) {
188234
}
189235
LOG(INFO) << "finished updating schemas: "
190236
<< success << " success, " << failure << " failure.";
237+
238+
the<Config> user_config(Config::Require("config")->Create("user"));
239+
// TODO: store as 64-bit number to avoid the year 2038 problem
240+
user_config->SetInt("var/last_build_time", (int)time(NULL));
241+
191242
return failure == 0;
192243
}
193244

@@ -263,6 +314,7 @@ bool SchemaUpdate::Run(Deployer* deployer) {
263314
LOG(INFO) << "patched copy of schema '" << schema_id
264315
<< "' is moved to trash";
265316
}
317+
// TODO: compile the config file if needs update
266318

267319
string dict_name;
268320
if (!config->GetString("translator/dictionary", &dict_name)) {
@@ -281,6 +333,7 @@ bool SchemaUpdate::Run(Deployer* deployer) {
281333
if (verbose_) {
282334
dict_compiler.set_options(DictCompiler::kRebuild | DictCompiler::kDump);
283335
}
336+
// TODO: use compiled schema instead of the YAML file alone
284337
if (!dict_compiler.Compile(schema_file_)) {
285338
LOG(ERROR) << "dictionary '" << dict_name << "' failed to compile.";
286339
return false;
@@ -317,6 +370,7 @@ bool ConfigFileUpdate::Run(Deployer* deployer) {
317370
trash)) {
318371
LOG(INFO) << "patched copy of '" << file_name_ << "' is moved to trash.";
319372
}
373+
// TODO: compile the config file if needs update
320374
return true;
321375
}
322376

src/rime/lever/deployment_tasks.h

+13-1
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,23 @@
77
#ifndef RIME_DEPLOYMENT_TASKS_H_
88
#define RIME_DEPLOYMENT_TASKS_H_
99

10+
#include <rime/common.h>
1011
#include <rime/deployer.h>
1112

1213
namespace rime {
1314

14-
// initialize/update installation.yaml, default.yaml
15+
// detects changes in either user configuration or upgraded shared data
16+
class DetectModifications : public DeploymentTask {
17+
public:
18+
DetectModifications(TaskInitializer arg = TaskInitializer());
19+
// Unlike other tasks, its return value indicates whether modifications
20+
// has been detected and workspace needs update.
21+
bool Run(Deployer* deployer);
22+
protected:
23+
vector<string> data_dirs_;
24+
};
25+
26+
// initialize/update installation.yaml
1527
class InstallationUpdate : public DeploymentTask {
1628
public:
1729
InstallationUpdate(TaskInitializer arg = TaskInitializer()) {}

src/rime/lever/levers_module.cc

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ static void rime_levers_initialize() {
2424
Registry& r = Registry::instance();
2525

2626
// deployment tools
27+
r.Register("detect_modifications", new Component<DetectModifications>);
2728
r.Register("installation_update", new Component<InstallationUpdate>);
2829
r.Register("workspace_update", new Component<WorkspaceUpdate>);
2930
r.Register("schema_update", new Component<SchemaUpdate>);

src/rime_api.cc

+3-2
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,9 @@ RIME_API Bool RimeStartMaintenance(Bool full_check) {
105105
}
106106
if (!full_check) {
107107
TaskInitializer args{
108-
make_pair<string, string>("default.yaml", "config_version")};
109-
if (!deployer.RunTask("config_file_update", args)) {
108+
vector<string>{deployer.user_data_dir, deployer.shared_data_dir}
109+
};
110+
if (!deployer.RunTask("detect_modifications", args)) {
110111
return False;
111112
}
112113
LOG(INFO) << "changes detected; starting maintenance.";

0 commit comments

Comments
 (0)