@reddoorla/maintenance 0.4.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 +124 -5
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +124 -5
- package/dist/index.js.map +1 -1
- package/dist/recipes/sync-configs.d.ts +1 -1
- package/dist/recipes/sync-configs.js +124 -5
- package/dist/recipes/sync-configs.js.map +1 -1
- package/dist/{sync-configs-C56tK7Go.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 +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as Site, a as AuditResult, A as AuditName, b as RecipeResult, R as RecipeName, I as InventoryProvider } from './sync-configs-
|
|
2
|
-
export { C as ConfigName, c as SyncConfigsOptions, s as syncConfigs } from './sync-configs-
|
|
1
|
+
import { S as Site, a as AuditResult, A as AuditName, b as RecipeResult, R as RecipeName, I as InventoryProvider } from './sync-configs-CW3nKS_N.js';
|
|
2
|
+
export { C as ConfigName, c as SyncConfigsOptions, s as syncConfigs } from './sync-configs-CW3nKS_N.js';
|
|
3
3
|
|
|
4
4
|
type SpawnResult = {
|
|
5
5
|
code: number;
|
package/dist/index.js
CHANGED
|
@@ -725,6 +725,93 @@ function templatesByName(which) {
|
|
|
725
725
|
return ALL_TEMPLATES.filter((t) => which.includes(t.config));
|
|
726
726
|
}
|
|
727
727
|
|
|
728
|
+
// src/recipes/sync-configs/gitignore.ts
|
|
729
|
+
var MANAGED_MARKER = "# canonical entries from @reddoorla/maintenance sync-configs";
|
|
730
|
+
var CANONICAL_GITIGNORE_ENTRIES = [
|
|
731
|
+
"node_modules/",
|
|
732
|
+
"build/",
|
|
733
|
+
"dist/",
|
|
734
|
+
".svelte-kit/",
|
|
735
|
+
"coverage/",
|
|
736
|
+
".vitest-cache/",
|
|
737
|
+
"playwright-report/",
|
|
738
|
+
"test-results/",
|
|
739
|
+
".lighthouseci/",
|
|
740
|
+
".tsbuildinfo",
|
|
741
|
+
".env",
|
|
742
|
+
".env.*",
|
|
743
|
+
"!.env.example",
|
|
744
|
+
".DS_Store",
|
|
745
|
+
"*.log",
|
|
746
|
+
".vercel/",
|
|
747
|
+
".netlify/"
|
|
748
|
+
];
|
|
749
|
+
function stripLeadingSlash(s) {
|
|
750
|
+
return s.startsWith("/") ? s.slice(1) : s;
|
|
751
|
+
}
|
|
752
|
+
function stripTrailingSlash(s) {
|
|
753
|
+
return s.endsWith("/") ? s.slice(0, -1) : s;
|
|
754
|
+
}
|
|
755
|
+
function normalizePresence(line) {
|
|
756
|
+
return stripTrailingSlash(stripLeadingSlash(line.trim()));
|
|
757
|
+
}
|
|
758
|
+
function presentSet(existing) {
|
|
759
|
+
const set = /* @__PURE__ */ new Set();
|
|
760
|
+
for (const raw of existing.split(/\r?\n/)) {
|
|
761
|
+
const trimmed = raw.trim();
|
|
762
|
+
if (!trimmed) continue;
|
|
763
|
+
if (trimmed.startsWith("#")) continue;
|
|
764
|
+
set.add(normalizePresence(trimmed));
|
|
765
|
+
}
|
|
766
|
+
return set;
|
|
767
|
+
}
|
|
768
|
+
function mergeGitignore(existing, canonical) {
|
|
769
|
+
if (existing === null) {
|
|
770
|
+
const body = [MANAGED_MARKER, ...canonical].join("\n") + "\n";
|
|
771
|
+
return { content: body, added: [...canonical] };
|
|
772
|
+
}
|
|
773
|
+
const present = presentSet(existing);
|
|
774
|
+
const added = [];
|
|
775
|
+
for (const entry of canonical) {
|
|
776
|
+
const norm = normalizePresence(entry);
|
|
777
|
+
if (!present.has(norm)) {
|
|
778
|
+
added.push(entry);
|
|
779
|
+
present.add(norm);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
if (added.length === 0) {
|
|
783
|
+
return { content: existing, added: [] };
|
|
784
|
+
}
|
|
785
|
+
let base = existing;
|
|
786
|
+
if (!base.endsWith("\n")) base += "\n";
|
|
787
|
+
const block = ["", MANAGED_MARKER, ...added].join("\n") + "\n";
|
|
788
|
+
return { content: base + block, added };
|
|
789
|
+
}
|
|
790
|
+
function findTrackedArtifacts(tracked, canonical) {
|
|
791
|
+
const dirEntries = [];
|
|
792
|
+
for (const raw of canonical) {
|
|
793
|
+
const t = raw.trim();
|
|
794
|
+
if (!t) continue;
|
|
795
|
+
if (t.startsWith("!")) continue;
|
|
796
|
+
if (/[*?[]/.test(t)) continue;
|
|
797
|
+
const noLead = stripLeadingSlash(t);
|
|
798
|
+
if (!noLead.endsWith("/")) continue;
|
|
799
|
+
const name = stripTrailingSlash(noLead);
|
|
800
|
+
if (!name) continue;
|
|
801
|
+
dirEntries.push(name);
|
|
802
|
+
}
|
|
803
|
+
const matched = [];
|
|
804
|
+
for (const path of tracked) {
|
|
805
|
+
for (const dir of dirEntries) {
|
|
806
|
+
if (path === dir || path.startsWith(dir + "/")) {
|
|
807
|
+
matched.push(path);
|
|
808
|
+
break;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
return matched;
|
|
813
|
+
}
|
|
814
|
+
|
|
728
815
|
// src/util/git.ts
|
|
729
816
|
import { execFile } from "child_process";
|
|
730
817
|
import { promisify } from "util";
|
|
@@ -747,6 +834,14 @@ async function createBranch(cwd, name) {
|
|
|
747
834
|
async function stageAll(cwd) {
|
|
748
835
|
await git(cwd, ["add", "-A"]);
|
|
749
836
|
}
|
|
837
|
+
async function listTrackedFiles(cwd) {
|
|
838
|
+
const { stdout } = await git(cwd, ["ls-files"]);
|
|
839
|
+
return stdout.split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
|
|
840
|
+
}
|
|
841
|
+
async function removeFromIndex(cwd, paths) {
|
|
842
|
+
if (paths.length === 0) return;
|
|
843
|
+
await git(cwd, ["rm", "-r", "--cached", "--", ...paths]);
|
|
844
|
+
}
|
|
750
845
|
async function commit(cwd, message) {
|
|
751
846
|
await stageAll(cwd);
|
|
752
847
|
const { stdout: status } = await git(cwd, ["status", "--porcelain"]);
|
|
@@ -757,6 +852,7 @@ async function commit(cwd, message) {
|
|
|
757
852
|
}
|
|
758
853
|
|
|
759
854
|
// src/recipes/sync-configs.ts
|
|
855
|
+
var GITIGNORE_CONFIG = "gitignore";
|
|
760
856
|
function siteLabel6(site) {
|
|
761
857
|
return site.name ?? site.path;
|
|
762
858
|
}
|
|
@@ -767,7 +863,7 @@ async function readMaybe(path) {
|
|
|
767
863
|
return null;
|
|
768
864
|
}
|
|
769
865
|
}
|
|
770
|
-
async function
|
|
866
|
+
async function planTemplateDiffs(cwd, templates) {
|
|
771
867
|
const diffs = [];
|
|
772
868
|
for (const t of templates) {
|
|
773
869
|
const existing = await readMaybe(join5(cwd, t.path));
|
|
@@ -775,11 +871,29 @@ async function planDiffs(cwd, templates) {
|
|
|
775
871
|
}
|
|
776
872
|
return diffs;
|
|
777
873
|
}
|
|
874
|
+
async function planGitignore(cwd) {
|
|
875
|
+
const existing = await readMaybe(join5(cwd, ".gitignore"));
|
|
876
|
+
const merge = mergeGitignore(existing, CANONICAL_GITIGNORE_ENTRIES);
|
|
877
|
+
const tracked = await listTrackedFiles(cwd);
|
|
878
|
+
const toUntrack = findTrackedArtifacts(tracked, CANONICAL_GITIGNORE_ENTRIES);
|
|
879
|
+
if (merge.added.length === 0 && toUntrack.length === 0) return { kind: "noop" };
|
|
880
|
+
return { kind: "apply", content: merge.content, toUntrack, added: merge.added };
|
|
881
|
+
}
|
|
882
|
+
async function applyGitignore(cwd, plan) {
|
|
883
|
+
await writeFile3(join5(cwd, ".gitignore"), plan.content, "utf-8");
|
|
884
|
+
if (plan.toUntrack.length > 0) {
|
|
885
|
+
await removeFromIndex(cwd, plan.toUntrack);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
778
888
|
async function syncConfigs(site, opts = {}) {
|
|
779
889
|
const label = siteLabel6(site);
|
|
780
|
-
const
|
|
781
|
-
const
|
|
782
|
-
|
|
890
|
+
const requested = opts.which ?? ALL_TEMPLATES.map((t) => t.config).concat(GITIGNORE_CONFIG);
|
|
891
|
+
const templateNames = requested.filter((c) => c !== GITIGNORE_CONFIG);
|
|
892
|
+
const templates = templatesByName(templateNames);
|
|
893
|
+
const includeGitignore = requested.includes(GITIGNORE_CONFIG);
|
|
894
|
+
const templateDiffs = await planTemplateDiffs(site.path, templates);
|
|
895
|
+
const gitignorePlan = includeGitignore ? await planGitignore(site.path) : { kind: "noop" };
|
|
896
|
+
if (templateDiffs.length === 0 && gitignorePlan.kind === "noop") {
|
|
783
897
|
return {
|
|
784
898
|
recipe: "sync-configs",
|
|
785
899
|
site: label,
|
|
@@ -794,7 +908,7 @@ async function syncConfigs(site, opts = {}) {
|
|
|
794
908
|
const branch = branchName("sync-configs");
|
|
795
909
|
await createBranch(site.path, branch);
|
|
796
910
|
const shas = [];
|
|
797
|
-
for (const t of
|
|
911
|
+
for (const t of templateDiffs) {
|
|
798
912
|
await writeFile3(join5(site.path, t.path), t.contents, "utf-8");
|
|
799
913
|
const sha = await commit(
|
|
800
914
|
site.path,
|
|
@@ -802,6 +916,11 @@ async function syncConfigs(site, opts = {}) {
|
|
|
802
916
|
);
|
|
803
917
|
if (sha) shas.push(sha);
|
|
804
918
|
}
|
|
919
|
+
if (gitignorePlan.kind === "apply") {
|
|
920
|
+
await applyGitignore(site.path, gitignorePlan);
|
|
921
|
+
const sha = await commit(site.path, `chore: sync gitignore from @reddoorla/maintenance`);
|
|
922
|
+
if (sha) shas.push(sha);
|
|
923
|
+
}
|
|
805
924
|
return {
|
|
806
925
|
recipe: "sync-configs",
|
|
807
926
|
site: label,
|