generated from getsentry/typescript-action
-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add support for multi-django app SQL generation
We've started to use multiple django applications to reduce contention on the head of migration history. However, our migration review tooling needs to support multiple django apps which it now does.
- Loading branch information
Showing
4 changed files
with
74 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,43 @@ | ||
import {getMigrationName} from '@app/util/getMigrationName'; | ||
|
||
test('handles garbage input', () => { | ||
const [app, migration] = getMigrationName('', 'sentry'); | ||
expect(migration).toBe(''); | ||
expect(app).toBe('sentry') | ||
}); | ||
|
||
test('gets filename without extension', () => { | ||
const input = getMigrationName('./src/sentry/migrations/001_testing.py'); | ||
expect(input).toBe('001_testing'); | ||
const [app, migration] = getMigrationName('./src/sentry/migrations/001_testing.py', 'notused'); | ||
expect(migration).toBe('001_testing'); | ||
expect(app).toBe('sentry'); | ||
}); | ||
|
||
test('gets filename when passed only filename with extension', () => { | ||
const input = getMigrationName('001_testing.py'); | ||
expect(input).toBe('001_testing'); | ||
const [app, migration] = getMigrationName('001_testing.py', 'sentry'); | ||
expect(migration).toBe('001_testing'); | ||
expect(app).toBe('sentry'); | ||
}); | ||
|
||
test('gets filename without extension', () => { | ||
const [app, migration] = getMigrationName('./src/sentry/migrations/001_testing.py', 'notused'); | ||
expect(migration).toBe('001_testing'); | ||
expect(app).toBe('sentry') | ||
}); | ||
|
||
test('gets filename with partial path', () => { | ||
const [app, migration] = getMigrationName('migrations/001_testing.py', 'sentry'); | ||
expect(migration).toBe('001_testing'); | ||
expect(app).toBe('sentry'); | ||
}); | ||
|
||
test('gets application names from nested apps', () => { | ||
const [app, migration] = getMigrationName('./src/sentry/feedback/migrations/001_testing.py', 'notused'); | ||
expect(migration).toBe('001_testing'); | ||
expect(app).toBe('feedback') | ||
}); | ||
|
||
test('preserve single quotes (e.g. if used to escape)', () => { | ||
const input = getMigrationName(`'foo/bar/001_testing.py'`); | ||
expect(input).toBe(`'001_testing'`); | ||
const [app, migration] = getMigrationName(`'foo/migrations/001_testing.py'`, 'notused'); | ||
expect(migration).toBe(`'001_testing'`); | ||
expect(app).toBe('foo'); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,38 @@ | ||
export function getMigrationName(name: string): string { | ||
const pathRegex = /([']?)(.*?)([']?)$/; | ||
type MigrationName = [appLabel: string, name: string]; | ||
|
||
const matches = name.trim().match(pathRegex); | ||
export function getMigrationName(name: string, fallbackApp: string): MigrationName { | ||
const parts = name.split('/'); | ||
const relevantParts = parts.slice(-3); | ||
|
||
if (!matches) { | ||
return ''; | ||
// Not enough paths segments to determine the app name. | ||
if (relevantParts.length < 3) { | ||
const migrationName = stripExtension(relevantParts.pop() ?? ''); | ||
return [fallbackApp, migrationName]; | ||
} | ||
|
||
const [, startQuote, path, endQuote] = matches; | ||
const migrationName = stripExtension(relevantParts.pop() ?? ''); | ||
let appName = fallbackApp; | ||
if (relevantParts[relevantParts.length - 1] === 'migrations') { | ||
appName = relevantParts[relevantParts.length - 2] ?? fallbackApp; | ||
} else { | ||
appName = relevantParts.pop() ?? fallbackApp; | ||
} | ||
if (appName && appName.startsWith("'")) { | ||
appName = appName.slice(1); | ||
} | ||
|
||
return [appName, migrationName]; | ||
} | ||
|
||
const quotePattern = /(.*?)([']?)$/; | ||
|
||
function stripExtension(name: string): string { | ||
const matches = name.trim().match(quotePattern); | ||
if (!matches) { | ||
return name; | ||
} | ||
let [, migration, quote] = matches; | ||
migration = migration.replace('.py', ''); | ||
|
||
return `${startQuote}${path | ||
.split('/') | ||
.slice(-1)[0] | ||
.replace('.py', '')}${endQuote}`; | ||
return `${quote}${migration}${quote}`; | ||
} |