Skip to content

Commit 002e847

Browse files
authored
Generate deprecations list from language repo (#300)
1 parent 01ba13b commit 002e847

File tree

5 files changed

+101
-145
lines changed

5 files changed

+101
-145
lines changed

lib/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ export {
4040
Deprecation,
4141
DeprecationOrId,
4242
DeprecationStatus,
43-
Version,
4443
} from './src/deprecations';
44+
export {Version} from './src/version';
4545
export {render, renderSync} from './src/legacy';
4646

4747
export const info = `sass-embedded\t${pkg.version}`;

lib/src/deprecations.ts

Lines changed: 6 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,17 @@
22
// MIT-style license that can be found in the LICENSE file or at
33
// https://opensource.org/licenses/MIT.
44

5-
import * as api from './vendor/sass';
5+
import {deprecations} from './vendor/deprecations';
6+
import {Deprecation, DeprecationOrId} from './vendor/sass';
7+
import {Version} from './version';
68

9+
export {deprecations} from './vendor/deprecations';
710
export {Deprecation, DeprecationOrId, DeprecationStatus} from './vendor/sass';
811

9-
export class Version implements api.Version {
10-
constructor(
11-
readonly major: number,
12-
readonly minor: number,
13-
readonly patch: number
14-
) {}
15-
static parse(version: string): Version {
16-
const match = version.match(/^(\d+)\.(\d+)\.(\d+)$/);
17-
if (match === null) {
18-
throw new Error(`Invalid version ${version}`);
19-
}
20-
return new Version(
21-
parseInt(match[1]),
22-
parseInt(match[2]),
23-
parseInt(match[3])
24-
);
25-
}
26-
}
27-
2812
/**
2913
* Returns whether the given deprecation was active in the given version.
3014
*/
31-
function isActiveIn(deprecation: api.Deprecation, version: Version) {
15+
function isActiveIn(deprecation: Deprecation, version: Version) {
3216
const deprecatedIn = deprecation.deprecatedIn;
3317
if (deprecation.status !== 'active' || !deprecatedIn) return false;
3418
if (version.major > deprecatedIn.major) return true;
@@ -43,7 +27,7 @@ function isActiveIn(deprecation: api.Deprecation, version: Version) {
4327
* that's ready to include in a CompileRequest.
4428
*/
4529
export function getDeprecationIds(
46-
arr: (api.DeprecationOrId | Version)[]
30+
arr: (DeprecationOrId | Version)[]
4731
): string[] {
4832
return arr.flatMap(item => {
4933
if (item instanceof Version) {
@@ -56,125 +40,3 @@ export function getDeprecationIds(
5640
return item.id;
5741
});
5842
}
59-
60-
export const deprecations: typeof api.deprecations = {
61-
'call-string': {
62-
id: 'call-string',
63-
status: 'active',
64-
deprecatedIn: new Version(0, 0, 0),
65-
obsoleteIn: null,
66-
description: 'Passing a string directly to meta.call().',
67-
},
68-
elseif: {
69-
id: 'elseif',
70-
status: 'active',
71-
deprecatedIn: new Version(1, 3, 2),
72-
obsoleteIn: null,
73-
description: '@elseif.',
74-
},
75-
'moz-document': {
76-
id: 'moz-document',
77-
status: 'active',
78-
deprecatedIn: new Version(1, 7, 2),
79-
obsoleteIn: null,
80-
description: '@-moz-document.',
81-
},
82-
'relative-canonical': {
83-
id: 'relative-canonical',
84-
status: 'active',
85-
deprecatedIn: new Version(1, 14, 2),
86-
obsoleteIn: null,
87-
},
88-
'new-global': {
89-
id: 'new-global',
90-
status: 'active',
91-
deprecatedIn: new Version(1, 17, 2),
92-
obsoleteIn: null,
93-
description: 'Declaring new variables with !global.',
94-
},
95-
'color-module-compat': {
96-
id: 'color-module-compat',
97-
status: 'active',
98-
deprecatedIn: new Version(1, 23, 0),
99-
obsoleteIn: null,
100-
description:
101-
'Using color module functions in place of plain CSS functions.',
102-
},
103-
'slash-div': {
104-
id: 'slash-div',
105-
status: 'active',
106-
deprecatedIn: new Version(1, 33, 0),
107-
obsoleteIn: null,
108-
description: '/ operator for division.',
109-
},
110-
'bogus-combinators': {
111-
id: 'bogus-combinators',
112-
status: 'active',
113-
deprecatedIn: new Version(1, 54, 0),
114-
obsoleteIn: null,
115-
description: 'Leading, trailing, and repeated combinators.',
116-
},
117-
'strict-unary': {
118-
id: 'strict-unary',
119-
status: 'active',
120-
deprecatedIn: new Version(1, 55, 0),
121-
obsoleteIn: null,
122-
description: 'Ambiguous + and - operators.',
123-
},
124-
'function-units': {
125-
id: 'function-units',
126-
status: 'active',
127-
deprecatedIn: new Version(1, 56, 0),
128-
obsoleteIn: null,
129-
description: 'Passing invalid units to built-in functions.',
130-
},
131-
'duplicate-var-flags': {
132-
id: 'duplicate-var-flags',
133-
status: 'active',
134-
deprecatedIn: new Version(1, 62, 0),
135-
obsoleteIn: null,
136-
description: 'Using !default or !global multiple times for one variable.',
137-
},
138-
'null-alpha': {
139-
id: 'null-alpha',
140-
status: 'active',
141-
deprecatedIn: new Version(1, 62, 3),
142-
obsoleteIn: null,
143-
description: 'Passing null as alpha in the JS API.',
144-
},
145-
'abs-percent': {
146-
id: 'abs-percent',
147-
status: 'active',
148-
deprecatedIn: new Version(1, 65, 0),
149-
obsoleteIn: null,
150-
description: 'Passing percentages to the Sass abs() function.',
151-
},
152-
'fs-importer-cwd': {
153-
id: 'fs-importer-cwd',
154-
status: 'active',
155-
deprecatedIn: new Version(1, 73, 0),
156-
obsoleteIn: null,
157-
description:
158-
'Using the current working directory as an implicit load path.',
159-
},
160-
'css-function-mixin': {
161-
id: 'css-function-mixin',
162-
status: 'active',
163-
deprecatedIn: new Version(1, 76, 0),
164-
obsoleteIn: null,
165-
description: 'Function and mixin names beginning with --.',
166-
},
167-
import: {
168-
id: 'import',
169-
status: 'future',
170-
deprecatedIn: null,
171-
obsoleteIn: null,
172-
description: '@import rules.',
173-
},
174-
'user-authored': {
175-
id: 'user-authored',
176-
status: 'user',
177-
deprecatedIn: null,
178-
obsoleteIn: null,
179-
},
180-
};

lib/src/version.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2024 Google LLC. Use of this source code is governed by an
2+
// MIT-style license that can be found in the LICENSE file or at
3+
// https://opensource.org/licenses/MIT.
4+
5+
import * as api from './vendor/sass';
6+
7+
export class Version implements api.Version {
8+
constructor(
9+
readonly major: number,
10+
readonly minor: number,
11+
readonly patch: number
12+
) {}
13+
static parse(version: string): Version {
14+
const match = version.match(/^(\d+)\.(\d+)\.(\d+)$/);
15+
if (match === null) {
16+
throw new Error(`Invalid version ${version}`);
17+
}
18+
return new Version(
19+
parseInt(match[1]),
20+
parseInt(match[2]),
21+
parseInt(match[3])
22+
);
23+
}
24+
}

tool/get-deprecations.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Generates the list of deprecations from spec/deprecations.yaml in the
2+
// language repo.
3+
4+
import * as fs from 'fs';
5+
import {parse} from 'yaml';
6+
7+
interface YamlData {
8+
[key: string]: {
9+
description: string;
10+
'dart-sass': {
11+
status: 'active' | 'future' | 'obsolete';
12+
deprecated?: string;
13+
obsolete?: string;
14+
};
15+
};
16+
}
17+
18+
const yamlFile = 'build/sass/spec/deprecations.yaml';
19+
20+
/**
21+
* Converts a version string in the form X.Y.Z to be code calling the Version
22+
* constructor, or null if the string is undefined.
23+
*/
24+
function toVersionCode(version: string | undefined): string {
25+
if (!version) return 'null';
26+
const match = version.match(/^(\d+)\.(\d+)\.(\d+)$/);
27+
if (match === null) {
28+
throw new Error(`Invalid version ${version}`);
29+
}
30+
return `new Version(${match[1]}, ${match[2]}, ${match[3]})`;
31+
}
32+
33+
/**
34+
* Generates the list of deprecations based on the YAML file in the language
35+
* repo.
36+
*/
37+
export async function getDeprecations(outDirectory: string) {
38+
const yamlText = fs.readFileSync(yamlFile, 'utf8');
39+
40+
const deprecations = parse(yamlText) as YamlData;
41+
let tsText =
42+
"import {Deprecations} from './sass';\n" +
43+
"import {Version} from '../version';\n\n" +
44+
'export const deprecations: Deprecations = {\n';
45+
for (const [id, deprecation] of Object.entries(deprecations)) {
46+
const key = id.includes('-') ? `'${id}'` : id;
47+
const dartSass = deprecation['dart-sass'];
48+
tsText +=
49+
` ${key}: {\n` +
50+
` id: '${id}',\n` +
51+
` description: '${deprecation.description}',\n` +
52+
` status: '${dartSass.status}',\n` +
53+
` deprecatedIn: ${toVersionCode(dartSass.deprecated)},\n` +
54+
` obsoleteIn: ${toVersionCode(dartSass.obsolete)},\n` +
55+
' },\n';
56+
}
57+
tsText +=
58+
" 'user-authored': {\n" +
59+
" id: 'user-authored',\n" +
60+
" status: 'user',\n" +
61+
' deprecatedIn: null,\n' +
62+
' obsoleteIn: null,\n' +
63+
' },\n' +
64+
'}\n';
65+
66+
fs.writeFileSync(`${outDirectory}/deprecations.ts`, tsText);
67+
}

tool/init.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import yargs from 'yargs';
66

7+
import {getDeprecations} from './get-deprecations';
78
import {getEmbeddedCompiler} from './get-embedded-compiler';
89
import {getLanguageRepo} from './get-language-repo';
910

@@ -65,6 +66,8 @@ void (async () => {
6566
await getEmbeddedCompiler(outPath);
6667
}
6768
}
69+
70+
await getDeprecations(outPath);
6871
} catch (error) {
6972
console.error(error);
7073
process.exitCode = 1;

0 commit comments

Comments
 (0)