-
-
Notifications
You must be signed in to change notification settings - Fork 229
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ automatically migrate outdated configs
- Loading branch information
1 parent
3ab39cb
commit 110e76b
Showing
9 changed files
with
246 additions
and
26 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
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
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
53 changes: 53 additions & 0 deletions
53
packages/@ourworldindata/grapher/src/schema/migrations/helpers.ts
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 |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { | ||
currentSchemaVersion, | ||
outdatedSchemaVersions, | ||
} from "../defaultGrapherConfig" | ||
|
||
const allSchemaVersions = [...outdatedSchemaVersions, currentSchemaVersion] | ||
|
||
type CurrentSchemaVersion = typeof currentSchemaVersion | ||
type OutdatedSchemaVersion = (typeof outdatedSchemaVersions)[number] | ||
type SchemaVersion = OutdatedSchemaVersion | CurrentSchemaVersion | ||
|
||
type Schema = | ||
`https://files.ourworldindata.org/schemas/grapher-schema.${SchemaVersion}.json` | ||
|
||
// we can't type configs that don't adhere to the latest schema as we don't know what they look like | ||
export type AnyConfig = Record<string, any> | ||
export type AnyConfigWithSchema = Record<string, any> & { | ||
$schema?: Schema | ||
} | ||
|
||
const schemaVersionRegex = | ||
/https:\/\/files\.ourworldindata\.org\/schemas\/grapher-schema\.(?<version>\d{3})\.json/m | ||
|
||
const isValidSchemaVersion = (version: string): version is SchemaVersion => | ||
allSchemaVersions.includes(version as any) | ||
|
||
export function getSchemaVersion(config: AnyConfigWithSchema): SchemaVersion | ||
export function getSchemaVersion(config: AnyConfig): SchemaVersion | null { | ||
const version = config.$schema?.match(schemaVersionRegex)?.groups?.version | ||
if (!version || !isValidSchemaVersion(version)) return null | ||
return version | ||
} | ||
|
||
export function createSchemaForVersion(version: SchemaVersion): Schema { | ||
return `https://files.ourworldindata.org/schemas/grapher-schema.${version}.json` | ||
} | ||
|
||
export const isLatestVersion = (version: SchemaVersion) => | ||
version === currentSchemaVersion | ||
|
||
export const isOutdatedVersion = (version: SchemaVersion) => | ||
outdatedSchemaVersions.includes(version as any) | ||
|
||
export const isSchemaMissing = (config: AnyConfigWithSchema) => | ||
config.$schema === undefined | ||
|
||
export const isSchemaOutdated = ( | ||
config: AnyConfig | ||
): config is AnyConfigWithSchema => { | ||
const version = getSchemaVersion(config) | ||
if (!version) return false | ||
return isOutdatedVersion(version) | ||
} |
44 changes: 44 additions & 0 deletions
44
packages/@ourworldindata/grapher/src/schema/migrations/migrate.ts
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 |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { GrapherInterface } from "@ourworldindata/types" | ||
import { | ||
getSchemaVersion, | ||
isLatestVersion, | ||
isSchemaMissing, | ||
type AnyConfig, | ||
type AnyConfigWithSchema, | ||
} from "./helpers" | ||
import { runMigration } from "./migrations" | ||
import { defaultGrapherConfig } from "../defaultGrapherConfig" | ||
import { isSchemaOutdated } from "./helpers" | ||
|
||
const recursivelyUpgradeConfigToNextSchemaVersion = ( | ||
config: AnyConfigWithSchema | ||
): AnyConfigWithSchema => { | ||
const version = getSchemaVersion(config) | ||
if (isLatestVersion(version)) return config | ||
return recursivelyUpgradeConfigToNextSchemaVersion(runMigration(config)) | ||
} | ||
|
||
const migrateToLatestSchemaVersion = ( | ||
config: AnyConfigWithSchema | ||
): GrapherInterface => | ||
recursivelyUpgradeConfigToNextSchemaVersion(config) as GrapherInterface | ||
|
||
export const makeConfigValidAgainstLatestSchema = (config: AnyConfig) => { | ||
// the config adheres to the latest schema | ||
if (config.$schema === defaultGrapherConfig.$schema) return config | ||
|
||
// if the schema field is missing, assume it's the latest version | ||
// TODO: remove? | ||
if (isSchemaMissing(config)) { | ||
config.$schema = defaultGrapherConfig.$schema | ||
return config | ||
} | ||
|
||
// if the schema version is outdated, migrate it to the latest version | ||
if (isSchemaOutdated(config)) { | ||
return migrateToLatestSchemaVersion(config) | ||
} | ||
|
||
// else, the schema is invalid | ||
throw new Error(`Invalid schema: ${config.$schema}`) | ||
} |
71 changes: 71 additions & 0 deletions
71
packages/@ourworldindata/grapher/src/schema/migrations/migrations.ts
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 |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { match } from "ts-pattern" | ||
import { | ||
type AnyConfigWithSchema, | ||
createSchemaForVersion, | ||
getSchemaVersion, | ||
isLatestVersion, | ||
} from "./helpers" | ||
|
||
// | ||
// schema migrations | ||
// | ||
// add a migration if introducing a breaking change. | ||
// make sure to update the $schema field to the next version! | ||
// | ||
|
||
// see https://github.com/owid/owid-grapher/commit/26f2a0d1790c71bdda7e12f284ca552945d2f6ef | ||
const migrateFrom001To002 = ( | ||
config: AnyConfigWithSchema | ||
): AnyConfigWithSchema => { | ||
delete config.selectedData | ||
config.$schema = createSchemaForVersion("002") | ||
return config | ||
} | ||
|
||
// see https://github.com/owid/owid-grapher/commit/4525ad81fb7064709ffab83677a8b0354b324dfb | ||
const migrateFrom002To003 = ( | ||
config: AnyConfigWithSchema | ||
): AnyConfigWithSchema => { | ||
if (config.hideTitelAnnotation) { | ||
config.hideTitleAnnotations = { | ||
entity: true, | ||
time: true, | ||
change: true, | ||
} | ||
} | ||
delete config.hideTitleAnnotation | ||
|
||
config.$schema = createSchemaForVersion("003") | ||
return config | ||
} | ||
|
||
// see https://github.com/owid/owid-grapher/commit/1776721253cf61d7f1e24ebadeaf7a7ca2f43ced | ||
const migrateFrom003To004 = ( | ||
config: AnyConfigWithSchema | ||
): AnyConfigWithSchema => { | ||
delete config.data | ||
config.$schema = createSchemaForVersion("004") | ||
return config | ||
} | ||
|
||
// see https://github.com/owid/owid-grapher/commit/1d67de3174764a413bc5055fbdf34efb2b49e079 | ||
const migrateFrom004To005 = ( | ||
config: AnyConfigWithSchema | ||
): AnyConfigWithSchema => { | ||
delete config.hideLinesOutsideTolerance | ||
config.$schema = createSchemaForVersion("005") | ||
return config | ||
} | ||
|
||
export const runMigration = ( | ||
config: AnyConfigWithSchema | ||
): AnyConfigWithSchema => { | ||
const version = getSchemaVersion(config) | ||
if (isLatestVersion(version)) return config | ||
return match(version) | ||
.with("001", () => migrateFrom001To002(config)) | ||
.with("002", () => migrateFrom002To003(config)) | ||
.with("003", () => migrateFrom003To004(config)) | ||
.with("004", () => migrateFrom004To005(config)) | ||
.exhaustive() | ||
} |