@shellus/way 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -209,6 +209,15 @@ projects:
209
209
  keep_monthly: 12
210
210
  ```
211
211
 
212
+ **schedule 语法**(node-cron 格式):
213
+
214
+ | 格式 | 说明 | 示例 |
215
+ |------|------|------|
216
+ | `"0 */2 * * *"` | 间隔表达式 | 每 2 小时 |
217
+ | `"0 9,15,21 * * *"` | 多个时间点(逗号) | 每天 9:00、15:00、21:00 |
218
+ | `"0 9-17 * * 1-5"` | 时间范围 | 工作日 9:00-17:00 每小时 |
219
+ | `"*/30 * * * *"` | 分钟间隔 | 每 30 分钟 |
220
+
212
221
  #### 排除规则通配符语法
213
222
 
214
223
  restic 使用 Go 的 filepath.Match 语法:
package/dist/cli.js CHANGED
@@ -16,7 +16,7 @@ function loadConfig(wayDir, remoteName) {
16
16
  const rulesFile = path.join(wayDir, "rules.yaml");
17
17
  const rules = yaml.load(fs.readFileSync(rulesFile, "utf8"));
18
18
  if ("schedule" in rules && "backup" in (rules.schedule || {})) {
19
- throw new Error("\u65E7\u914D\u7F6E\u683C\u5F0F\u4E0D\u518D\u652F\u6301\uFF0C\u8BF7\u53C2\u8003 rules.yaml.example \u66F4\u65B0\u914D\u7F6E");
19
+ throw new Error("\u68C0\u6D4B\u5230 v0.4.x \u65E7\u914D\u7F6E\u683C\u5F0F\uFF0C\u8BF7\u8FD0\u884C\u8FC1\u79FB\u811A\u672C\uFF1Anpx --yes @shellus/way@latest migrate-to-v0.5.sh \u6216\u624B\u52A8\u53C2\u8003 rules.yaml.example \u66F4\u65B0\u914D\u7F6E");
20
20
  }
21
21
  return { repository, rules };
22
22
  }
@@ -155,51 +155,53 @@ async function systemd(options) {
155
155
  const wayDir = process.env.WAY_DIR || `${process.env.HOME}/.way`;
156
156
  const config = loadConfig(wayDir, options.remote);
157
157
  const wayPath = execSync("which way", { encoding: "utf-8" }).trim();
158
+ const currentUser = execSync("whoami", { encoding: "utf-8" }).trim();
158
159
  const serviceContent = `[Unit]
159
160
  Description=Way Backup Daemon
160
161
  After=network.target
161
162
 
162
163
  [Service]
163
164
  Type=simple
165
+ User=${currentUser}
164
166
  ExecStart=${wayPath} daemon
165
167
  Restart=always
166
168
  RestartSec=10
167
169
  Environment="WAY_DIR=${wayDir}"
170
+ Environment="HOME=${process.env.HOME}"
168
171
 
169
172
  [Install]
170
- WantedBy=default.target
173
+ WantedBy=multi-user.target
171
174
  `;
172
175
  if (options.action === "show") {
173
176
  console.log("=== way-backup.service ===");
174
177
  console.log(serviceContent);
175
178
  return;
176
179
  }
177
- const systemdDir = `${process.env.HOME}/.config/systemd/user`;
180
+ const systemdDir = "/etc/systemd/system";
178
181
  const servicePath = path2.join(systemdDir, "way-backup.service");
179
182
  if (options.action === "install") {
180
- fs2.mkdirSync(systemdDir, { recursive: true });
181
183
  fs2.writeFileSync(servicePath, serviceContent);
182
- execSync("systemctl --user daemon-reload");
183
- execSync("systemctl --user enable way-backup.service");
184
- execSync("systemctl --user start way-backup.service");
184
+ execSync("systemctl daemon-reload");
185
+ execSync("systemctl enable way-backup.service");
186
+ execSync("systemctl start way-backup.service");
185
187
  console.log("Systemd service installed and started");
186
- execSync("systemctl --user --no-pager status way-backup.service", { stdio: "inherit" });
188
+ execSync("systemctl --no-pager status way-backup.service", { stdio: "inherit" });
187
189
  }
188
190
  if (options.action === "uninstall") {
189
191
  try {
190
- execSync("systemctl --user stop way-backup.service", { stdio: "ignore" });
192
+ execSync("systemctl stop way-backup.service", { stdio: "ignore" });
191
193
  } catch {
192
194
  }
193
195
  try {
194
- execSync("systemctl --user disable way-backup.service", { stdio: "ignore" });
196
+ execSync("systemctl disable way-backup.service", { stdio: "ignore" });
195
197
  } catch {
196
198
  }
197
199
  if (fs2.existsSync(servicePath)) fs2.unlinkSync(servicePath);
198
- execSync("systemctl --user daemon-reload");
200
+ execSync("systemctl daemon-reload");
199
201
  console.log("Systemd service uninstalled");
200
202
  }
201
203
  if (options.action === "status") {
202
- execSync("systemctl --user --no-pager status way-backup.service", { stdio: "inherit" });
204
+ execSync("systemctl --no-pager status way-backup.service", { stdio: "inherit" });
203
205
  }
204
206
  }
205
207
 
@@ -266,7 +268,7 @@ async function daemon(options) {
266
268
 
267
269
  // src/cli.ts
268
270
  var program = new Command();
269
- program.name("way").version("0.5.0").description("\u7B56\u7565\u5907\u4EFD\u5DE5\u5177 - \u57FA\u4E8E restic \u7684\u7B56\u7565\u5C01\u88C5").option("--remote <name>", "\u6307\u5B9A\u4ED3\u5E93", "default").addHelpText("after", `
271
+ program.name("way").version("0.5.1").description("\u7B56\u7565\u5907\u4EFD\u5DE5\u5177 - \u57FA\u4E8E restic \u7684\u7B56\u7565\u5C01\u88C5").option("--remote <name>", "\u6307\u5B9A\u4ED3\u5E93", "default").addHelpText("after", `
270
272
  \u793A\u4F8B:
271
273
  $ way run \u6267\u884C\u6240\u6709\u9879\u76EE\u5907\u4EFD
272
274
  $ way run data \u53EA\u5907\u4EFD data \u9879\u76EE
@@ -278,9 +280,11 @@ program.name("way").version("0.5.0").description("\u7B56\u7565\u5907\u4EFD\u5DE5
278
280
 
279
281
  \u6587\u6863: https://github.com/shellus/way
280
282
  `);
281
- program.command("run [projects...]").description("\u6267\u884C\u5907\u4EFD").allowUnknownOption().allowExcessArguments().action(async (projects, options, command) => {
282
- const remote = command.parent.opts().remote;
283
- await run({ remote, projects });
283
+ program.command("run [projects...]").description("\u6267\u884C\u5907\u4EFD").option("--dry-run", "\u6A21\u62DF\u5907\u4EFD\uFF08\u4E0D\u5B9E\u9645\u5199\u5165\uFF09").allowUnknownOption().allowExcessArguments().action(async function(projects) {
284
+ const remote = this.parent.opts().remote;
285
+ const extraArgs = this.args.filter((a) => a.startsWith("-") && !["--dry-run"].includes(a));
286
+ if (this.opts().dryRun) extraArgs.push("--dry-run");
287
+ await run({ remote, projects: projects.filter((p) => !p.startsWith("-")), extraArgs });
284
288
  });
285
289
  program.command("gc").description("\u6E05\u7406\u65E7\u5FEB\u7167").option("--dry-run", "\u6A21\u62DF\u6E05\u7406\uFF08\u4E0D\u5B9E\u9645\u5220\u9664\uFF09").action(async function(cmdOptions) {
286
290
  const remote = this.parent.opts().remote;
@@ -80,38 +80,38 @@ fi
80
80
  echo "✓ 配置迁移完成"
81
81
 
82
82
  # 检测并升级 systemd 服务
83
- TIMER_FILE="$HOME/.config/systemd/user/way-backup.timer"
84
- SERVICE_FILE="$HOME/.config/systemd/user/way-backup.service"
83
+ USER_TIMER="$HOME/.config/systemd/user/way-backup.timer"
84
+ USER_SERVICE="$HOME/.config/systemd/user/way-backup.service"
85
+ SYSTEM_SERVICE="/etc/systemd/system/way-backup.service"
85
86
 
86
- if systemctl --user is-active way-backup.timer &>/dev/null || [ -f "$TIMER_FILE" ]; then
87
+ # 清理旧版 user 级别服务
88
+ if systemctl --user is-active way-backup.timer &>/dev/null || [ -f "$USER_TIMER" ]; then
87
89
  echo ""
88
- echo "检测到旧版 systemd timer,正在升级为 daemon service..."
89
-
90
- # 停止并禁用旧 timer
90
+ echo "检测到旧版 user 级 systemd timer,正在清理..."
91
91
  systemctl --user stop way-backup.timer 2>/dev/null || true
92
92
  systemctl --user disable way-backup.timer 2>/dev/null || true
93
- rm -f "$TIMER_FILE"
94
-
95
- # 停止旧 service(如果在运行)
93
+ rm -f "$USER_TIMER"
96
94
  systemctl --user stop way-backup.service 2>/dev/null || true
95
+ systemctl --user disable way-backup.service 2>/dev/null || true
96
+ rm -f "$USER_SERVICE"
97
+ systemctl --user daemon-reload
98
+ fi
97
99
 
98
- # 重新安装新版 service
99
- way systemd install
100
-
101
- echo "✓ systemd 服务已从 timer 升级为 daemon"
102
- elif systemctl --user is-active way-backup.service &>/dev/null || [ -f "$SERVICE_FILE" ]; then
100
+ if systemctl --user is-active way-backup.service &>/dev/null || [ -f "$USER_SERVICE" ]; then
103
101
  echo ""
104
- echo "检测到 systemd service,正在重新安装..."
102
+ echo "检测到旧版 user 级 systemd service,正在清理..."
103
+ systemctl --user stop way-backup.service 2>/dev/null || true
104
+ systemctl --user disable way-backup.service 2>/dev/null || true
105
+ rm -f "$USER_SERVICE"
106
+ systemctl --user daemon-reload
107
+ fi
105
108
 
106
- # 重新安装以更新配置
107
- way systemd uninstall
108
- way systemd install
109
+ # 安装 system 级别服务
110
+ echo ""
111
+ echo "安装 system 级 systemd service..."
112
+ way systemd install
109
113
 
110
- echo "✓ systemd 服务已更新"
111
- else
112
- echo ""
113
- echo "未检测到 systemd 服务,如需安装: way systemd install"
114
- fi
114
+ echo "✓ systemd 服务已升级为 system 级别"
115
115
 
116
116
  echo ""
117
117
  echo "如需回滚配置: mv $BACKUP_FILE $RULES_FILE"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shellus/way",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "将备份作为持续运营的项目,而非一次性任务。基于 restic 的策略封装。",
5
5
  "type": "module",
6
6
  "bin": {
@@ -4,7 +4,12 @@
4
4
 
5
5
  # 全局默认配置
6
6
  defaults:
7
- schedule: "0 */2 * * *" # 默认每 2 小时
7
+ # schedule 使用 node-cron 语法(分 周)
8
+ # 支持多种表达方式:
9
+ # "0 */2 * * *" - 每 2 小时
10
+ # "0 9,15,21 * * *" - 每天 9:00、15:00、21:00
11
+ # "0 9-17 * * 1-5" - 工作日 9:00-17:00 每小时
12
+ schedule: "0 */2 * * *"
8
13
  retention:
9
14
  keep_daily: 7
10
15
  keep_weekly: 4