Skip to content

Commit 1838b73

Browse files
Copilotkairosci
andcommitted
Fix: Respect .gitignore when discovering web and extension configurations
* Implement gitignore filtering for web and extension directories Co-authored-by: kairosci <alessio.attilio@engineer.com> * Fix prettier formatting issues Co-authored-by: kairosci <alessio.attilio@engineer.com> * Fix prettier formatting in test file Co-authored-by: kairosci <alessio.attilio@engineer.com>
1 parent 06dcce0 commit 1838b73

File tree

2 files changed

+101
-2
lines changed

2 files changed

+101
-2
lines changed

packages/app/src/cli/models/app/loader.test.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,45 @@ redirect_urls = [ "https://example.com/api/auth" ]
753753
expect(app.webs.length).toBe(0)
754754
})
755755

756+
test('ignores web blocks in gitignored directories', async () => {
757+
// Given
758+
const {webDirectory} = await writeConfig(appConfiguration)
759+
760+
// Create a gitignored directory with a web config
761+
const ignoredDirectory = joinPath(tmpDir, 'ignored-worktree')
762+
await mkdir(ignoredDirectory)
763+
await writeWebConfiguration({webDirectory: ignoredDirectory, role: 'backend'})
764+
765+
// Create .gitignore file
766+
const gitignoreContent = 'ignored-worktree/\n'
767+
await writeFile(joinPath(tmpDir, '.gitignore'), gitignoreContent)
768+
769+
// When
770+
const app = await loadTestingApp()
771+
772+
// Then
773+
// Should only load the web from the non-ignored directory
774+
expect(app.webs.length).toBe(1)
775+
expect(app.webs[0]!.directory).not.toContain('ignored-worktree')
776+
})
777+
778+
test('loads all web blocks when no .gitignore file exists', async () => {
779+
// Given
780+
const {webDirectory} = await writeConfig(appConfiguration)
781+
782+
// Create another directory with a web config (but no .gitignore file)
783+
const anotherDirectory = joinPath(tmpDir, 'another-web')
784+
await mkdir(anotherDirectory)
785+
await writeWebConfiguration({webDirectory: anotherDirectory, role: 'frontend'})
786+
787+
// When
788+
const app = await loadTestingApp()
789+
790+
// Then
791+
// Should load both web blocks since there's no .gitignore
792+
expect(app.webs.length).toBe(2)
793+
})
794+
756795
test('loads the app when it has a extension with a valid configuration', async () => {
757796
// Given
758797
await writeConfig(appConfiguration)
@@ -834,6 +873,44 @@ redirect_urls = [ "https://example.com/api/auth" ]
834873
expect(app.allExtensions[0]!.localIdentifier).toBe('custom-extension')
835874
})
836875

876+
test('ignores extensions in gitignored directories', async () => {
877+
// Given
878+
await writeConfig(appConfiguration)
879+
880+
// Create a non-ignored extension
881+
const blockConfiguration = `
882+
name = "my_extension"
883+
type = "checkout_post_purchase"
884+
`
885+
await writeBlockConfig({
886+
blockConfiguration,
887+
name: 'my-extension',
888+
})
889+
await writeFile(joinPath(blockPath('my-extension'), 'index.js'), '')
890+
891+
// Create a gitignored directory with an extension
892+
const ignoredExtensionDir = joinPath(tmpDir, 'extensions', 'ignored-extension')
893+
await mkdir(ignoredExtensionDir)
894+
const ignoredBlockConfiguration = `
895+
name = "ignored_extension"
896+
type = "checkout_post_purchase"
897+
`
898+
await writeFile(joinPath(ignoredExtensionDir, 'my-ignored-extension.extension.toml'), ignoredBlockConfiguration)
899+
await writeFile(joinPath(ignoredExtensionDir, 'index.js'), '')
900+
901+
// Create .gitignore file
902+
const gitignoreContent = 'extensions/ignored-extension/\n'
903+
await writeFile(joinPath(tmpDir, '.gitignore'), gitignoreContent)
904+
905+
// When
906+
const app = await loadTestingApp()
907+
908+
// Then
909+
// Should only load the non-ignored extension
910+
expect(app.allExtensions.length).toBe(1)
911+
expect(app.allExtensions[0]!.configuration.name).toBe('my_extension')
912+
})
913+
837914
test('loads the app from a extension directory when it has a extension with a valid configuration', async () => {
838915
// Given
839916
await writeConfig(appConfiguration)

packages/app/src/cli/models/app/loader.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,10 @@ class AppLoader<TConfig extends AppConfiguration, TModuleSpec extends ExtensionS
400400
return joinPath(appDirectory, webGlob, configurationFileNames.web)
401401
})
402402
webConfigGlobs.push(`!${joinPath(appDirectory, '**/node_modules/**')}`)
403-
const webTomlPaths = await glob(webConfigGlobs)
403+
const allWebTomlPaths = await glob(webConfigGlobs)
404+
405+
// Filter out paths that are ignored by .gitignore
406+
const webTomlPaths = await filterIgnoredPaths(appDirectory, allWebTomlPaths)
404407

405408
const webs = await Promise.all(webTomlPaths.map((path) => this.loadWeb(path)))
406409
this.validateWebs(webs)
@@ -559,7 +562,10 @@ class AppLoader<TConfig extends AppConfiguration, TModuleSpec extends ExtensionS
559562
return joinPath(appDirectory, extensionPath, '*.extension.toml')
560563
})
561564
extensionConfigPaths.push(`!${joinPath(appDirectory, '**/node_modules/**')}`)
562-
const configPaths = await glob(extensionConfigPaths)
565+
const allConfigPaths = await glob(extensionConfigPaths)
566+
567+
// Filter out paths that are ignored by .gitignore
568+
const configPaths = await filterIgnoredPaths(appDirectory, allConfigPaths)
563569

564570
return configPaths.map(async (configurationPath) => {
565571
const directory = dirname(configurationPath)
@@ -999,6 +1005,22 @@ async function checkIfGitTracked(appDirectory: string, configurationPath: string
9991005
return isTracked
10001006
}
10011007

1008+
/**
1009+
* Filters an array of paths to exclude those that match patterns in .gitignore
1010+
*/
1011+
async function filterIgnoredPaths(appDirectory: string, paths: string[]): Promise<string[]> {
1012+
const gitIgnorePath = joinPath(appDirectory, '.gitignore')
1013+
if (!fileExistsSync(gitIgnorePath)) return paths
1014+
1015+
const gitIgnoreContent = await readFile(gitIgnorePath)
1016+
const ignored = ignore.default().add(gitIgnoreContent)
1017+
1018+
return paths.filter((path) => {
1019+
const relative = relativePath(appDirectory, path)
1020+
return !ignored.ignores(relative)
1021+
})
1022+
}
1023+
10021024
async function getConfigurationPath(appDirectory: string, configName: string | undefined) {
10031025
const configurationFileName = getAppConfigurationFileName(configName)
10041026
const configurationPath = joinPath(appDirectory, configurationFileName)

0 commit comments

Comments
 (0)