Skip to content

Commit 53b7d71

Browse files
committed
feat: support new archive page and rss
1 parent 03d4c2e commit 53b7d71

File tree

6 files changed

+138
-101
lines changed

6 files changed

+138
-101
lines changed

.tool-versions

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
deno 1.31.2
1+
deno 2.0.4
22
nodejs 16.19.1

.vscode/launch.json

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,60 @@
66
"configurations": [
77
{
88
"request": "launch",
9-
"name": "Launch Program",
10-
"type": "pwa-node",
9+
"name": "list --versions",
10+
"type": "node",
1111
"program": "${workspaceFolder}/src/cli.ts",
1212
"cwd": "${workspaceFolder}",
13-
"runtimeExecutable": "deno",
13+
"env": {},
14+
"runtimeExecutable": "/Users/takashi.sakai/.asdf/shims/deno",
1415
"runtimeArgs": [
1516
"run",
1617
"--unstable",
17-
"--inspect",
18+
"--inspect-brk",
1819
"--allow-all"
1920
],
21+
"args": [
22+
"list",
23+
"--versions"
24+
],
25+
"attachSimplePort": 9229
26+
},
27+
{
28+
"request": "launch",
29+
"name": "6000.0.25f1",
30+
"type": "node",
31+
"program": "${workspaceFolder}/src/cli.ts",
32+
"cwd": "${workspaceFolder}",
33+
"env": {},
34+
"runtimeExecutable": "/Users/takashi.sakai/.asdf/shims/deno",
35+
"runtimeArgs": [
36+
"run",
37+
"--unstable",
38+
"--inspect-brk",
39+
"--allow-all"
40+
],
41+
"args": [
42+
"6000.0.25f1"
43+
],
44+
"attachSimplePort": 9229
45+
},
46+
{
47+
"request": "launch",
48+
"name": "--help",
49+
"type": "node",
50+
"program": "${workspaceFolder}/src/cli.ts",
51+
"cwd": "${workspaceFolder}",
52+
"env": {},
53+
"runtimeExecutable": "/Users/takashi.sakai/.asdf/shims/deno",
54+
"runtimeArgs": [
55+
"run",
56+
"--unstable",
57+
"--inspect-brk",
58+
"--allow-all"
59+
],
60+
"args": [
61+
"--help"
62+
],
2063
"attachSimplePort": 9229
2164
}
2265
]

src/cli.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ new Command()
3030
.description("Find Unity changesets.")
3131
.example("unity-changeset 2018.4.36f1", "Get changeset of Unity 2018.4.36f1 ('6cd387d23174' will be output).")
3232
.arguments("<version>")
33-
.action((_, version) => {
34-
getUnityChangeset(version)
33+
.globalOption("--db", "Database url", { default: "https://mob-sakai.github.io/unity-changeset/db" })
34+
.action((options, version) => {
35+
getUnityChangeset(options.db as string, version)
3536
.then((c) => console.log(c.changeset))
3637
.catch(() => {
3738
console.error("The given version was not found.");
@@ -45,16 +46,16 @@ new Command()
4546
"list",
4647
new Command()
4748
.description("List Unity changesets.")
48-
.example("unity-changeset list", "List changesets of the archived versions.")
49+
.globalOption("--db", "Database url", { default: "https://mob-sakai.github.io/unity-changeset/db" })
50+
.example("unity-changeset list", "List changesets.")
4951
.example("unity-changeset list --all --json", "List changesets of all versions in json format.")
5052
.example("unity-changeset list --version-only --min 2018.3 --max 2019.4", "List all versions from 2018.3 to 2019.4.")
5153
.example("unity-changeset list --version-only --grep '(2018.4|2019.4)'", "List all versions in 2018.4 and 2019.4.")
5254
.example("unity-changeset list --lts --latest-patch", "List changesets of the latest patch versions (LTS only).")
5355
// Search options.
5456
.group("Search options")
55-
.option("--archive", "Search archived changesets (default, alpha/beta not included)")
56-
.option("--all", "Search all changesets (alpha/beta included)", { conflicts: ["archive", "pre-release"] })
57-
.option("--pre-release, --beta", "Search only pre-release (alpha/beta) changesets", { conflicts: ["archive", "all"] })
57+
.option("--all", "Search all changesets (alpha/beta included)", { conflicts: ["pre-release"] })
58+
.option("--pre-release, --beta", "Search only pre-release (alpha/beta) changesets", { conflicts: ["all"] })
5859
// Filter options.
5960
.group("Filter options")
6061
.option("--min <version>", "Minimum version (included)")
@@ -79,7 +80,7 @@ new Command()
7980
? SearchMode.All
8081
: options.preRelease
8182
? SearchMode.PreRelease
82-
: SearchMode.Archived;
83+
: SearchMode.Default;
8384

8485
// Group mode.
8586
const groupMode = (options.latestPatch || options.minorVersionOnly)
@@ -89,7 +90,7 @@ new Command()
8990
: GroupMode.All;
9091

9192
// Filter options.
92-
const filterOptions : FilterOptions = {
93+
const filterOptions: FilterOptions = {
9394
min: options.min || "",
9495
max: options.max || "",
9596
grep: options.grep || "",
@@ -105,15 +106,15 @@ new Command()
105106
: options.minorVersionOnly
106107
? OutputMode.MinorVersionOnly
107108
: OutputMode.Changeset;
108-
109+
109110
// Format mode.
110111
const formatMode = options.json
111112
? FormatMode.Json
112113
: options.prettyJson
113114
? FormatMode.PrettyJson
114115
: FormatMode.None;
115116

116-
listChangesets(searchMode, filterOptions, groupMode, outputMode, formatMode)
117+
listChangesets(options.db as string, searchMode, filterOptions, groupMode, outputMode, formatMode)
117118
.then((result) => console.log(result));
118119
}),
119120
)

src/index.ts

Lines changed: 44 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,12 @@ export const UnityChangeset = UnityChangesetClass;
44
export type UnityChangeset = UnityChangesetClass;
55

66
const REGEXP_HUB_LINKS = /unityhub:\/\/\d{4}\.\d+\.\d+(a|b|f)\d+\/\w{12}/g;
7-
const UNITY_ARCHIVE_URL = "https://unity.com/releases/editor/archive";
8-
const UNITY_RSS_URL = "https://unity.com/releases/editor/releases.xml";
9-
const UNITY_BETA_RSS_URL = "https://unity.com/releases/editor/beta/latest.xml";
10-
const UNITY_LTS_RSS_URL = "https://unity.com/releases/editor/lts-releases.xml";
117

128
/*
139
Unity release URLs for each lifecycle.
1410
*/
1511
const UNITY_RELEASE_URLS: { [key: string]: string } = {
12+
"p": "https://unity.com/releases/editor/whats-new/",
1613
"f": "https://unity.com/releases/editor/whats-new/",
1714
"a": "https://unity.com/releases/editor/alpha/",
1815
"b": "https://unity.com/releases/editor/beta/",
@@ -24,70 +21,50 @@ const UNITY_RELEASE_URLS: { [key: string]: string } = {
2421
* @returns An Unity changeset.
2522
*/
2623
export async function getUnityChangeset(
24+
db: string,
2725
version: string,
2826
): Promise<UnityChangeset> {
29-
const match = version.match(/^(\d{4}\.\d+\.\d+)(a|b|f)\d+$/);
27+
let results = await loadDb(db, version);
28+
if (0 < results.length) {
29+
return results[0];
30+
}
31+
32+
const match = version.match(/^(\d\.\d+\.\d+)(a|b|f|p)\d+$/);
3033
const lifecycle = match?.[2] as string;
3134
const releaseUrl = UNITY_RELEASE_URLS[lifecycle];
32-
33-
let results = [];
3435
if (lifecycle == "f") {
3536
const shortVersion = match?.[1] as string;
3637
results = (await getUnityChangesetsFromUrl(releaseUrl + shortVersion))
3738
.filter((c) => c.version === version);
38-
if (0 < results.length) return results[0];
39-
40-
results = (await scrapeArchivedChangesets())
41-
.filter((c) => c.version === version);
42-
if (0 < results.length) return results[0];
4339
} else {
4440
results = (await getUnityChangesetsFromUrl(releaseUrl + version))
4541
.filter((c) => c.version === version);
46-
if (0 < results.length) return results[0];
4742
}
48-
49-
throw new Error(`No changeset found for '${version}'`);
50-
}
5143

52-
/*
53-
* Scrape the archived Unity changesets from Unity archives.
54-
* @returns The Unity changesets.
55-
*/
56-
export function scrapeArchivedChangesets(): Promise<UnityChangeset[]> {
57-
return Promise.all([
58-
getUnityChangesetsFromUrl(UNITY_ARCHIVE_URL),
59-
getUnityChangesetsFromUrl(UNITY_RSS_URL),
60-
getUnityChangesetsFromUrl(UNITY_LTS_RSS_URL),
61-
])
62-
.then((results) => {
63-
const changesets = results[0].concat(results[1]);
64-
const ltsVersons = groupChangesets(results[2], GroupMode.LatestPatch)
65-
.map((c) => c.minor);
66-
const unique = new Set();
44+
if (0 < results.length) {
45+
return results[0];
46+
}
6747

68-
return changesets
69-
.filter((c) => {
70-
const duplicated = unique.has(c.versionNumber);
71-
unique.add(c.versionNumber);
72-
return !duplicated;
73-
})
74-
.map((c) => {
75-
c.lts = ltsVersons.includes(c.minor);
76-
return c;
77-
})
78-
.sort((a, b) => b.versionNumber - a.versionNumber);
79-
});
48+
throw new Error(`No changeset found for '${version}'`);
8049
}
8150

82-
/*
83-
* Scrape the alpha/beta Unity changesets from Unity RSS feed.
84-
* @returns The Unity changesets (alpha/beta).
85-
*/
86-
export function scrapeBetaChangesets(): Promise<UnityChangeset[]> {
87-
return getUnityChangesetsFromUrl(UNITY_BETA_RSS_URL)
88-
.then((results) =>
89-
results.sort((a, b) => b.versionNumber - a.versionNumber)
90-
);
51+
export async function loadDb(
52+
db: string,
53+
version?: string,
54+
): Promise<UnityChangeset[]> {
55+
const response = await fetch(db);
56+
const text = await response.text();
57+
const lines = text.split("\n");
58+
59+
if (version) {
60+
const startsWith = version + "\t";
61+
return lines
62+
.filter((line) => line.startsWith(startsWith))
63+
.map((line) => UnityChangeset.createFromDb(line));
64+
} else {
65+
return lines
66+
.map((line) => UnityChangeset.createFromDb(line));
67+
}
9168
}
9269

9370
function getUnityChangesetsFromUrl(
@@ -110,13 +87,13 @@ function getUnityChangesetsFromUrl(
11087
/*
11188
* Search mode.
11289
*
113-
* All: All the changesets.
114-
* Archived: Only the archived changesets.
115-
* PreRelease: Only the alpha/beta changesets.
90+
* All: All changesets.
91+
* Default: Only non pre-release changesets.
92+
* PreRelease: Only pre-release (alpha/beta) changesets.
11693
*/
11794
export enum SearchMode {
11895
All = 0,
119-
Archived = 2,
96+
Default = 2,
12097
PreRelease = 3,
12198
}
12299

@@ -179,13 +156,14 @@ export enum FormatMode {
179156
}
180157

181158
export function listChangesets(
159+
db: string,
182160
searchMode: SearchMode,
183161
filterOptions: FilterOptions,
184162
groupMode: GroupMode,
185163
outputMode: OutputMode,
186164
formatMode: FormatMode,
187165
): Promise<string> {
188-
return searchChangesets(searchMode)
166+
return searchChangesets(db, searchMode)
189167
.then((results) => filterChangesets(results, filterOptions))
190168
.then((results) => groupChangesets(results, groupMode))
191169
.then((results) => {
@@ -218,20 +196,20 @@ export function listChangesets(
218196
});
219197
}
220198

221-
export function searchChangesets(
199+
export async function searchChangesets(
200+
db: string,
222201
searchMode: SearchMode,
223202
): Promise<UnityChangeset[]> {
203+
const results = await loadDb(db);
224204
switch (searchMode) {
225205
case SearchMode.All:
226-
return Promise.all([
227-
scrapeArchivedChangesets(),
228-
scrapeBetaChangesets(),
229-
])
230-
.then((r) => r.flat());
231-
case SearchMode.Archived:
232-
return scrapeArchivedChangesets();
206+
return results;
207+
case SearchMode.Default:
208+
return results
209+
.filter((c) => !c.preRelease);
233210
case SearchMode.PreRelease:
234-
return scrapeBetaChangesets();
211+
return results
212+
.filter((c) => c.preRelease);
235213
default:
236214
throw Error(`The given search mode '${searchMode}' was not supported`);
237215
}

0 commit comments

Comments
 (0)