MCPcopy Create free account
hub / github.com/codename-co/stack / syncEntry

Function syncEntry

packages/scripts/maintenance/sync-metadata.ts:123–250  ·  view source on GitHub ↗
(entry: StackEntry)

Source from the content-addressed store, hash-verified

121 url.trim().replace(/\/+$/, "").replace(/^http:\/\//, "https://").toLowerCase();
122
123async function syncEntry(entry: StackEntry): Promise<Result> {
124 const { data } = entry;
125 const changes: Change[] = [];
126 const notes: string[] = [];
127 const opts = { noCache: NO_CACHE };
128
129 const ref = parseRepository(data.repository);
130 let meta: RepoMeta | null = null;
131
132 if (ref) {
133 try {
134 meta = await fetchRepoMeta(ref, opts);
135 if (!meta) notes.push(`repository not found upstream: ${data.repository}`);
136 } catch (e) {
137 notes.push(`repository lookup failed: ${(e as Error).message}`);
138 }
139 } else if (data.repository) {
140 notes.push(`unsupported repository host, skipped: ${data.repository}`);
141 }
142
143 const suggestions: Change[] = [];
144
145 /**
146 * Route a divergence: applied outright, or held for review when the API is
147 * describing the repository rather than the software.
148 */
149 const propose = (field: string, from: unknown, to: string | number) => {
150 const change = { field, from, to };
151 if (AUTO_APPLIED.has(field) || from == null || from === "") {
152 changes.push(change);
153 return;
154 }
155 if (ACCEPTED.has(`${entry.slug}:${field}`)) {
156 changes.push(change);
157 return;
158 }
159 if (isRejected(OVERRIDES, entry.slug, field, String(to))) return;
160 suggestions.push(change);
161 };
162
163 if (meta) {
164 // repository — upstream resolves renames/transfers, so a differing
165 // html_url means the project moved and our link is stale.
166 if (canonical(meta.url) !== canonical(data.repository ?? "")) {
167 propose("repository", data.repository, meta.url);
168 }
169
170 // stars
171 const stars = roundStars(meta.stars);
172 if (stars !== data.stars) propose("stars", data.stars ?? null, stars);
173
174 // homepage — only when upstream declares one. An empty upstream field is
175 // an absence of information, never a reason to drop a curated URL. A
176 // homepage that merely repeats the repository is not information either:
177 // `repository` already says that, and it would push a real product page
178 // out of the catalogue.
179 if (
180 meta.homepage &&

Callers 1

mainFunction · 0.85

Calls 14

parseRepositoryFunction · 0.90
fetchRepoMetaFunction · 0.90
isRollingTagFunction · 0.90
fetchReleasesFunction · 0.90
fetchReleaseDateFunction · 0.90
parseImagePinsFunction · 0.90
primaryImageFunction · 0.90
parseImageFunction · 0.90
fetchDockerTagDateFunction · 0.90
setFieldFunction · 0.90
writeStackFunction · 0.90
canonicalFunction · 0.85

Tested by

no test coverage detected