Skip to content

Commit e1069c0

Browse files
authored
Merge pull request #2444 from ada-x64/bugs/2-7-migration
Fix 2.7.0 Migration
2 parents 7ec76b5 + 1f37158 commit e1069c0

5 files changed

Lines changed: 145 additions & 73 deletions

File tree

rust/perspective-viewer/src/ts/migrate.ts

Lines changed: 38 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
1111
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
1212

13+
import Semver from "./migrate/semver";
1314
import migrate_0_0_0 from "./migrate/0-0-0";
1415
import migrate_2_6_1 from "./migrate/2-6-1";
16+
import { version as PKG_VERSION } from "@finos/perspective/package.json" assert { type: "json" };
1517

1618
/**
1719
* A migration utility for `@finos/perspective-viewer` and
@@ -57,74 +59,31 @@ import migrate_2_6_1 from "./migrate/2-6-1";
5759
*/
5860
export function convert(
5961
old: Record<string, unknown> | ArrayBuffer | string,
60-
{ warn = true, replace_defaults = false }: PerspectiveConvertOptions = {}
62+
{
63+
warn = true,
64+
verbose = false,
65+
replace_defaults = false,
66+
}: PerspectiveConvertOptions = {}
6167
): Record<string, unknown> | ArrayBuffer | string {
6268
if (typeof old === "object" && !(old instanceof ArrayBuffer)) {
6369
const copy = JSON.parse(JSON.stringify(old));
6470
if ("viewers" in copy && "detail" in copy) {
6571
return migrate_workspace(copy, { warn, replace_defaults });
6672
} else {
67-
return migrate_viewer(copy, false, { warn, replace_defaults });
73+
return migrate_viewer(copy, false, {
74+
warn: verbose ? true : warn,
75+
verbose,
76+
replace_defaults,
77+
});
6878
}
6979
} else {
7080
return old;
7181
}
7282
}
7383

74-
function* null_iter() {
75-
while (true) yield null;
76-
}
77-
export type Semver = {
78-
major: number;
79-
minor: number;
80-
patch: number;
81-
build?: {
82-
major: number;
83-
minor: number;
84-
patch: number;
85-
};
86-
};
87-
// This gets what the semver crate calls major, minor, patch, and build values, but does not capture release.
88-
export function parse_semver(ver: string): Semver {
89-
let regex = /(\d+)\.(\d+)\.(\d+)(\+.+)?/;
90-
let [_ver, major, minor, patch, build_str] = ver.match(regex);
91-
let [_build, build_major, build_minor, build_patch] =
92-
build_str?.match(regex) ?? null_iter();
93-
let build =
94-
build_major && build_minor && build_patch
95-
? {
96-
major: Number(build_major),
97-
minor: Number(build_minor),
98-
patch: Number(build_patch),
99-
}
100-
: null;
101-
return {
102-
major: Number(major),
103-
minor: Number(minor),
104-
patch: Number(patch),
105-
build,
106-
};
107-
}
108-
109-
/**
110-
* Checks if left > right
111-
* @param left
112-
* @param right_str
113-
* @returns
114-
*/
115-
export function cmp_semver(left: Semver, right_str: string) {
116-
let right = parse_semver(right_str);
117-
return (
118-
left.major > right.major ||
119-
(left.major === right.major && left.minor > right.minor) ||
120-
(left.major === right.major &&
121-
left.minor === right.minor &&
122-
left.patch > right.patch)
123-
);
124-
}
125-
12684
type PerspectiveConvertOptions = {
12785
warn?: boolean;
86+
verbose?: boolean;
12887
replace_defaults?: boolean;
12988
};
13089

@@ -166,20 +125,39 @@ function migrate_workspace(old, options) {
166125
* @returns
167126
*/
168127
function migrate_viewer(old, omit_attributes, options) {
169-
old.version = old.version
170-
? parse_semver(old.version)
171-
: parse_semver("0.0.0");
128+
old.version = old.version ? new Semver(old.version) : new Semver("0.0.0");
172129
options.omit_attributes = omit_attributes;
173-
return chain(
130+
// This array details the "next version" in line. It begins with 2.6.1
131+
// and continues until the latest migration. Then, the current package
132+
// version is appended to the end, in case the latest migration
133+
// is older than the latest release. Each migration will shift the array.
134+
// Note that because we will be working with the latest version on master,
135+
// and those versions will need to update from themselves to themselves,
136+
// migration scripts must be idempotent.
137+
options.version_chain = ["2.6.1" /*, "2.7.0", etc. */];
138+
options.version_chain.push(PKG_VERSION);
139+
let res = chain(
174140
old,
175-
[migrate_0_0_0, migrate_2_6_1, semver_to_string],
141+
[migrate_0_0_0, migrate_2_6_1, assure_latest, semver_to_string],
176142
options
177143
);
144+
if (options.verbose) {
145+
console.log("Final result -> ", res);
146+
}
147+
return res;
148+
}
149+
150+
function assure_latest(old: { version: Semver }) {
151+
if (old.version.gt(PKG_VERSION)) {
152+
throw new Error("Migrated version is newer than package version!");
153+
} else {
154+
old.version = new Semver(PKG_VERSION);
155+
return old;
156+
}
178157
}
179158

180159
function semver_to_string(old) {
181160
// intentionally ignores build
182-
console.warn(old.version);
183161
old.version = `${old.version.major}.${old.version.minor}.${old.version.patch}`;
184162
return old;
185163
}

rust/perspective-viewer/src/ts/migrate/0-0-0.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
1111
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
1212

13-
import { chain, parse_semver } from "../migrate";
13+
import { chain } from "../migrate";
14+
import Semver from "./semver";
1415

1516
/**
1617
* Migrates all viewer configs older than version 1.0.0.
@@ -20,14 +21,15 @@ import { chain, parse_semver } from "../migrate";
2021
* @returns The migrated viewer.
2122
*/
2223
export default function migrate_0_0_0(old, options) {
23-
if (old.version?.major > 0) {
24+
const next_version = options.version_chain.shift();
25+
if (old.version?.ge(next_version)) {
2426
return old;
2527
} else {
2628
if (options.warn) {
27-
console.warn("Migrating pre-1.0.0 config");
29+
console.warn(`Migrating Legacy -> ${next_version}`);
2830
}
2931
}
30-
return chain(
32+
let res = chain(
3133
old,
3234
[
3335
migrate_group_by,
@@ -43,12 +45,17 @@ export default function migrate_0_0_0(old, options) {
4345
? migrate_attributes_workspace
4446
: migrate_attributes_viewer,
4547
(old) => {
46-
old.version = parse_semver("0.0.0");
48+
old.version = new Semver("0.0.0");
4749
return old;
4850
},
4951
].filter((x) => !!x),
5052
options
5153
);
54+
55+
if (options.verbose) {
56+
console.log(res);
57+
}
58+
return res;
5259
}
5360

5461
/**
@@ -297,7 +304,11 @@ function migrate_plugins(old, options) {
297304
Sunburst: "Sunburst",
298305
};
299306

300-
if ("plugin" in old && old.plugin !== ALIASES[old.plugin]) {
307+
if (
308+
"plugin" in old &&
309+
old.plugin in ALIASES &&
310+
old.plugin !== ALIASES[old.plugin]
311+
) {
301312
old.plugin = ALIASES[old.plugin];
302313
if (options.warn) {
303314
console.warn(

rust/perspective-viewer/src/ts/migrate/2-6-1.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
1111
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
1212

13-
import { cmp_semver, parse_semver } from "../migrate";
13+
import Semver from "./semver";
1414

1515
/**
1616
* Migrates from 2.6.1
@@ -19,12 +19,13 @@ import { cmp_semver, parse_semver } from "../migrate";
1919
* @returns
2020
*/
2121
export default function migrate_2_6_1(old, options) {
22-
if (cmp_semver(old.version, "2.7.0")) {
23-
return;
22+
let next_version = options.version_chain.shift();
23+
if (old.version?.ge(next_version)) {
24+
return old;
2425
} else if (options.warn) {
25-
console.warn("Migrating from 2.6.1");
26+
console.warn(`Migrating 2.6.1 -> ${next_version}`);
2627
}
27-
old.version = parse_semver("2.7.0");
28+
old.version = new Semver(next_version);
2829

2930
// Migrate X/Y Scatter plugin
3031
if (old.plugin === "X/Y Scatter") {
@@ -72,5 +73,8 @@ export default function migrate_2_6_1(old, options) {
7273
}
7374
old.expressions = new_exprs;
7475

76+
if (options.verbose) {
77+
console.log(old);
78+
}
7579
return old;
7680
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2+
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3+
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4+
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5+
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6+
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7+
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
8+
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9+
// ┃ This file is part of the Perspective library, distributed under the terms ┃
10+
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11+
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12+
13+
function* null_iter() {
14+
while (true) yield null;
15+
}
16+
export default class Semver {
17+
major: number;
18+
minor: number;
19+
patch: number;
20+
build?: {
21+
major: number;
22+
minor: number;
23+
patch: number;
24+
};
25+
26+
constructor(ver: string | Semver) {
27+
if (typeof ver !== "string") {
28+
this.major = ver.major;
29+
this.minor = ver.minor;
30+
this.patch = ver.patch;
31+
this.build = ver.build;
32+
return this;
33+
}
34+
35+
let regex = /(\d+)\.(\d+)\.(\d+)(\+.+)?/;
36+
let [_ver, major, minor, patch, build_str] = ver.match(regex);
37+
let [_build, build_major, build_minor, build_patch] =
38+
build_str?.match(regex) ?? null_iter();
39+
let build =
40+
build_major && build_minor && build_patch
41+
? {
42+
major: Number(build_major),
43+
minor: Number(build_minor),
44+
patch: Number(build_patch),
45+
}
46+
: null;
47+
48+
this.major = Number(major);
49+
this.minor = Number(minor);
50+
this.patch = Number(patch);
51+
this.build = build;
52+
return this;
53+
}
54+
55+
gt(val: string | Semver) {
56+
let right = new Semver(val);
57+
return (
58+
this.major > right.major ||
59+
(this.major === right.major && this.minor > right.minor) ||
60+
(this.major === right.major &&
61+
this.minor === right.minor &&
62+
this.patch > right.patch)
63+
);
64+
}
65+
eq(val: string | Semver) {
66+
let right = new Semver(val);
67+
return (
68+
this.major === right.major &&
69+
this.minor == right.minor &&
70+
this.patch == right.patch
71+
);
72+
}
73+
74+
ge(val: string | Semver) {
75+
let right = new Semver(val);
76+
return this.eq(right) || this.gt(right);
77+
}
78+
}

rust/perspective-viewer/tsconfig.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"rootDir": "src/ts",
1010
"allowSyntheticDefaultImports": true,
1111
"moduleResolution": "node",
12-
"skipLibCheck": true
12+
"skipLibCheck": true,
13+
"resolveJsonModule": true
1314
},
14-
"files": ["src/ts/perspective-viewer.ts"],
15+
"files": ["src/ts/perspective-viewer.ts"]
1516
}

0 commit comments

Comments
 (0)