@reddoorla/maintenance 0.3.0 → 0.5.0
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/dist/cli/bin.js +143 -6
- package/dist/cli/bin.js.map +1 -1
- package/dist/configs/svelte.d.ts +39 -0
- package/dist/configs/svelte.js +30 -0
- package/dist/configs/svelte.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +143 -6
- package/dist/index.js.map +1 -1
- package/dist/recipes/sync-configs.d.ts +1 -1
- package/dist/recipes/sync-configs.js +143 -6
- package/dist/recipes/sync-configs.js.map +1 -1
- package/dist/{sync-configs-D_Dm-68_.d.ts → sync-configs-CW3nKS_N.d.ts} +1 -1
- package/dist/util/git.d.ts +3 -1
- package/dist/util/git.js +10 -0
- package/dist/util/git.js.map +1 -1
- package/package.json +5 -1
package/dist/cli/bin.js
CHANGED
|
@@ -881,11 +881,116 @@ var playwrightA11y = {
|
|
|
881
881
|
contents: `export { default } from "@reddoorla/maintenance/configs/playwright-a11y";
|
|
882
882
|
`
|
|
883
883
|
};
|
|
884
|
-
var
|
|
884
|
+
var svelte = {
|
|
885
|
+
config: "svelte",
|
|
886
|
+
path: "svelte.config.js",
|
|
887
|
+
contents: `import { createSvelteConfig } from "@reddoorla/maintenance/configs/svelte";
|
|
888
|
+
import adapter from "@sveltejs/adapter-auto";
|
|
889
|
+
|
|
890
|
+
/** @type {import('@sveltejs/kit').Config} */
|
|
891
|
+
export default createSvelteConfig({
|
|
892
|
+
kit: { adapter: adapter() },
|
|
893
|
+
});
|
|
894
|
+
`
|
|
895
|
+
};
|
|
896
|
+
var ALL_TEMPLATES = [
|
|
897
|
+
eslint,
|
|
898
|
+
prettier,
|
|
899
|
+
lighthouse,
|
|
900
|
+
playwrightA11y,
|
|
901
|
+
svelte
|
|
902
|
+
];
|
|
885
903
|
function templatesByName(which) {
|
|
886
904
|
return ALL_TEMPLATES.filter((t) => which.includes(t.config));
|
|
887
905
|
}
|
|
888
906
|
|
|
907
|
+
// src/recipes/sync-configs/gitignore.ts
|
|
908
|
+
var MANAGED_MARKER = "# canonical entries from @reddoorla/maintenance sync-configs";
|
|
909
|
+
var CANONICAL_GITIGNORE_ENTRIES = [
|
|
910
|
+
"node_modules/",
|
|
911
|
+
"build/",
|
|
912
|
+
"dist/",
|
|
913
|
+
".svelte-kit/",
|
|
914
|
+
"coverage/",
|
|
915
|
+
".vitest-cache/",
|
|
916
|
+
"playwright-report/",
|
|
917
|
+
"test-results/",
|
|
918
|
+
".lighthouseci/",
|
|
919
|
+
".tsbuildinfo",
|
|
920
|
+
".env",
|
|
921
|
+
".env.*",
|
|
922
|
+
"!.env.example",
|
|
923
|
+
".DS_Store",
|
|
924
|
+
"*.log",
|
|
925
|
+
".vercel/",
|
|
926
|
+
".netlify/"
|
|
927
|
+
];
|
|
928
|
+
function stripLeadingSlash(s) {
|
|
929
|
+
return s.startsWith("/") ? s.slice(1) : s;
|
|
930
|
+
}
|
|
931
|
+
function stripTrailingSlash(s) {
|
|
932
|
+
return s.endsWith("/") ? s.slice(0, -1) : s;
|
|
933
|
+
}
|
|
934
|
+
function normalizePresence(line) {
|
|
935
|
+
return stripTrailingSlash(stripLeadingSlash(line.trim()));
|
|
936
|
+
}
|
|
937
|
+
function presentSet(existing) {
|
|
938
|
+
const set = /* @__PURE__ */ new Set();
|
|
939
|
+
for (const raw of existing.split(/\r?\n/)) {
|
|
940
|
+
const trimmed = raw.trim();
|
|
941
|
+
if (!trimmed) continue;
|
|
942
|
+
if (trimmed.startsWith("#")) continue;
|
|
943
|
+
set.add(normalizePresence(trimmed));
|
|
944
|
+
}
|
|
945
|
+
return set;
|
|
946
|
+
}
|
|
947
|
+
function mergeGitignore(existing, canonical) {
|
|
948
|
+
if (existing === null) {
|
|
949
|
+
const body = [MANAGED_MARKER, ...canonical].join("\n") + "\n";
|
|
950
|
+
return { content: body, added: [...canonical] };
|
|
951
|
+
}
|
|
952
|
+
const present = presentSet(existing);
|
|
953
|
+
const added = [];
|
|
954
|
+
for (const entry of canonical) {
|
|
955
|
+
const norm = normalizePresence(entry);
|
|
956
|
+
if (!present.has(norm)) {
|
|
957
|
+
added.push(entry);
|
|
958
|
+
present.add(norm);
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
if (added.length === 0) {
|
|
962
|
+
return { content: existing, added: [] };
|
|
963
|
+
}
|
|
964
|
+
let base = existing;
|
|
965
|
+
if (!base.endsWith("\n")) base += "\n";
|
|
966
|
+
const block = ["", MANAGED_MARKER, ...added].join("\n") + "\n";
|
|
967
|
+
return { content: base + block, added };
|
|
968
|
+
}
|
|
969
|
+
function findTrackedArtifacts(tracked, canonical) {
|
|
970
|
+
const dirEntries = [];
|
|
971
|
+
for (const raw of canonical) {
|
|
972
|
+
const t = raw.trim();
|
|
973
|
+
if (!t) continue;
|
|
974
|
+
if (t.startsWith("!")) continue;
|
|
975
|
+
if (/[*?[]/.test(t)) continue;
|
|
976
|
+
const noLead = stripLeadingSlash(t);
|
|
977
|
+
if (!noLead.endsWith("/")) continue;
|
|
978
|
+
const name = stripTrailingSlash(noLead);
|
|
979
|
+
if (!name) continue;
|
|
980
|
+
dirEntries.push(name);
|
|
981
|
+
}
|
|
982
|
+
const matched = [];
|
|
983
|
+
for (const path of tracked) {
|
|
984
|
+
for (const dir of dirEntries) {
|
|
985
|
+
if (path === dir || path.startsWith(dir + "/")) {
|
|
986
|
+
matched.push(path);
|
|
987
|
+
break;
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
return matched;
|
|
992
|
+
}
|
|
993
|
+
|
|
889
994
|
// src/util/git.ts
|
|
890
995
|
import { execFile } from "child_process";
|
|
891
996
|
import { promisify } from "util";
|
|
@@ -908,6 +1013,14 @@ async function createBranch(cwd, name) {
|
|
|
908
1013
|
async function stageAll(cwd) {
|
|
909
1014
|
await git(cwd, ["add", "-A"]);
|
|
910
1015
|
}
|
|
1016
|
+
async function listTrackedFiles(cwd) {
|
|
1017
|
+
const { stdout } = await git(cwd, ["ls-files"]);
|
|
1018
|
+
return stdout.split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
|
|
1019
|
+
}
|
|
1020
|
+
async function removeFromIndex(cwd, paths) {
|
|
1021
|
+
if (paths.length === 0) return;
|
|
1022
|
+
await git(cwd, ["rm", "-r", "--cached", "--", ...paths]);
|
|
1023
|
+
}
|
|
911
1024
|
async function commit(cwd, message) {
|
|
912
1025
|
await stageAll(cwd);
|
|
913
1026
|
const { stdout: status } = await git(cwd, ["status", "--porcelain"]);
|
|
@@ -918,6 +1031,7 @@ async function commit(cwd, message) {
|
|
|
918
1031
|
}
|
|
919
1032
|
|
|
920
1033
|
// src/recipes/sync-configs.ts
|
|
1034
|
+
var GITIGNORE_CONFIG = "gitignore";
|
|
921
1035
|
function siteLabel6(site) {
|
|
922
1036
|
return site.name ?? site.path;
|
|
923
1037
|
}
|
|
@@ -928,7 +1042,7 @@ async function readMaybe(path) {
|
|
|
928
1042
|
return null;
|
|
929
1043
|
}
|
|
930
1044
|
}
|
|
931
|
-
async function
|
|
1045
|
+
async function planTemplateDiffs(cwd, templates) {
|
|
932
1046
|
const diffs = [];
|
|
933
1047
|
for (const t of templates) {
|
|
934
1048
|
const existing = await readMaybe(join6(cwd, t.path));
|
|
@@ -936,11 +1050,29 @@ async function planDiffs(cwd, templates) {
|
|
|
936
1050
|
}
|
|
937
1051
|
return diffs;
|
|
938
1052
|
}
|
|
1053
|
+
async function planGitignore(cwd) {
|
|
1054
|
+
const existing = await readMaybe(join6(cwd, ".gitignore"));
|
|
1055
|
+
const merge = mergeGitignore(existing, CANONICAL_GITIGNORE_ENTRIES);
|
|
1056
|
+
const tracked = await listTrackedFiles(cwd);
|
|
1057
|
+
const toUntrack = findTrackedArtifacts(tracked, CANONICAL_GITIGNORE_ENTRIES);
|
|
1058
|
+
if (merge.added.length === 0 && toUntrack.length === 0) return { kind: "noop" };
|
|
1059
|
+
return { kind: "apply", content: merge.content, toUntrack, added: merge.added };
|
|
1060
|
+
}
|
|
1061
|
+
async function applyGitignore(cwd, plan) {
|
|
1062
|
+
await writeFile3(join6(cwd, ".gitignore"), plan.content, "utf-8");
|
|
1063
|
+
if (plan.toUntrack.length > 0) {
|
|
1064
|
+
await removeFromIndex(cwd, plan.toUntrack);
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
939
1067
|
async function syncConfigs(site, opts = {}) {
|
|
940
1068
|
const label = siteLabel6(site);
|
|
941
|
-
const
|
|
942
|
-
const
|
|
943
|
-
|
|
1069
|
+
const requested = opts.which ?? ALL_TEMPLATES.map((t) => t.config).concat(GITIGNORE_CONFIG);
|
|
1070
|
+
const templateNames = requested.filter((c) => c !== GITIGNORE_CONFIG);
|
|
1071
|
+
const templates = templatesByName(templateNames);
|
|
1072
|
+
const includeGitignore = requested.includes(GITIGNORE_CONFIG);
|
|
1073
|
+
const templateDiffs = await planTemplateDiffs(site.path, templates);
|
|
1074
|
+
const gitignorePlan = includeGitignore ? await planGitignore(site.path) : { kind: "noop" };
|
|
1075
|
+
if (templateDiffs.length === 0 && gitignorePlan.kind === "noop") {
|
|
944
1076
|
return {
|
|
945
1077
|
recipe: "sync-configs",
|
|
946
1078
|
site: label,
|
|
@@ -955,7 +1087,7 @@ async function syncConfigs(site, opts = {}) {
|
|
|
955
1087
|
const branch = branchName("sync-configs");
|
|
956
1088
|
await createBranch(site.path, branch);
|
|
957
1089
|
const shas = [];
|
|
958
|
-
for (const t of
|
|
1090
|
+
for (const t of templateDiffs) {
|
|
959
1091
|
await writeFile3(join6(site.path, t.path), t.contents, "utf-8");
|
|
960
1092
|
const sha = await commit(
|
|
961
1093
|
site.path,
|
|
@@ -963,6 +1095,11 @@ async function syncConfigs(site, opts = {}) {
|
|
|
963
1095
|
);
|
|
964
1096
|
if (sha) shas.push(sha);
|
|
965
1097
|
}
|
|
1098
|
+
if (gitignorePlan.kind === "apply") {
|
|
1099
|
+
await applyGitignore(site.path, gitignorePlan);
|
|
1100
|
+
const sha = await commit(site.path, `chore: sync gitignore from @reddoorla/maintenance`);
|
|
1101
|
+
if (sha) shas.push(sha);
|
|
1102
|
+
}
|
|
966
1103
|
return {
|
|
967
1104
|
recipe: "sync-configs",
|
|
968
1105
|
site: label,
|