From eec000b430617212aefab99da5a468863ccc411f Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Wed, 30 Sep 2026 18:27:47 +0200 Subject: [PATCH] fix: a programmatic on/mute line joins the existing ones in the header Co-Authored-By: Claude Opus 5.5 (1M context) --- .../assets/AssetGraph/pipelineAnnotationEdits.test.ts | 7 +++++++ .../assets/AssetGraph/pipelineAnnotationEdits.ts | 11 +++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/frontend/src/lib/components/assets/AssetGraph/pipelineAnnotationEdits.test.ts b/frontend/src/lib/components/assets/AssetGraph/pipelineAnnotationEdits.test.ts index 6243bfb932..8759f114b4 100644 --- a/frontend/src/lib/components/assets/AssetGraph/pipelineAnnotationEdits.test.ts +++ b/frontend/src/lib/components/assets/AssetGraph/pipelineAnnotationEdits.test.ts @@ -17,6 +17,13 @@ describe('pipeline annotation edits', () => { ) }) + it('adds `on` next to the existing `on` lines', () => { + const sql = '-- pipeline\n-- on schedule\n-- materialize ducklake://main/x\nSELECT 1;' + expect(listenToAsset(sql, table, false)).toBe( + '-- pipeline\n-- on schedule\n-- on datatable://main/orders\n-- materialize ducklake://main/x\nSELECT 1;' + ) + }) + it('removes an `on` line however it is spelled, options included', () => { const py = '# pipeline\n# on datatable://main/orders debounce=60s\nprint(1)' expect(stopListeningToAsset(py, table, true)).toBe('# pipeline\nprint(1)') diff --git a/frontend/src/lib/components/assets/AssetGraph/pipelineAnnotationEdits.ts b/frontend/src/lib/components/assets/AssetGraph/pipelineAnnotationEdits.ts index ad856263c5..70ab899412 100644 --- a/frontend/src/lib/components/assets/AssetGraph/pipelineAnnotationEdits.ts +++ b/frontend/src/lib/components/assets/AssetGraph/pipelineAnnotationEdits.ts @@ -66,13 +66,16 @@ function hasDirective(content: string, match: LineMatch): boolean { return header(content.split('\n')).some((l) => matches(l, match)) } -/** Adds ` ` at the end of the header, in its comment style. */ +/** Adds ` ` in the header's comment style: after the last line + * of the same directive (`on`, `mute`), so they stay grouped, else at its end. */ function addDirective(content: string, directive: string): string { const lines = content.split('\n') const h = header(lines) - const last = h[h.length - 1] - const line = `${last?.prefix ?? '//'} ${directive}` - lines.splice(last ? last.index + 1 : 0, 0, line) + const keyword = directive.split(/\s/)[0] + const sameKind = h.filter((l) => l.inner.split(/\s/)[0] === keyword) + const after = sameKind[sameKind.length - 1] ?? h[h.length - 1] + const line = `${after?.prefix ?? '//'} ${directive}` + lines.splice(after ? after.index + 1 : 0, 0, line) return lines.join('\n') }