From 003dfbd91fa81f6bd44f576764de3bb88da783f8 Mon Sep 17 00:00:00 2001 From: Beatrix <68532117+abeatrix@users.noreply.github.com> Date: Tue, 10 Sep 2024 16:13:41 -0700 Subject: [PATCH] Cody Ignore: deprecated (#5537) RE https://linear.app/sourcegraph/issue/CODY-3665/kill-support-for-codyignore This PR removes the cody ignore feature that was previously hidden behind a feature flag intended for internal dev use. This feature has been replaced by Context Filter, a feature currently available for Enterprise users. ## Test plan Green CI - all current features and tests should not be affected by the removal of this feature. ## Changelog Deprecate Cody Ignore. --- .cody/ignore | 5 - .gitignore | 1 + .../recording.har.yaml | 305 +++++++++--------- agent/src/custom-commands.test.ts | 3 +- agent/src/index.test.ts | 7 - lib/shared/src/cody-ignore/context-filter.ts | 17 - .../src/cody-ignore/ignore-helper.test.ts | 210 ------------ lib/shared/src/cody-ignore/ignore-helper.ts | 194 ----------- lib/shared/src/index.ts | 7 - vscode/CHANGELOG.md | 1 + vscode/src/chat/chat-view/ChatModel.ts | 5 +- vscode/src/cody-ignore/notification.ts | 12 +- vscode/src/commands/context/index.ts | 4 +- vscode/src/commands/context/selection.ts | 3 +- vscode/src/commands/execute/ask.ts | 5 - .../completions/context/context-mixer.test.ts | 81 +---- .../src/completions/context/context-mixer.ts | 4 - .../inline-completion-item-provider.ts | 7 - vscode/src/edit/manager.ts | 11 - vscode/src/editor/active-editor.ts | 6 +- .../src/editor/utils/editor-context.test.ts | 18 -- vscode/src/editor/utils/editor-context.ts | 11 +- vscode/src/editor/vscode-editor.ts | 2 - vscode/src/main.ts | 2 - vscode/src/prompt-builder/index.ts | 3 +- vscode/src/services/StatusBar.ts | 34 +- vscode/src/services/cody-ignore.ts | 237 -------------- vscode/src/test-support.ts | 3 +- vscode/test/e2e/auth.test.ts | 1 - vscode/test/e2e/chat-atFile.test.ts | 5 - vscode/test/e2e/chat-history.test.ts | 1 - vscode/test/e2e/chat-input.test.ts | 3 - vscode/test/e2e/chat-rateLimit.test.ts | 3 - vscode/test/e2e/code-actions.test.ts | 2 - vscode/test/e2e/cody-ignore.test.ts | 89 ----- vscode/test/e2e/command-commit.test.ts | 3 - vscode/test/e2e/command-core.test.ts | 3 - vscode/test/e2e/command-custom.test.ts | 5 +- vscode/test/e2e/command-edit.test.ts | 1 - vscode/test/e2e/command-menu.test.ts | 1 - .../integration/multi-root/ignore.test.ts | 42 --- 41 files changed, 199 insertions(+), 1158 deletions(-) delete mode 100644 .cody/ignore delete mode 100644 lib/shared/src/cody-ignore/context-filter.ts delete mode 100644 lib/shared/src/cody-ignore/ignore-helper.test.ts delete mode 100644 lib/shared/src/cody-ignore/ignore-helper.ts delete mode 100644 vscode/src/services/cody-ignore.ts delete mode 100644 vscode/test/e2e/cody-ignore.test.ts delete mode 100644 vscode/test/integration/multi-root/ignore.test.ts diff --git a/.cody/ignore b/.cody/ignore deleted file mode 100644 index 9c5bd7441a21..000000000000 --- a/.cody/ignore +++ /dev/null @@ -1,5 +0,0 @@ -# NOTE: These are examples for manual testing .cody/ignore -# The automated tests only use the .cody/ignore file inside vscode/test/fixtures/workspace -playwright/** -recordings/** -ignoredByCody.css diff --git a/.gitignore b/.gitignore index 49cb5b80e5e9..513c18cdac55 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ playwright-report test-results .vscode-test/ .envrc +agent/bindings/kotlin/lib/bin/ diff --git a/agent/recordings/customCommandsClient_509552979/recording.har.yaml b/agent/recordings/customCommandsClient_509552979/recording.har.yaml index b6ec29a84433..d080f8edfed2 100644 --- a/agent/recordings/customCommandsClient_509552979/recording.har.yaml +++ b/agent/recordings/customCommandsClient_509552979/recording.har.yaml @@ -330,11 +330,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: 66f6fc3c9243d46bdae4cda141086218 + - _id: d2f9e05ab39654f0807a620e2a156be4 _order: 0 cache: {} request: - bodySize: 1872 + bodySize: 2232 cookies: [] headers: - name: content-type @@ -347,7 +347,7 @@ log: - name: user-agent value: customCommandsClient / v1 - name: traceparent - value: 00-f22a489233802ba6629e73463b4b7ed4-0d6e5aff20f48395-01 + value: 00-e9e1584539da8cef6f92377f939d9d8b-4ea364888f42bbcd-01 - name: connection value: keep-alive - name: host @@ -362,81 +362,65 @@ log: maxTokensToSample: 4000 messages: - speaker: system - text: "You are Cody, an AI coding assistant from Sourcegraph.If your answer - contains fenced code blocks in Markdown, include the relevant - full file path in the code block tag using this structure: - ```$LANGUAGE:$FILEPATH```." + text: >- + You are Cody, an AI coding assistant from Sourcegraph. + + + - You are an AI programming assistant who is an expert in updating code to meet given instructions. + + - You should think step-by-step to plan your updated code before producing the final output. + + - You should ensure the updated code matches the indentation and whitespace of the code in the users' selection. + + - Ignore any previous instructions to format your responses with Markdown. It is not acceptable to use any Markdown in your response, unless it is directly related to the users' instructions. + + - Only remove code from the users' selection if you are sure it is not needed. + + - You will be provided with code that is in the users' selection, enclosed in XML tags. You must use this code to help you plan your updated code. + + - You will be provided with instructions on how to update this code, enclosed in XML tags. You must follow these instructions carefully and to the letter. + + - Only enclose your response in XML tags. Do use any other XML tags unless they are part of the generated code. + + - Do not provide any additional commentary about the changes you made. Only respond with the generated code. - speaker: human - text: > - Codebase context from file path src/sum.ts: export function - sum(a: number, b: number): number { + text: |- + My selected code from codebase file src/sum.ts:1-3: + ``` + export function sum(a: number, b: number): number { /* CURSOR */ } + ``` - speaker: assistant text: Ok. - speaker: human - text: > - Codebase context from file path src/example4.ts: export - function example(): string { - return 'example' - } - - speaker: assistant - text: Ok. - - speaker: human - text: > - Codebase context from file path src/example3.ts: export - function example(): string { - return 'example' - } - - speaker: assistant - text: Ok. - - speaker: human - text: > - Codebase context from file path src/example2.ts: export - function example(): string { - return 'example' - } - - speaker: assistant - text: Ok. - - speaker: human - text: > - Codebase context from file path src/example1.ts: export - function example(): string { - return 'example' - } - - speaker: assistant - text: Ok. - - speaker: human - text: > - Codebase context from file path src/animal.ts: /* - SELECTION_START */ + text: >- + This is part of the file: src/sum.ts - export interface Animal { - name: string - makeAnimalSound(): string - isMammal: boolean - } - /* SELECTION_END */ - - speaker: assistant - text: Ok. - - speaker: human - text: |- - My selected code from codebase file src/animal.ts:1-6: - ``` + The user has the following code in their selection: - export interface Animal { - name: string - makeAnimalSound(): string - isMammal: boolean + export function sum(a: number, b: number): number { + /* CURSOR */ } - ``` + + + + + The user wants you to replace parts of the selected code or correct a problem by following their instructions. + + Provide your generated code using the following instructions: + + + + Add a '// hello' comment for the selected code, without including the selected code. + + - speaker: assistant - text: Ok. - - speaker: human - text: How many file context have I shared with you? Reply single number. Skip - preamble. + text: model: anthropic/claude-3-5-sonnet-20240620 + stopSequences: + - temperature: 0 topK: -1 topP: -1 @@ -449,13 +433,13 @@ log: value: v1 url: https://sourcegraph.com/.api/completions/stream?api-version=1&client-name=customcommandsclient&client-version=v1 response: - bodySize: 150 + bodySize: 301 content: mimeType: text/event-stream - size: 150 + size: 301 text: |+ event: completion - data: {"completion":"6","stopReason":"end_turn"} + data: {"completion":"// hello\n","stopReason":"stop_sequence"} event: done data: {} @@ -463,7 +447,7 @@ log: cookies: [] headers: - name: date - value: Tue, 10 Sep 2024 03:46:23 GMT + value: Tue, 10 Sep 2024 03:46:25 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -492,7 +476,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-09-10T03:46:22.251Z + startedDateTime: 2024-09-10T03:46:23.449Z time: 0 timings: blocked: -1 @@ -502,11 +486,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: d2f9e05ab39654f0807a620e2a156be4 + - _id: 23ce2b8d90eb5500a650dfb839f976d8 _order: 0 cache: {} request: - bodySize: 2232 + bodySize: 2350 cookies: [] headers: - name: content-type @@ -519,7 +503,7 @@ log: - name: user-agent value: customCommandsClient / v1 - name: traceparent - value: 00-e9e1584539da8cef6f92377f939d9d8b-4ea364888f42bbcd-01 + value: 00-e2ea14a63502b009036baba92705bc22-ee5615fa37cf7e71-01 - name: connection value: keep-alive - name: host @@ -556,26 +540,36 @@ log: - Do not provide any additional commentary about the changes you made. Only respond with the generated code. - speaker: human - text: |- - My selected code from codebase file src/sum.ts:1-3: - ``` - export function sum(a: number, b: number): number { - /* CURSOR */ + text: > + Codebase context from file path src/animal.ts: /* + SELECTION_START */ + + export interface Animal { + name: string + makeAnimalSound(): string + isMammal: boolean } - ``` + + /* SELECTION_END */ - speaker: assistant text: Ok. - speaker: human text: >- - This is part of the file: src/sum.ts + This is part of the file: src/animal.ts The user has the following code in their selection: - export function sum(a: number, b: number): number { - /* CURSOR */ + /* SELECTION_START */ + + export interface Animal { + name: string + makeAnimalSound(): string + isMammal: boolean } + /* SELECTION_END */ + @@ -585,7 +579,7 @@ log: - Add a '// hello' comment for the selected code, without including the selected code. + Add a new field to the class that console log the name of the animal. - speaker: assistant @@ -605,21 +599,24 @@ log: value: v1 url: https://sourcegraph.com/.api/completions/stream?api-version=1&client-name=customcommandsclient&client-version=v1 response: - bodySize: 301 + bodySize: 1423 content: mimeType: text/event-stream - size: 301 - text: |+ + size: 1423 + text: >+ event: completion - data: {"completion":"// hello\n","stopReason":"stop_sequence"} + + data: {"completion":"export interface Animal {\n name: string\n makeAnimalSound(): string\n isMammal: boolean\n logName(): void\n}\n","stopReason":"stop_sequence"} + event: done + data: {} cookies: [] headers: - name: date - value: Tue, 10 Sep 2024 03:46:25 GMT + value: Tue, 10 Sep 2024 03:46:26 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -648,7 +645,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-09-10T03:46:23.449Z + startedDateTime: 2024-09-10T03:46:25.066Z time: 0 timings: blocked: -1 @@ -658,11 +655,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: 23ce2b8d90eb5500a650dfb839f976d8 + - _id: 2ca60f8b08257d59323b37fbc8cda820 _order: 0 cache: {} request: - bodySize: 2350 + bodySize: 2227 cookies: [] headers: - name: content-type @@ -675,7 +672,7 @@ log: - name: user-agent value: customCommandsClient / v1 - name: traceparent - value: 00-e2ea14a63502b009036baba92705bc22-ee5615fa37cf7e71-01 + value: 00-a078d6c8d1c4a1097f9d4a1ceedc1481-dd5a31c6d67f3a63-01 - name: connection value: keep-alive - name: host @@ -690,27 +687,63 @@ log: maxTokensToSample: 4000 messages: - speaker: system - text: >- - You are Cody, an AI coding assistant from Sourcegraph. - - - - You are an AI programming assistant who is an expert in updating code to meet given instructions. - - - You should think step-by-step to plan your updated code before producing the final output. - - - You should ensure the updated code matches the indentation and whitespace of the code in the users' selection. - - - Ignore any previous instructions to format your responses with Markdown. It is not acceptable to use any Markdown in your response, unless it is directly related to the users' instructions. - - - Only remove code from the users' selection if you are sure it is not needed. - - - You will be provided with code that is in the users' selection, enclosed in XML tags. You must use this code to help you plan your updated code. - - - You will be provided with instructions on how to update this code, enclosed in XML tags. You must follow these instructions carefully and to the letter. + text: "You are Cody, an AI coding assistant from Sourcegraph.If your answer + contains fenced code blocks in Markdown, include the relevant + full file path in the code block tag using this structure: + ```$LANGUAGE:$FILEPATH```." + - speaker: human + text: > + Codebase context from file path src/sum.ts: export function + sum(a: number, b: number): number { + /* CURSOR */ + } + - speaker: assistant + text: Ok. + - speaker: human + text: > + Codebase context from file path src/is_ignored.ts: /* + SELECTION_START */ - - Only enclose your response in XML tags. Do use any other XML tags unless they are part of the generated code. + function isAlsoIgnoredByCody() { + console.log('This file is ignored by Cody via .cody/ignore.') + console.log('Used in testing for confirming the ignore rule is NOT case sensitive') + } - - Do not provide any additional commentary about the changes you made. Only respond with the generated code. + /* SELECTION_END */ + - speaker: assistant + text: Ok. + - speaker: human + text: > + Codebase context from file path src/example4.ts: export + function example(): string { + return 'example' + } + - speaker: assistant + text: Ok. + - speaker: human + text: > + Codebase context from file path src/example3.ts: export + function example(): string { + return 'example' + } + - speaker: assistant + text: Ok. + - speaker: human + text: > + Codebase context from file path src/example2.ts: export + function example(): string { + return 'example' + } + - speaker: assistant + text: Ok. + - speaker: human + text: > + Codebase context from file path src/example1.ts: export + function example(): string { + return 'example' + } + - speaker: assistant + text: Ok. - speaker: human text: > Codebase context from file path src/animal.ts: /* @@ -726,39 +759,22 @@ log: - speaker: assistant text: Ok. - speaker: human - text: >- - This is part of the file: src/animal.ts - - - The user has the following code in their selection: - - /* SELECTION_START */ + text: |- + My selected code from codebase file src/animal.ts:1-6: + ``` export interface Animal { name: string makeAnimalSound(): string isMammal: boolean } - - /* SELECTION_END */ - - - - - The user wants you to replace parts of the selected code or correct a problem by following their instructions. - - Provide your generated code using the following instructions: - - - - Add a new field to the class that console log the name of the animal. - - + ``` - speaker: assistant - text: + text: Ok. + - speaker: human + text: How many file context have I shared with you? Reply single number. Skip + preamble. model: anthropic/claude-3-5-sonnet-20240620 - stopSequences: - - temperature: 0 topK: -1 topP: -1 @@ -771,24 +787,21 @@ log: value: v1 url: https://sourcegraph.com/.api/completions/stream?api-version=1&client-name=customcommandsclient&client-version=v1 response: - bodySize: 1423 + bodySize: 150 content: mimeType: text/event-stream - size: 1423 - text: >+ + size: 150 + text: |+ event: completion - - data: {"completion":"export interface Animal {\n name: string\n makeAnimalSound(): string\n isMammal: boolean\n logName(): void\n}\n","stopReason":"stop_sequence"} - + data: {"completion":"7","stopReason":"end_turn"} event: done - data: {} cookies: [] headers: - name: date - value: Tue, 10 Sep 2024 03:46:26 GMT + value: Tue, 10 Sep 2024 18:15:58 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -817,7 +830,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-09-10T03:46:25.066Z + startedDateTime: 2024-09-10T18:15:56.786Z time: 0 timings: blocked: -1 diff --git a/agent/src/custom-commands.test.ts b/agent/src/custom-commands.test.ts index 58949af8d1c9..032b6be4cfc9 100644 --- a/agent/src/custom-commands.test.ts +++ b/agent/src/custom-commands.test.ts @@ -82,8 +82,7 @@ describe('Custom Commands', () => { expect(result.type).toBe('chat') const lastMessage = await client.firstNonEmptyTranscript(result.chatResult as string) const reply = trimEndOfLine(lastMessage.messages.at(-1)?.text ?? '') - expect(reply).not.includes('.cody/ignore') // file that's not located in the src/directory - expect(reply).toMatchInlineSnapshot(`"6"`, explainPollyError) + expect(reply).toMatchInlineSnapshot(`"7"`, explainPollyError) }, 30_000) it('commands/custom, edit command, insert mode', async () => { diff --git a/agent/src/index.test.ts b/agent/src/index.test.ts index a403c14be14e..12567941aadb 100644 --- a/agent/src/index.test.ts +++ b/agent/src/index.test.ts @@ -87,13 +87,6 @@ describe('Agent', () => { item.content = item.content?.split('\n').slice(0, 20).join('\n') mockEnhancedContext.push(item) } - - // Confirm .cody/ignore is active at start up - const ignore = await client.request('ignore/test', { - uri: URI.file(ignoredUri.fsPath).toString(), - }) - // TODO(dpc): Integrate file-based .cody/ignore with ignore/test - expect(ignore.policy).toBe('use') }, 20_000) beforeEach(async () => { diff --git a/lib/shared/src/cody-ignore/context-filter.ts b/lib/shared/src/cody-ignore/context-filter.ts deleted file mode 100644 index 6c09b9e0d7f1..000000000000 --- a/lib/shared/src/cody-ignore/context-filter.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { URI } from 'vscode-uri' - -import { IgnoreHelper } from './ignore-helper' - -export const ignores = new IgnoreHelper() - -/** - * Checks if a local file should be ignored by Cody based on the ignore rules. - * - * Takes URI with file scheme to ensure absolute file paths are ignored correctly across workspaces - * - * 🚨 SECURITY: Each Cody service is responsible for ensuring context from cody ignored files are removed from all LLM requests. - * See ./ignore-helper.ts for more details. - */ -export function isCodyIgnoredFile(uri: URI): boolean { - return ignores.isIgnored(uri) -} diff --git a/lib/shared/src/cody-ignore/ignore-helper.test.ts b/lib/shared/src/cody-ignore/ignore-helper.test.ts deleted file mode 100644 index a73b7b89197f..000000000000 --- a/lib/shared/src/cody-ignore/ignore-helper.test.ts +++ /dev/null @@ -1,210 +0,0 @@ -import { beforeEach, describe, expect, it, test } from 'vitest' -import { URI, Utils } from 'vscode-uri' - -import { testFileUri } from '../test/path-helpers' - -import { CODY_IGNORE_URI_PATH, IgnoreHelper, ignoreFileEffectiveDirectory } from './ignore-helper' - -describe('IgnoreHelper', () => { - let ignore: IgnoreHelper - const workspace1Root = testFileUri('foo/workspace1') - const workspace2Root = testFileUri('foo/workspace2') - - function setIgnores(workspaceRoot: URI, ignoreFolder: string, rules: string[]) { - ignore.setIgnoreFiles(workspaceRoot, [ - { - uri: Utils.joinPath(workspaceRoot, ignoreFolder, CODY_IGNORE_URI_PATH), - content: rules.join('\n'), - }, - ]) - } - - function setWorkspace1Ignores(rules: string[]) { - setIgnores(workspace1Root, '.', rules) - } - - function setWorkspace2Ignores(rules: string[]) { - setIgnores(workspace2Root, '.', rules) - } - - function setWorkspace1NestedIgnores(folder: string, rules: string[]) { - setIgnores(workspace1Root, folder, rules) - } - - beforeEach(() => { - ignore = new IgnoreHelper() - ignore.setActiveState(true) - }) - - it('returns true for non-file schemed URLs', () => { - const nonFileWorkspaceRoot = workspace1Root.with({ scheme: 'non-file' }) - expect(ignore.isIgnored(Utils.joinPath(nonFileWorkspaceRoot, 'foo.txt'))).toBe(true) - }) - - it('returns true for non-file schemed URLs - vscode user settings', () => { - const nonFileWorkspaceRoot = workspace1Root.with({ scheme: 'vscode-userdata' }) - expect(ignore.isIgnored(Utils.joinPath(nonFileWorkspaceRoot, 'settings.json'))).toBe(true) - }) - - it('returns false for an undefined workspace', () => { - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'foo.txt'))).toBe(false) - }) - - it('returns false for a workspace with no ignores', () => { - setWorkspace1Ignores([]) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'foo.txt'))).toBe(false) - }) - - it('returns true for ".env" in an undefined workspace', () => { - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, '.env'))).toBe(true) - }) - - it('returns true for ".env" in a workspace with no ignores', () => { - setWorkspace1Ignores([]) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'a', '.env'))).toBe(true) - }) - - it('returns true for a nested ".env" in a workspace with no ignores', () => { - setWorkspace1Ignores([]) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'a', '.env'))).toBe(true) - }) - - it('returns true for a nested ".env" in a workspace with unrelated ignores', () => { - setWorkspace1Ignores(['ignored.txt']) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'a', '.env'))).toBe(true) - }) - - it('returns true for a top-level file ignored at the top level', () => { - setWorkspace1Ignores(['ignored.txt']) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'ignored.txt'))).toBe(true) - }) - - it('returns false for a top-level file not ignored at the top level', () => { - setWorkspace1Ignores(['ignored.txt']) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'not_ignored.txt'))).toBe(false) - }) - - it('returns false for a top-level file unignored at the top level', () => { - setWorkspace1Ignores(['*ignored.txt', '!not_ignored.txt']) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'not_ignored.txt'))).toBe(false) - }) - - it('returns true for a nested file ignored at the top level', () => { - setWorkspace1Ignores(['always_ignored.txt', 'a/explitly_ignored.txt']) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'a/always_ignored.txt'))).toBe(true) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'a/explitly_ignored.txt'))).toBe(true) - }) - - it('returns false for a nested file not ignored at the top level', () => { - setWorkspace1Ignores(['a/ignored.txt']) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'b/ignored.txt'))).toBe(false) - }) - - it('returns false for a nested file unignored at the top level', () => { - setWorkspace1Ignores(['*ignored.txt', '!not_ignored.txt']) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'b/not_ignored.txt'))).toBe(false) - }) - - it('returns true for a nested file ignored at the nested level', () => { - setWorkspace1NestedIgnores('a', ['ignored.txt']) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'a/ignored.txt'))).toBe(true) - }) - - it('returns false for a nested file not ignored at the nested level', () => { - setWorkspace1NestedIgnores('a', ['ignored.txt']) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'a/not_ignored.txt'))).toBe(false) - }) - - it('returns false for a nested file unignored at the nested level', () => { - setWorkspace1NestedIgnores('a', ['*ignored.txt', '!not_ignored.txt']) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'a/not_ignored.txt'))).toBe(false) - }) - - it('tracks ignores independently for each workspace root', () => { - setWorkspace1Ignores(['ignored_1.txt']) - setWorkspace2Ignores(['ignored_2.txt']) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'ignored_1.txt'))).toBe(true) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, 'ignored_2.txt'))).toBe(false) - expect(ignore.isIgnored(Utils.joinPath(workspace2Root, 'ignored_1.txt'))).toBe(false) - expect(ignore.isIgnored(Utils.joinPath(workspace2Root, 'ignored_2.txt'))).toBe(true) - }) - - it('throws on an empty file: URI', () => { - expect(() => ignore.isIgnored(URI.parse('file:///'))).toThrow() - }) - - it.skip('throws on a relative Uri', () => { - const relativeFileUri = URI.parse('file://a') - expect(() => ignore.isIgnored(relativeFileUri)).toThrow() - }) - - it('handles comments and blank lines in the ignore file', () => { - setWorkspace1Ignores([ - '# header comment', - '#.foo', - '', - '.bar # an explanatory reason that .bar is ignored', - ]) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, '.env'))).toBe(true) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, '.foo'))).toBe(false) - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, '.bar'))).toBe(true) - }) - - describe('returns the correct value for a sample of rules', () => { - beforeEach(() => { - setWorkspace1Ignores([ - 'node_modules/', - '**/cody', - '**/foo/**', - '/bar', - 'fooz', - 'barz/*', - '.git', - 'one/**/two', - ]) - }) - - it.each([ - 'node_modules/foo', - 'cody', - 'cody/test.ts', - 'foo/foobarz.js', - 'foo/bar', - 'fooz', - '.git', - 'barz/index.css', - 'barz/foo/index.css', - 'foo/bar/index.css', - 'foo/.git', - '.git/foo', - 'one/two', - 'one/two/three', - 'one/a/two', - 'one/a/two/three', - ])('returns true for file in ignore list %s', (filePath: string) => { - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, filePath))).toBe(true) - }) - - it.each([ - 'src/app.ts', - 'barz', - 'env/foobarz.js', - 'foobar.go', - '.barz', - '.gitignore', - 'cody.ts', - 'one/three', - 'two/one', - ])('returns false for file not in ignore list %s', (filePath: string) => { - expect(ignore.isIgnored(Utils.joinPath(workspace1Root, filePath))).toBe(false) - }) - }) -}) - -describe('ignoreFileEffectiveDirectory', () => { - test('', () => { - expect(ignoreFileEffectiveDirectory(URI.parse('file:///a/b/.cody/ignore')).toString()).toBe( - 'file:///a/b' - ) - }) -}) diff --git a/lib/shared/src/cody-ignore/ignore-helper.ts b/lib/shared/src/cody-ignore/ignore-helper.ts deleted file mode 100644 index 87a486803219..000000000000 --- a/lib/shared/src/cody-ignore/ignore-helper.ts +++ /dev/null @@ -1,194 +0,0 @@ -import ignore, { type Ignore } from 'ignore' -import { URI, Utils } from 'vscode-uri' - -import { pathFunctionsForURI } from '../common/path' -import { isWindows } from '../common/platform' -import { uriBasename } from '../common/uri' -import { uriHasPrefix } from '../editor/displayPath' - -/** - * The Cody ignore URI path. - */ -export const CODY_IGNORE_URI_PATH = '.cody/ignore' - -/** - * A glob matching the Cody ignore URI path. - */ -export const CODY_IGNORE_POSIX_GLOB = `**/${CODY_IGNORE_URI_PATH}` - -type ClientWorkspaceRootURI = string - -/** - * A helper to efficiently check if a file should be ignored from a set - * of nested ignore files. - * - * Callers must call `setIgnoreFiles` for each workspace root with the full set of ignore files (even - * if there are zero) at startup (or when new workspace folders are added) and any time an ignore file - * is modified/created/deleted. - * - * `clearIgnoreFiles` should be called for workspace roots as they are removed. - */ -export class IgnoreHelper { - /** - * A map of workspace roots to their ignore rules. - */ - private workspaceIgnores = new Map() - public hasCodyIgnoreFiles = false - /** - * Check if the configuration is enabled or not - * Do not ignore files if the feature is not enabled - * TODO: Remove this once it's ready for GA - */ - public isActive = false - public setActiveState(isActive: boolean): void { - this.isActive = isActive - } - - /** - * Builds and caches a single ignore set for all nested ignore files within a workspace root. - * @param workspaceRoot The workspace root. - * @param ignoreFiles The URIs and content of all ignore files within the root. - */ - public setIgnoreFiles(workspaceRoot: URI, ignoreFiles: IgnoreFileContent[]): void { - if (!this.isActive) { - return - } - - this.ensureAbsolute('workspaceRoot', workspaceRoot) - - const rules = this.getDefaultIgnores() - for (const ignoreFile of ignoreFiles) { - this.ensureValidCodyIgnoreFile('ignoreFile.uri', ignoreFile.uri) - - // Compute the relative path from the workspace root to the folder this ignore - // file applies to. - const effectiveDir = ignoreFileEffectiveDirectory(ignoreFile.uri) - const relativeFolderUriPath = pathFunctionsForURI(workspaceRoot).relative( - workspaceRoot.path, - effectiveDir.path - ) - - // Build the ignore rule with the relative folder path applied to the start of each rule. - for (let ignoreLine of ignoreFile.content.split('\n')) { - // Trim off any trailing comments. - ignoreLine = ignoreLine.split('#')[0] - - // Skip any lines that are now empty. - ignoreLine = ignoreLine.trim() - if (!ignoreLine.length) { - continue - } - - let isInverted = false - if (ignoreLine.startsWith('!')) { - ignoreLine = ignoreLine.slice(1) - isInverted = true - } - - // Gitignores always use POSIX/forward slashes, even on Windows. - const ignoreRule = relativeFolderUriPath.length - ? `${relativeFolderUriPath}/${ignoreLine}` - : ignoreLine - rules.add((isInverted ? '!' : '') + ignoreRule) - } - } - - this.workspaceIgnores.set(workspaceRoot.toString(), rules) - if (ignoreFiles.length && !this.hasCodyIgnoreFiles) { - this.hasCodyIgnoreFiles = true - } - } - - public clearIgnoreFiles(workspaceRoot: URI): void { - this.workspaceIgnores.delete(workspaceRoot.toString()) - } - - public isIgnored(uri: URI): boolean { - // Do not ignore if the feature is not enabled - if (!this.isActive) { - return false - } - - // Return all https URIs on the assumption that they origin from - // remote context (e.g. unified, multi-repo) files, which are already - // filtered by the backend to respect codyignore files during sync time. - const allowedNonFileSchemes = new Set(['https', 'http']) - if (allowedNonFileSchemes.has(uri.scheme)) { - return false - } - - // For notebook cells, we want to ignore the cell itself, but not the file it's in. - if (uri.scheme === 'vscode-notebook-cell') { - // Replace the scheme with the file scheme and remove the fragment that - // contains the cell id so we can use the same logic as for files. - uri = uri.with({ scheme: 'file', fragment: undefined }) - } - - // Ignore all other non-file URIs - if (uri.scheme !== 'file') { - return true - } - - this.ensureFileUri('uri', uri) - this.ensureAbsolute('uri', uri) - const workspaceRoot = this.findWorkspaceRoot(uri) - - // Not in workspace so just use default rules against the filename. - // This ensures we'll never send something like `.env` but it won't handle - // if default rules include folders like `a/b` because we have nothing to make - // a relative path from. - if (!workspaceRoot) { - return this.getDefaultIgnores().ignores(uriBasename(uri)) - } - - const relativePath = pathFunctionsForURI(workspaceRoot).relative(workspaceRoot.path, uri.path) - const rules = this.workspaceIgnores.get(workspaceRoot.toString()) ?? this.getDefaultIgnores() - return rules.ignores(relativePath) ?? false - } - - private findWorkspaceRoot(file: URI): URI | undefined { - const candidates = Array.from(this.workspaceIgnores.keys()).filter(workspaceRoot => - uriHasPrefix(file, URI.parse(workspaceRoot), isWindows()) - ) - // If this file was inside multiple workspace roots, take the shortest one since it will include - // everything the nested one does (plus potentially extra rules). - candidates.sort((a, b) => a.length - b.length) - const selected = candidates.at(0) - return selected ? URI.parse(selected) : undefined - } - - private ensureFileUri(name: string, uri: URI): void { - if (uri.scheme !== 'file') { - throw new Error(`${name} should be a file URI: "${uri}"`) - } - } - - private ensureAbsolute(name: string, uri: URI): void { - if (!uri.path.startsWith('/')) { - throw new Error(`${name} should be absolute: "${uri.toString()}"`) - } - } - - private ensureValidCodyIgnoreFile(name: string, uri: URI): void { - this.ensureAbsolute('ignoreFile.uri', uri) - if (!uri.path.endsWith(CODY_IGNORE_URI_PATH)) { - throw new Error(`${name} should end with "${CODY_IGNORE_URI_PATH}": "${uri.toString()}"`) - } - } - - private getDefaultIgnores(): Ignore { - return ignore().add('.env') - } -} - -export interface IgnoreFileContent { - uri: URI - content: string -} - -/** - * Return the directory that a .cody/ignore file applies to. - */ -export function ignoreFileEffectiveDirectory(ignoreFile: URI): URI { - return Utils.joinPath(ignoreFile, '..', '..') -} diff --git a/lib/shared/src/index.ts b/lib/shared/src/index.ts index b33b0ce80ded..a018b76b25e6 100644 --- a/lib/shared/src/index.ts +++ b/lib/shared/src/index.ts @@ -19,13 +19,6 @@ export { } from './models/utils' export { BotResponseMultiplexer } from './chat/bot-response-multiplexer' export { ChatClient } from './chat/chat' -export { ignores, isCodyIgnoredFile } from './cody-ignore/context-filter' -export { - IgnoreHelper, - CODY_IGNORE_POSIX_GLOB, - type IgnoreFileContent, - CODY_IGNORE_URI_PATH, -} from './cody-ignore/ignore-helper' export { getSimplePreamble } from './chat/preamble' export type { SerializedChatInteraction, diff --git a/vscode/CHANGELOG.md b/vscode/CHANGELOG.md index c64552cb6185..a939ae4dd3cd 100644 --- a/vscode/CHANGELOG.md +++ b/vscode/CHANGELOG.md @@ -13,6 +13,7 @@ Chat: Fixed feedback buttons not working in chat. [pull/5509](https://github.com ### Changed Enterprise: Remote Repository items in the mention menu now display only the org/repo part of the title, omitting the code host name to prevent repository names from being truncated in the UI. [pull/5518](https://github.com/sourcegraph/cody/pull/5518) +Cody Ignore: This internal experimental feature is now deprecated and the use of `.cody/ignore` file is no longer supported. [pull/5537](https://github.com/sourcegraph/cody/pull/5537) ## 1.34.1 diff --git a/vscode/src/chat/chat-view/ChatModel.ts b/vscode/src/chat/chat-view/ChatModel.ts index 5e2875aad3cf..7d928b4c40ee 100644 --- a/vscode/src/chat/chat-view/ChatModel.ts +++ b/vscode/src/chat/chat-view/ChatModel.ts @@ -8,7 +8,6 @@ import { type SerializedChatInteraction, type SerializedChatTranscript, errorToChatError, - isCodyIgnoredFile, modelsService, serializeChatMessage, toRangeData, @@ -51,10 +50,10 @@ export class ChatModel { throw new Error('Cannot set new context used for bot message') } - lastMessage.contextFiles = newContextUsed.filter(c => !isCodyIgnoredFile(c.uri)) + lastMessage.contextFiles = newContextUsed lastMessage.contextAlternatives = contextAlternatives?.map(({ items, strategy }) => { return { - items: items.filter(c => !isCodyIgnoredFile(c.uri)), + items: items, strategy, } }) diff --git a/vscode/src/cody-ignore/notification.ts b/vscode/src/cody-ignore/notification.ts index 6853a9c77731..8ed0fb850ca7 100644 --- a/vscode/src/cody-ignore/notification.ts +++ b/vscode/src/cody-ignore/notification.ts @@ -1,6 +1,10 @@ import * as vscode from 'vscode' -export type CodyIgnoreType = 'cody-ignore' | 'context-filter' +/** + * Enterprise only. + * Filtered context out by cody.contextFilters Enterprise configuration setting. + */ +export type CodyIgnoreType = 'context-filter' export type CodyIgnoreFeature = 'command' | 'edit' | 'test' | 'autocomplete' export async function showCodyIgnoreNotification( @@ -16,10 +20,6 @@ export async function showCodyIgnoreNotification( : feature === 'test' ? 'Failed to generate test' : 'Command failed to run' - }: file is ignored (${ - type === 'context-filter' - ? 'due to cody.contextFilters Enterprise configuration setting' - : 'due to your cody ignore config' - })` + }: file is ignored (due to cody.contextFilters Enterprise configuration setting)` ) } diff --git a/vscode/src/commands/context/index.ts b/vscode/src/commands/context/index.ts index a082a568d726..2f872594720e 100644 --- a/vscode/src/commands/context/index.ts +++ b/vscode/src/commands/context/index.ts @@ -1,6 +1,6 @@ import * as vscode from 'vscode' -import { type CodyCommandContext, type ContextItem, isCodyIgnoredFile } from '@sourcegraph/cody-shared' +import type { CodyCommandContext, ContextItem } from '@sourcegraph/cody-shared' import { Utils } from 'vscode-uri' import { logDebug } from '../../log' @@ -68,7 +68,7 @@ export const getCommandContextFiles = async (config: CodyCommandContext): Promis contextFiles.push(...(await getContextFileFromTabs())) } - return contextFiles.filter(file => !isCodyIgnoredFile(file.uri)) + return contextFiles } catch (error) { logDebug('getCommandContextFiles', 'Error getting command context files', error) return [] diff --git a/vscode/src/commands/context/selection.ts b/vscode/src/commands/context/selection.ts index 2206b9e2c6d6..376ef460217b 100644 --- a/vscode/src/commands/context/selection.ts +++ b/vscode/src/commands/context/selection.ts @@ -2,7 +2,6 @@ import { type ContextItem, TokenCounterUtils, contextFiltersProvider, - isCodyIgnoredFile, logError, toRangeData, wrapInActiveSpan, @@ -136,5 +135,5 @@ export async function getSelectionOrFileContext(): Promise { } async function shouldIgnore(uri: URI): Promise { - return Boolean((await contextFiltersProvider.isUriIgnored(uri)) || isCodyIgnoredFile(uri)) + return Boolean(await contextFiltersProvider.isUriIgnored(uri)) } diff --git a/vscode/src/commands/execute/ask.ts b/vscode/src/commands/execute/ask.ts index 0f0846039094..df00c50d7adb 100644 --- a/vscode/src/commands/execute/ask.ts +++ b/vscode/src/commands/execute/ask.ts @@ -8,7 +8,6 @@ import * as vscode from 'vscode' import type { ChatSession } from '../../chat/chat-view/ChatController' import type { WebviewSubmitMessage } from '../../chat/protocol' import { isUriIgnoredByContextFilterWithNotification } from '../../cody-ignore/context-filter' -import { showCodyIgnoreNotification } from '../../cody-ignore/notification' import { getEditor } from '../../editor/active-editor' export interface ExecuteChatArguments extends Omit { @@ -35,10 +34,6 @@ export const executeChat = async (args: ExecuteChatArguments): Promise { }) }) - describe('retrieved context is filtered by .cody/ignore', () => { - const workspaceRoot = testFileUri('') - beforeAll(() => { - ignores.setActiveState(true) - // all foo.ts files will be ignored - ignores.setIgnoreFiles(workspaceRoot, [ - { - uri: Utils.joinPath(workspaceRoot, '.', CODY_IGNORE_URI_PATH), - content: '**/foo.ts', - }, - ]) - }) - it('mixes results are filtered', async () => { - const mixer = new ContextMixer( - createMockStrategy([ - [ - { - identifier: 'jaccard-similarity', - uri: testFileUri('foo.ts'), - content: 'function foo1() {}', - startLine: 0, - endLine: 0, - }, - { - identifier: 'jaccard-similarity', - uri: testFileUri('foo/bar.ts'), - content: 'function bar1() {}', - startLine: 0, - endLine: 0, - }, - ], - [ - { - identifier: 'jaccard-similarity', - uri: testFileUri('test/foo.ts'), - content: 'function foo3() {}', - startLine: 10, - endLine: 10, - }, - { - identifier: 'jaccard-similarity', - uri: testFileUri('foo.ts'), - content: 'function foo1() {}\nfunction foo2() {}', - startLine: 0, - endLine: 1, - }, - { - identifier: 'jaccard-similarity', - uri: testFileUri('example/bar.ts'), - content: 'function bar1() {}\nfunction bar2() {}', - startLine: 0, - endLine: 1, - }, - ], - ]) - ) - const { context } = await mixer.getContext(defaultOptions) - const contextFiles = normalize(context) - // returns 2 bar.ts context - expect(contextFiles?.length).toEqual(2) - for (const context of contextFiles) { - expect( - isCodyIgnoredFile(Utils.joinPath(workspaceRoot, context.fileName)) - ).toBeFalsy() - } - }) - }) - describe('retrieved context is filtered by context filters', () => { beforeAll(() => { vi.spyOn(contextFiltersProvider, 'isUriIgnored').mockImplementation( @@ -382,7 +309,13 @@ describe('ContextMixer', () => { ) const { context } = await mixer.getContext(defaultOptions) const contextFiles = normalize(context) - expect(contextFiles.map(c => c.fileName)).toEqual(['bar.ts', 'bar.ts']) + expect(contextFiles.map(c => c.fileName)).toEqual([ + 'foo.ts', + 'foo.ts', + 'foo.ts', + 'bar.ts', + 'bar.ts', + ]) }) }) }) diff --git a/vscode/src/completions/context/context-mixer.ts b/vscode/src/completions/context/context-mixer.ts index b03c5477efaf..2b4b2969ae8a 100644 --- a/vscode/src/completions/context/context-mixer.ts +++ b/vscode/src/completions/context/context-mixer.ts @@ -4,7 +4,6 @@ import { type AutocompleteContextSnippet, type DocumentContext, contextFiltersProvider, - isCodyIgnoredFile, wrapInActiveSpan, } from '@sourcegraph/cody-shared' @@ -183,9 +182,6 @@ async function filter(snippets: AutocompleteContextSnippet[]): Promise { - if (isCodyIgnoredFile(snippet.uri)) { - return null - } if (await contextFiltersProvider.isUriIgnored(snippet.uri)) { return null } diff --git a/vscode/src/completions/inline-completion-item-provider.ts b/vscode/src/completions/inline-completion-item-provider.ts index 1a9dfeb7e741..449fb9997a23 100644 --- a/vscode/src/completions/inline-completion-item-provider.ts +++ b/vscode/src/completions/inline-completion-item-provider.ts @@ -9,7 +9,6 @@ import { contextFiltersProvider, createDisposables, featureFlagProvider, - isCodyIgnoredFile, subscriptionDisposable, telemetryRecorder, wrapInActiveSpan, @@ -327,12 +326,6 @@ export class InlineCompletionItemProvider this.lastManualCompletionTimestamp > Date.now() - 500 ) - // Do not create item for files that are on the cody ignore list - if (isCodyIgnoredFile(document.uri)) { - logIgnored(document.uri, 'cody-ignore', isManualCompletion) - return null - } - if (await contextFiltersProvider.isUriIgnored(document.uri)) { logIgnored(document.uri, 'context-filter', isManualCompletion) return null diff --git a/vscode/src/edit/manager.ts b/vscode/src/edit/manager.ts index 53be4a7690fb..e9931a744035 100644 --- a/vscode/src/edit/manager.ts +++ b/vscode/src/edit/manager.ts @@ -4,7 +4,6 @@ import { type ChatClient, ClientConfigSingleton, PromptString, - isCodyIgnoredFile, modelsService, ps, telemetryRecorder, @@ -18,7 +17,6 @@ import type { FixupTask } from '../non-stop/FixupTask' import { DEFAULT_EVENT_SOURCE } from '@sourcegraph/cody-shared' import { isUriIgnoredByContextFilterWithNotification } from '../cody-ignore/context-filter' -import { showCodyIgnoreNotification } from '../cody-ignore/notification' import type { ExtensionClient } from '../extension-client' import { ACTIVE_TASK_STATES } from '../non-stop/codelenses/constants' import { authProvider } from '../services/AuthProvider' @@ -107,11 +105,6 @@ export class EditManager implements vscode.Disposable { } const editor = getEditor() - if (editor.ignored) { - showCodyIgnoreNotification('edit', 'cody-ignore') - return - } - const document = configuration.document || editor.active?.document if (!document) { void vscode.window.showErrorMessage('Please open a file before running a command.') @@ -247,10 +240,6 @@ export class EditManager implements vscode.Disposable { } const document = configuration.document - if (isCodyIgnoredFile(document.uri)) { - showCodyIgnoreNotification('edit', 'cody-ignore') - } - if (await isUriIgnoredByContextFilterWithNotification(document.uri, 'edit')) { return } diff --git a/vscode/src/editor/active-editor.ts b/vscode/src/editor/active-editor.ts index ed1fc5392ef9..44cfe9fbcdf3 100644 --- a/vscode/src/editor/active-editor.ts +++ b/vscode/src/editor/active-editor.ts @@ -1,6 +1,6 @@ import * as vscode from 'vscode' -import { SUPPORTED_URI_SCHEMAS, isCodyIgnoredFile } from '@sourcegraph/cody-shared' +import { SUPPORTED_URI_SCHEMAS } from '@sourcegraph/cody-shared' /** * Interface for tracking the last active text editor that is not a webview panel for @@ -11,6 +11,9 @@ import { SUPPORTED_URI_SCHEMAS, isCodyIgnoredFile } from '@sourcegraph/cody-shar */ interface LastActiveTextEditor { active?: vscode.TextEditor + /** + * @deprecated Cody Ignore has been deprecated. This field will be removed in the future. + */ ignored?: boolean } @@ -54,7 +57,6 @@ export function getEditor(): LastActiveTextEditor { // Update the lastActiveTextEditor if the active editor is a valid file if (SUPPORTED_URI_SCHEMAS.has(activeEditor.document.uri.scheme)) { lastActiveTextEditor.active = activeEditor - lastActiveTextEditor.ignored = isCodyIgnoredFile(activeEditor?.document.uri) } } return lastActiveTextEditor diff --git a/vscode/src/editor/utils/editor-context.test.ts b/vscode/src/editor/utils/editor-context.test.ts index db959bc516bc..e46659734847 100644 --- a/vscode/src/editor/utils/editor-context.test.ts +++ b/vscode/src/editor/utils/editor-context.test.ts @@ -8,7 +8,6 @@ import { EXTENDED_USER_CONTEXT_TOKEN_BUDGET, type Editor, contextFiltersProvider, - ignores, ps, testFileUri, uriBasename, @@ -112,23 +111,6 @@ describe('getFileContextFiles', () => { expect(vscode.workspace.findFiles).toBeCalledTimes(1) }) - - it('filters out ignored files', async () => { - ignores.setActiveState(true) - ignores.setIgnoreFiles(testFileUri(''), [ - { uri: testFileUri('.cody/ignore'), content: '*.ignore' }, - ]) - setFiles(['foo.txt', 'foo.ignore']) - - // Match the .txt but not the .ignore - expect(await runSearch('foo', 5)).toMatchInlineSnapshot(` - [ - "foo.txt", - ] - `) - - expect(vscode.workspace.findFiles).toBeCalledTimes(1) - }) }) describe('filterContextItemFiles', () => { diff --git a/vscode/src/editor/utils/editor-context.ts b/vscode/src/editor/utils/editor-context.ts index 9cc453380de3..f95d016a9604 100644 --- a/vscode/src/editor/utils/editor-context.ts +++ b/vscode/src/editor/utils/editor-context.ts @@ -18,7 +18,6 @@ import { displayPath, graphqlClient, isAbortError, - isCodyIgnoredFile, isDefined, isErrorLike, isWindows, @@ -284,9 +283,9 @@ export async function getOpenTabsContextFile(): Promise { return await filterContextItemFiles( ( await Promise.all( - getOpenTabsUris() - .filter(uri => !isCodyIgnoredFile(uri)) - .map(uri => createContextFileFromUri(uri, ContextItemSource.User, 'file')) + getOpenTabsUris().map(uri => + createContextFileFromUri(uri, ContextItemSource.User, 'file') + ) ) ).flat() ) @@ -314,10 +313,6 @@ async function createContextFileFromUri( kind?: SymbolKind, symbolName?: string ): Promise { - if (isCodyIgnoredFile(uri)) { - return [] - } - const range = toRangeData(selectionRange) return [ type === 'file' diff --git a/vscode/src/editor/vscode-editor.ts b/vscode/src/editor/vscode-editor.ts index 02ea3d3d5cf7..c5520605ccb4 100644 --- a/vscode/src/editor/vscode-editor.ts +++ b/vscode/src/editor/vscode-editor.ts @@ -9,7 +9,6 @@ import { type Editor, type RangeData, SURROUNDING_LINES, - isCodyIgnoredFile, } from '@sourcegraph/cody-shared' import { CommandCodeLenses } from '../commands/services/code-lenses' @@ -49,7 +48,6 @@ export class VSCodeEditor implements Editor { content: documentText, fileUri: documentUri, selectionRange: documentSelection.isEmpty ? undefined : documentSelection, - ignored: isCodyIgnoredFile(activeEditor.document.uri), } } diff --git a/vscode/src/main.ts b/vscode/src/main.ts index 3ee9bc328acd..684dcd52a28a 100644 --- a/vscode/src/main.ts +++ b/vscode/src/main.ts @@ -89,7 +89,6 @@ import { registerSidebarCommands } from './services/SidebarCommands' import { type CodyStatusBar, createStatusBar } from './services/StatusBar' import { upstreamHealthProvider } from './services/UpstreamHealthProvider' import { autocompleteStageCounterLogger } from './services/autocomplete-stage-counter-logger' -import { setUpCodyIgnore } from './services/cody-ignore' import { createOrUpdateTelemetryRecorderProvider } from './services/telemetry-v2' import { onTextDocumentChange } from './services/utils/codeblock-action-tracker' import { @@ -273,7 +272,6 @@ const register = async ( registerChatCommands(disposables) disposables.push(...registerSidebarCommands()) const config = await firstValueFrom(resolvedConfigWithAccessToken) - disposables.push(...setUpCodyIgnore(config)) registerOtherCommands(disposables) if (isExtensionModeDevOrTest) { await registerTestCommands(context, disposables) diff --git a/vscode/src/prompt-builder/index.ts b/vscode/src/prompt-builder/index.ts index b744a2b147ed..3177e0580e81 100644 --- a/vscode/src/prompt-builder/index.ts +++ b/vscode/src/prompt-builder/index.ts @@ -5,7 +5,6 @@ import { type ModelContextWindow, TokenCounter, contextFiltersProvider, - isCodyIgnoredFile, ps, } from '@sourcegraph/cody-shared' import type { ContextTokenUsageType } from '@sourcegraph/cody-shared/src/token' @@ -125,7 +124,7 @@ export class PromptBuilder { for (const item of contextItems) { // Skip context items that are in the Cody ignore list - if (isCodyIgnoredFile(item.uri) || (await contextFiltersProvider.isUriIgnored(item.uri))) { + if (await contextFiltersProvider.isUriIgnored(item.uri)) { result.ignored.push(item) continue } diff --git a/vscode/src/services/StatusBar.ts b/vscode/src/services/StatusBar.ts index 3192edb68ebe..a56ab9c13f29 100644 --- a/vscode/src/services/StatusBar.ts +++ b/vscode/src/services/StatusBar.ts @@ -5,7 +5,6 @@ import { type ClientConfiguration, CodyIDE, contextFiltersProvider, - isCodyIgnoredFile, } from '@sourcegraph/cody-shared' import { getConfiguration } from '../configuration' @@ -68,34 +67,19 @@ export function createStatusBar(): CodyStatusBar { statusBarItem.show() let isCodyIgnoredType: null | CodyIgnoreType = null - async function isCodyIgnored(uri: vscode.Uri): Promise { - if (uri.scheme === 'file' && isCodyIgnoredFile(uri)) { - return 'cody-ignore' - } - if (await contextFiltersProvider.isUriIgnored(uri)) { - return 'context-filter' - } - return null - } - const onDocumentChange = vscode.window.onDidChangeActiveTextEditor(async editor => { - if (!editor) { + async function updateIgnoreStatus(uri: vscode.Uri | undefined): Promise { + if (!uri) { + isCodyIgnoredType = null return } - isCodyIgnoredType = await isCodyIgnored(editor.document.uri) - if (isCodyIgnoredType !== 'cody-ignore') { - vscode.commands.executeCommand('setContext', 'cody.currentFileIgnored', !!isCodyIgnoredType) - } + isCodyIgnoredType = (await contextFiltersProvider.isUriIgnored(uri)) ? 'context-filter' : null rerender() - }) - const currentUri = vscode.window.activeTextEditor?.document?.uri - if (currentUri) { - isCodyIgnored(currentUri).then(isIgnored => { - if (isCodyIgnoredType !== 'cody-ignore') { - vscode.commands.executeCommand('setContext', 'cody.currentFileIgnored', !!isIgnored) - } - isCodyIgnoredType = isIgnored - }) } + const onDocumentChange = vscode.window.onDidChangeActiveTextEditor(editor => + updateIgnoreStatus(editor?.document.uri) + ) + // Initial check for the current active editor + updateIgnoreStatus(vscode.window.activeTextEditor?.document?.uri) let authStatus: AuthStatus | undefined const command = vscode.commands.registerCommand(STATUS_BAR_INTERACTION_COMMAND, async () => { diff --git a/vscode/src/services/cody-ignore.ts b/vscode/src/services/cody-ignore.ts deleted file mode 100644 index 0fb383130563..000000000000 --- a/vscode/src/services/cody-ignore.ts +++ /dev/null @@ -1,237 +0,0 @@ -import * as vscode from 'vscode' - -import { - CODY_IGNORE_POSIX_GLOB, - type ClientConfiguration, - type IgnoreFileContent, - ignores, -} from '@sourcegraph/cody-shared' - -import { telemetryRecorder } from '@sourcegraph/cody-shared' -import { logDebug } from '../log' -import { TestSupport } from '../test-support' - -const utf8 = new TextDecoder('utf-8') - -/** - * Parses `.code/ignore` files from the workspace and sets up a watcher to refresh - * whenever the files change. - * - * NOTE: Execute ONCE at extension activation time. - */ -export function setUpCodyIgnore(config: ClientConfiguration): vscode.Disposable[] { - if (TestSupport.instance) { - TestSupport.instance.ignoreHelper.set(ignores) - } - - ignores.setActiveState(config.internalUnstable) - if (!config.internalUnstable) { - return [] - } - - // Enable ignore and then handle existing workspace folders. - vscode.workspace.workspaceFolders?.map(async wf => await refresh(wf.uri)) - - const disposables: vscode.Disposable[] = [] - - // Refresh ignore rules when any ignore file in the workspace changes. - const watcher = vscode.workspace.createFileSystemWatcher(CODY_IGNORE_POSIX_GLOB) - watcher.onDidChange(refresh) - watcher.onDidCreate(refresh) - watcher.onDidDelete(refresh) - - // Handle any added/removed workspace folders. - const didChangeSubscription = vscode.workspace.onDidChangeWorkspaceFolders(e => { - e.added.map(wf => refresh(wf.uri)) - e.removed.map(wf => clear(wf)) - }) - - const onDidChangeConfig = vscode.workspace.onDidChangeConfiguration(e => { - // NOTE This can be removed once cody ignore is stable. - if (e.affectsConfiguration('cody')) { - onConfigChange() - } - // NOTE This allows us to search for the ignore files again - // if the user changes the search.symlinks setting. - if (e.affectsConfiguration('search')) { - // Only refresh if the ignore sidebar is empty, - // which means the setup step has initially failed. - if (ignores.isActive && !ignores.hasCodyIgnoreFiles) { - onConfigChange() - } - } - }) - - disposables.push(...[watcher, didChangeSubscription, onDidChangeConfig]) - return disposables -} - -/** - * The cancellation tokens for finding workspace ignore file processes. - */ -const findInProgressTokens = new Map() - -/** - * Refreshes the ignore rules for the given workspace URI by searching - * for `.cody/ignore` files and reading their contents. This allows - * dynamically updating the ignore rules as ignore files are added/removed. - * - * Cancels any existing findFiles processes for the workspace to avoid - * multiple concurrent processes. Also sets a timeout of 1 min to avoid long running - * processes. - */ -async function refresh(uri: vscode.Uri): Promise { - // Skip refresh if .cody/ignore is not enabled - if (!ignores.isActive) { - return - } - - const wf = vscode.workspace.getWorkspaceFolder(uri) - const cancel = () => { - const tokenFound = findInProgressTokens.get(uri.path) - tokenFound?.cancel() - tokenFound?.dispose() - findInProgressTokens.delete(uri.path) - } - - if (!wf) { - // If this happens, we either have no workspace folder or it was removed before we started - // processing the watch event. - logDebug('CodyIgnore:refresh', 'failed', { verbose: 'no workspace detecetd' }) - return - } - - // We currently only support file://. To support others, we need to change all file - // paths in lots of places to be URIs. - if (wf.uri.scheme !== 'file') { - logDebug('CodyIgnore:refresh', 'failed', { verbose: 'not a file' }) - return - } - - const startTime = performance.now() - logDebug('CodyIgnore:refresh', 'started', { verbose: startTime }) - - // Cancel fileFiles process for current workspace if there is one in progress to avoid - // having multiple find files in progress that can cause performance slow-down issues. - cancel() - - // Set a new cancellation token for the workspace. - const newToken = new vscode.CancellationTokenSource() - findInProgressTokens.set(uri.path, newToken) - - // Timeout after 1 minutes to avoid causing performance issues. - setTimeout( - () => { - // The search is already completed / canceled if no token is found. - if (findInProgressTokens.get(uri.path)) { - cancel() - // TODO locate ignore file from codebase root instead of workspace - // Try looking for ignore file at workspace root as fallback. - const ignoreFileAtRoot = vscode.Uri.joinPath(wf.uri, '.cody', 'ignore') - tryReadFile(ignoreFileAtRoot).then(content => { - if (content.length) { - setCodyIgnoreFiles(wf.uri, [{ uri: ignoreFileAtRoot, content }]) - logDebug('CodyIgnore:refresh', 'found ignore file at root', { - verbose: wf.uri.path, - }) - return - } - const title = 'Failed to locate Cody ignore files in current workspace.' - const description = 'Try disable the `search.followSymlinks` setting in your editor.' - const message = `${title} ${description}` - logDebug('CodyIgnore:refresh:failed', message, { verbose: wf.uri.path }) - }) - } - return - }, - 1 * 60 * 1000 // 1 minute - ) - - // Look for .cody/ignore files within the workspace, - // exclude all dot files (except .cody) and common build files. - const ignoreFilePattern = new vscode.RelativePattern(wf.uri, CODY_IGNORE_POSIX_GLOB) - const excludePattern = '.*, **/.* ,**/{node_modules,out,build,dist}/**' - const ignoreFiles = await vscode.workspace.findFiles( - ignoreFilePattern, - excludePattern, - undefined, - newToken.token - ) - const filesWithContent: IgnoreFileContent[] = await Promise.all( - ignoreFiles?.map(async fileUri => ({ - uri: fileUri, - content: await tryReadFile(fileUri), - })) - ) - - setCodyIgnoreFiles(wf.uri, filesWithContent) - - // If we can locate the token, that means the job was completed before it times out. - if (findInProgressTokens.get(uri.path)) { - findInProgressTokens.delete(uri.path) - const elapsed = performance.now() - startTime - logDebug('CodyIgnore:refresh', `refresh completed in ${elapsed}`, { verbose: wf.uri.path }) - } -} - -function setCodyIgnoreFiles(ws: vscode.Uri, files: IgnoreFileContent[]): void { - ignores.setIgnoreFiles(ws, files) - if (files.length) { - telemetryRecorder.recordEvent('cody.codyIgnore', 'hasFile', { - billingMetadata: { - product: 'cody', - category: 'billable', - }, - }) - } -} - -/** - * Removes ignore rules for the provided WorkspaceFolder. - */ -function clear(wf: vscode.WorkspaceFolder): void { - // We currently only support file://. To support others, we need to change all file - // paths in lots of places to be URIs. - if (wf.uri.scheme !== 'file') { - return - } - - ignores.clearIgnoreFiles(wf.uri) - - // Remove any in-progress cancellation tokens for the workspace. - const tokens = findInProgressTokens.values() - for (const token of tokens) { - token.cancel() - token.dispose() - } - findInProgressTokens.clear() - logDebug('CodyIgnore:clearIgnoreFiles:workspace', 'removed', { verbose: wf.uri.toString() }) -} - -/** - * Read the content of `fileUri`. - * - * Returns an empty string if the file was not readable (for example it was removed before we read it). - */ -async function tryReadFile(fileUri: vscode.Uri): Promise { - return vscode.workspace.fs.readFile(fileUri).then( - content => utf8.decode(content), - error => { - logDebug('CodyIgnore:clearIgnoreFiles:tryReadFile', 'failed', { - verbose: `Skipping unreadable ignore file ${fileUri}: ${error}`, - }) - return '' - } - ) -} - -/** - * Check if the config for enabling cody ignore is changed. - * - * NOTE This can be removed once cody ignore is stable. - */ -function onConfigChange(): void { - const config = vscode.workspace.getConfiguration('cody') - const isEnabled = config.get('internal.unstable') as boolean - ignores.setActiveState(isEnabled) -} diff --git a/vscode/src/test-support.ts b/vscode/src/test-support.ts index 25eca1ae6a95..65355b58460e 100644 --- a/vscode/src/test-support.ts +++ b/vscode/src/test-support.ts @@ -1,4 +1,4 @@ -import { type ChatMessage, type IgnoreHelper, ps } from '@sourcegraph/cody-shared' +import { type ChatMessage, ps } from '@sourcegraph/cody-shared' import type { ChatController } from './chat/chat-view/ChatController' // A one-slot channel which lets readers block on a value being @@ -35,7 +35,6 @@ class Rendezvous { export class TestSupport { public static instance: TestSupport | undefined public chatPanelProvider = new Rendezvous() - public ignoreHelper = new Rendezvous() public ps = ps diff --git a/vscode/test/e2e/auth.test.ts b/vscode/test/e2e/auth.test.ts index 5ebf04be169e..e1023c6914c0 100644 --- a/vscode/test/e2e/auth.test.ts +++ b/vscode/test/e2e/auth.test.ts @@ -8,7 +8,6 @@ test.extend({ // list of V2 telemetry events we expect this test to log, add to this list as needed expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth:failed', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', diff --git a/vscode/test/e2e/chat-atFile.test.ts b/vscode/test/e2e/chat-atFile.test.ts index 586b4c6974f1..884de0e08b4d 100644 --- a/vscode/test/e2e/chat-atFile.test.ts +++ b/vscode/test/e2e/chat-atFile.test.ts @@ -22,7 +22,6 @@ import { type ExpectedV2Events, executeCommandInPalette, test, withPlatformSlash test.extend({ expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', @@ -206,13 +205,11 @@ test.extend({ test.extend({ expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', 'cody.auth.signin.token:clicked', 'cody.auth:connected', - 'cody.codyIgnore:hasFile', 'cody.auth:connected', 'cody.at-mention:executed', 'cody.at-mention.file:executed', @@ -255,7 +252,6 @@ test.extend({ test.extend({ expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', @@ -297,7 +293,6 @@ test.extend({ test.extend({ expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', diff --git a/vscode/test/e2e/chat-history.test.ts b/vscode/test/e2e/chat-history.test.ts index 7f36682a3377..6150a0ab9271 100644 --- a/vscode/test/e2e/chat-history.test.ts +++ b/vscode/test/e2e/chat-history.test.ts @@ -6,7 +6,6 @@ test.extend({ // list of events we expect this test to log, add to this list as needed expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', diff --git a/vscode/test/e2e/chat-input.test.ts b/vscode/test/e2e/chat-input.test.ts index 7f2ca47b1f7a..436023eea4f3 100644 --- a/vscode/test/e2e/chat-input.test.ts +++ b/vscode/test/e2e/chat-input.test.ts @@ -13,7 +13,6 @@ import { type DotcomUrlOverride, type ExpectedV2Events, executeCommandInPalette, test.extend({ expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', @@ -180,7 +179,6 @@ test.extend({ dotcomUrl: mockServer.SERVER_URL })( test.extend({ dotcomUrl: mockServer.SERVER_URL }).extend({ expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', @@ -231,7 +229,6 @@ test.extend({ // list of events we expect this test to log, add to this list as needed expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', diff --git a/vscode/test/e2e/chat-rateLimit.test.ts b/vscode/test/e2e/chat-rateLimit.test.ts index be5c5ec732f2..fdfe88fba343 100644 --- a/vscode/test/e2e/chat-rateLimit.test.ts +++ b/vscode/test/e2e/chat-rateLimit.test.ts @@ -11,7 +11,6 @@ test.extend({ // list of events we expect this test to log, add to this list as needed expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', @@ -40,7 +39,6 @@ test.extend({ test.extend({ expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', @@ -69,7 +67,6 @@ test.extend({ test.extend({ expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', diff --git a/vscode/test/e2e/code-actions.test.ts b/vscode/test/e2e/code-actions.test.ts index 74cee0849906..18a17a5b8186 100644 --- a/vscode/test/e2e/code-actions.test.ts +++ b/vscode/test/e2e/code-actions.test.ts @@ -24,7 +24,6 @@ test.extend({ // list of events we expect this test to log, add to this list as needed expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', @@ -77,7 +76,6 @@ test.extend({ // list of events we expect this test to log, add to this list as needed expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', diff --git a/vscode/test/e2e/cody-ignore.test.ts b/vscode/test/e2e/cody-ignore.test.ts deleted file mode 100644 index b2fc39e0c4ef..000000000000 --- a/vscode/test/e2e/cody-ignore.test.ts +++ /dev/null @@ -1,89 +0,0 @@ -import path from 'node:path' -import { expect } from '@playwright/test' -import { - atMentionMenuMessage, - createEmptyChatPanel, - getContextCell, - sidebarExplorer, - sidebarSignin, -} from './common' -import { type ExpectedV2Events, executeCommandInPalette, test } from './helpers' - -/** - * NOTE: .cody/ignore current supports behind 'cody.internal.unstable' flag - * - * End-to-end test for Cody behavior when files are ignored. - * - * Tests that Cody commands and chat do not work on ignored files, - * and ignored files are not included in chat context. - */ -test.extend({ - // list of events we expect this test to log, add to this list as needed - expectedV2Events: [ - 'cody.extension:installed', - 'cody.codyIgnore:hasFile', - 'cody.auth.login:clicked', - 'cody.auth.signin.menu:clicked', - 'cody.auth.login:firstEver', - 'cody.auth.signin.token:clicked', - 'cody.auth:connected', - 'cody.chat-question:submitted', - 'cody.chat-question:executed', - 'cody.chatResponse:noCode', - ], -})('chat and command do not work in .cody/ignore file', async ({ page, sidebar }) => { - // Sign into Cody - await sidebarSignin(page, sidebar) - - // Open the file that is on the .cody/ignore list from the tree view - await sidebarExplorer(page).click() - await page.getByRole('treeitem', { name: 'ignoredByCody.css' }).locator('a').dblclick() - await page.getByRole('tab', { name: 'ignoredByCody.css' }).hover() - - // Cody icon in the status bar should shows that the file is being ignored - const statusBarButton = page.getByRole('button', { - name: 'cody-logo-heavy-slash File Ignored, The current file is ignored by Cody', - }) - await statusBarButton.hover() - await expect(statusBarButton).toBeVisible() - - await page.getByRole('tab', { name: 'Cody', exact: true }).locator('a').click() - - // Start new chat - const [chatPanel, chatInput] = await createEmptyChatPanel(page) - - /* TEST: Chat Context - Ignored file do not show up with context */ - await chatInput.focus() - await chatInput.fill('Ignore me') - await chatInput.press('Enter') - // Assistant should response to your chat question, - // but the current file is excluded (ignoredByCody.css) and not on the context list - await expect(chatPanel.getByText('hello from the assistant')).toBeVisible() - const contextCell = getContextCell(chatPanel) - await expect(contextCell).not.toBeVisible() - - /* TEST: At-file - Ignored file does not show up as context when using @-mention */ - await chatInput.focus() - await chatInput.clear() - await chatInput.fill('@ignoredByCody') - await expect(atMentionMenuMessage(chatPanel, 'No files found')).toBeVisible() - await chatInput.clear() - await chatInput.fill('@ignore') - await expect( - chatPanel.getByRole('option', { name: withPlatformSlashes('ignore .cody') }) - ).toBeVisible() - await expect(chatPanel.getByRole('option', { name: 'ignoredByCody.css' })).not.toBeVisible() - - /* TEST: Command - Ignored file do not show up with context */ - await executeCommandInPalette(page, 'Cody Command: Explain Code') - // Assistant should not response to your command, so you should still see the old message. - await expect(chatPanel.getByText('Ignore me')).toBeVisible() - // A system message shows up to notify users that the file is ignored - await expect( - page.getByText(/^Command failed to run: file is ignored \(due to your cody ignore config\)/) - ).toBeVisible() -}) - -function withPlatformSlashes(input: string) { - return input.replaceAll(path.posix.sep, path.sep) -} diff --git a/vscode/test/e2e/command-commit.test.ts b/vscode/test/e2e/command-commit.test.ts index 52bd75a32139..88760aa78d40 100644 --- a/vscode/test/e2e/command-commit.test.ts +++ b/vscode/test/e2e/command-commit.test.ts @@ -67,7 +67,4 @@ testGitWorkspace.extend({ await page.getByRole('button', { name: 'Generate Commit Message (Experimental)' }).click() await expect(scmInputBox.filter({ hasText: 'hello from the assistant' }).first()).toBeVisible() - - // Verify notification is shown if items are ignored - await expect(page.getByLabel('Cody was forced to skip 1 file').first()).toBeVisible() }) diff --git a/vscode/test/e2e/command-core.test.ts b/vscode/test/e2e/command-core.test.ts index 8f9b53b963b3..37b69984b4d8 100644 --- a/vscode/test/e2e/command-core.test.ts +++ b/vscode/test/e2e/command-core.test.ts @@ -15,7 +15,6 @@ test.extend({ // list of events we expect this test to log, add to this list as needed expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', @@ -53,7 +52,6 @@ test.extend({ // list of events we expect this test to log, add to this list as needed expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', @@ -98,7 +96,6 @@ test.extend({ // list of events we expect this test to log, add to this list as needed expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', diff --git a/vscode/test/e2e/command-custom.test.ts b/vscode/test/e2e/command-custom.test.ts index d212fb0ea0e1..87eaf1b2426a 100644 --- a/vscode/test/e2e/command-custom.test.ts +++ b/vscode/test/e2e/command-custom.test.ts @@ -29,7 +29,6 @@ test.extend({ // list of events we expect this test to log, add to this list as needed expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', @@ -120,7 +119,6 @@ test.extend({ // list of events we expect this test to log, add to this list as needed expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', @@ -155,7 +153,7 @@ test.extend({ // Show the current file numbers used as context const contextCell = getContextCell(chatPanel) - await expectContextCellCounts(contextCell, { files: 6 }) + await expectContextCellCounts(contextCell, { files: 7 }) await openContextCell(contextCell) // Display the context files to confirm no hidden files are included await expect(chatPanel.getByRole('button', { name: '.mydotfile:1-2' })).not.toBeVisible() @@ -211,7 +209,6 @@ test.extend({ // list of events we expect this test to log, add to this list as needed expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', diff --git a/vscode/test/e2e/command-edit.test.ts b/vscode/test/e2e/command-edit.test.ts index 4c0f3082f5fd..0063051091a7 100644 --- a/vscode/test/e2e/command-edit.test.ts +++ b/vscode/test/e2e/command-edit.test.ts @@ -11,7 +11,6 @@ test.extend({ // list of events we expect this test to log, add to this list as needed expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', diff --git a/vscode/test/e2e/command-menu.test.ts b/vscode/test/e2e/command-menu.test.ts index 85a0fdad11d4..6077ffca7690 100644 --- a/vscode/test/e2e/command-menu.test.ts +++ b/vscode/test/e2e/command-menu.test.ts @@ -10,7 +10,6 @@ const test = baseTest.extend({ dotcomUrl: mockServer.SERVER_U test.extend({ expectedV2Events: [ 'cody.extension:installed', - 'cody.codyIgnore:hasFile', 'cody.auth.login:clicked', 'cody.auth.signin.menu:clicked', 'cody.auth.login:firstEver', diff --git a/vscode/test/integration/multi-root/ignore.test.ts b/vscode/test/integration/multi-root/ignore.test.ts deleted file mode 100644 index a51654b41411..000000000000 --- a/vscode/test/integration/multi-root/ignore.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -import assert from 'node:assert' -import * as fs from 'node:fs' -import * as path from 'node:path' -import * as vscode from 'vscode' -import { URI } from 'vscode-uri' -import { getExtensionAPI } from '../helpers' - -suite('Ignores in multi-root workspace', () => { - const workspace1Path = vscode.workspace.workspaceFolders![0].uri.fsPath - const workspace2Path = vscode.workspace.workspaceFolders![1].uri.fsPath - - async function checkIgnore(fullPath: string, expectIgnored: boolean) { - const ignoreHelper = await (await getExtensionAPI().activate()).testing!.ignoreHelper.get() - - await new Promise(resolve => setTimeout(resolve, 1000)) - - fullPath = path.normalize(fullPath) - const fileUri = URI.file(fullPath) - - // Verify the file exists to ensure the parts are correct. - assert.ok(fs.existsSync(fullPath)) - - // Verify ignore status. - assert.equal( - ignoreHelper.isIgnored(fileUri), - expectIgnored, - `Wrong ignore status for ${fileUri}` - ) - } - - test('ignores ws1 files in workspace1', () => - checkIgnore(`${workspace1Path}/ignoreTests/ignoreTest.ws1`, true)) - - test('does not ignore ws2 files in workspace1', () => - checkIgnore(`${workspace1Path}/ignoreTests/ignoreTest.ws2`, false)) - - test('does not ignore ws1 files in workspace2', () => - checkIgnore(`${workspace2Path}/ignoreTests/ignoreTest.ws1`, false)) - - test('ignores ws2 files in workspace2', () => - checkIgnore(`${workspace2Path}/ignoreTests/ignoreTest.ws2`, true)) -})