Skip to content

Commit ca0ee64

Browse files
authored
Merge pull request #176 from sass/update-dart-sass-dep
Use Dart Sass and the embedded compiler from HEAD by default
2 parents 587aad9 + 7ce203d commit ca0ee64

File tree

11 files changed

+402
-407
lines changed

11 files changed

+402
-407
lines changed

.github/workflows/ci.yml

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ env:
99

1010
on:
1111
push:
12-
branches: [main]
12+
branches: [main, feature.*]
1313
tags: ['**']
1414
pull_request:
1515

@@ -61,6 +61,8 @@ jobs:
6161
with:
6262
node-version: ${{ matrix.node-version }}
6363
check-latest: true
64+
- uses: frenck/action-setup-yq@v1
65+
with: {version: v4.30.5} # frenck/action-setup-yq#35
6466
- uses: arduino/setup-protoc@v1
6567
with:
6668
version: ${{ env.PROTOC_VERSION }}
@@ -74,25 +76,17 @@ jobs:
7476
with: {repo: sass/embedded-protocol, default-ref: null}
7577

7678
- name: Check out Dart Sass
77-
id: clone-dart-sass
7879
uses: sass/clone-linked-repo@v1
79-
with: {repo: sass/dart-sass, default-ref: null}
80+
with: {repo: sass/dart-sass}
8081

8182
- name: Check out the embedded compiler
8283
uses: sass/clone-linked-repo@v1
83-
with:
84-
repo: sass/dart-sass-embedded
85-
# If we check out a specific version of Dart Sass, always check out
86-
# the embedded compiler as well so we can actually use that Dart Sass
87-
# version.
88-
default-ref: ${{ !steps.clone-dart-sass.skip && 'main' || null }}
84+
with: {repo: sass/dart-sass-embedded}
8985

9086
- name: Link the embedded compiler to Dart Sass
9187
run: |
92-
if [[ -d dart-sass ]]; then
93-
echo "dependency_overrides: {sass: {path: ../dart-sass}}" \
94-
>> dart-sass-embedded/pubspec.yaml
95-
fi
88+
yq -i '.dependency_overrides.sass = {"path": "../dart-sass"}' \
89+
dart-sass-embedded/pubspec.yaml
9690
9791
- name: Check out the JS API definition
9892
uses: sass/clone-linked-repo@v1
@@ -102,8 +96,7 @@ jobs:
10296
- name: npm run init
10397
run: |
10498
if [[ -d embedded-protocol ]]; then args=--protocol-path=embedded-protocol; fi
105-
if [[ -d dart-sass-embedded ]]; then args="$args --compiler-path=dart-sass-embedded"; fi
106-
npm run init -- --api-path=language $args
99+
npm run init -- --compiler-path=dart-sass-embedded --api-path=language $args
107100
108101
- run: npm run test
109102

@@ -132,6 +125,8 @@ jobs:
132125
with: {sdk: stable}
133126
- uses: actions/setup-node@v2
134127
with: {node-version: "${{ matrix.node_version }}"}
128+
- uses: frenck/action-setup-yq@v1
129+
with: {version: v4.30.5} # frenck/action-setup-yq#35
135130
- uses: arduino/setup-protoc@v1
136131
with:
137132
version: ${{ env.PROTOC_VERSION }}
@@ -142,25 +137,17 @@ jobs:
142137
with: {repo: sass/embedded-protocol, default-ref: null}
143138

144139
- name: Check out Dart Sass
145-
id: clone-dart-sass
146140
uses: sass/clone-linked-repo@v1
147-
with: {repo: sass/dart-sass, default-ref: null}
141+
with: {repo: sass/dart-sass}
148142

149143
- name: Check out the embedded compiler
150144
uses: sass/clone-linked-repo@v1
151-
with:
152-
repo: sass/dart-sass-embedded
153-
# If we check out a specific version of Dart Sass, always check out
154-
# the embedded compiler as well so we can actually use that Dart Sass
155-
# version.
156-
default-ref: ${{ !steps.clone-dart-sass.skip && 'main' || null }}
145+
with: {repo: sass/dart-sass-embedded}
157146

158147
- name: Link the embedded compiler to Dart Sass
159148
run: |
160-
if [[ -d dart-sass ]]; then
161-
echo "dependency_overrides: {sass: {path: ../dart-sass}}" \
162-
>> dart-sass-embedded/pubspec.yaml
163-
fi
149+
yq -i '.dependency_overrides.sass = {"path": "../dart-sass"}' \
150+
dart-sass-embedded/pubspec.yaml
164151
165152
- name: Check out the JS API definition
166153
uses: sass/clone-linked-repo@v1
@@ -170,8 +157,7 @@ jobs:
170157
- name: npm run init
171158
run: |
172159
if [[ -d embedded-protocol ]]; then args=--protocol-path=embedded-protocol; fi
173-
if [[ -d dart-sass-embedded ]]; then args="$args --compiler-path=dart-sass-embedded"; fi
174-
npm run init -- --api-path=language $args
160+
npm run init -- --compiler-path=dart-sass-embedded --api-path=language $args
175161
176162
- name: Check out sass-spec
177163
uses: sass/clone-linked-repo@v1

CONTRIBUTING.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,74 @@ such, manual commits should never:
3535

3636
* Update the `package.json`'s `"compiler-version"` field to a non-`-dev` number.
3737
Changing it from non-`-dev` to dev when using a new feature is fine.
38+
39+
# Keeping in Sync With Other Packages
40+
41+
The embedded host depends on several different components which come from
42+
different repositories:
43+
44+
* The [Dart Sass embedded compiler].
45+
* [Dart Sass] (transitively through the embedded compiler).
46+
* The [Sass embedded protocol].
47+
* The [Sass JS API definition].
48+
49+
[Dart Sass embedded compiler]: https://github.com/sass/dart-sass-embedded
50+
[Dart Sass]: https://github.com/sass/dart-sass
51+
[Sass embedded protocol]: https://github.com/sass/embedded-protocol
52+
[JS API definition]: https://github.com/sass/sass/tree/main/spec/js-api
53+
54+
These dependencies are made available in different ways depending on context.
55+
56+
## Local Development
57+
58+
When developing locally, you can download all of these dependencies by running
59+
`npm run init`. This provides the following options for `compiler` (for the
60+
embedded compiler), `protocol` (for the embedded protocol), and `api` (for the
61+
JS API):
62+
63+
* `--<type>-path`: The local filesystem path of the package to use. This is
64+
useful when doing local development on both the host and its dependencies at
65+
the same time.
66+
67+
* `--<type>-ref`: A Git reference for the GitHub repository of the package to
68+
clone.
69+
70+
By default:
71+
72+
* This uses the version of the embedded protocol and compiler specified by
73+
`protocol-version` in `package.json`, *unless* that version ends in `-dev` in
74+
which case it checks out the latest revision on GitHub.
75+
76+
* This uses the embedded compiler version and JS API definition from the latest
77+
revision on GitHub.
78+
79+
* This uses the Dart Sass version from the latest revision on GitHub, unless the
80+
embedded `--compiler-path` was passed in which case it uses whatever version
81+
of Dart Sass that package references.
82+
83+
## Continuous Integration
84+
85+
CI tests also use `npm run init`, so they use the same defaults as local
86+
development. However, if the pull request description includes a link to a pull
87+
request for the embedded compiler, Dart Sass, the embedded protocol, or the JS
88+
API, this will check out that version and run tests against it instead.
89+
90+
## Release
91+
92+
When this package is released to npm, it downloads the embedded protocol version
93+
that matches `protocol-version` in `package.json`. It downloads the latest JS
94+
API revision on GitHub.
95+
96+
The release version of the `sass-embedded` package does *not* include the
97+
embedded compiler or Dart Sass. Instead, we release optional packages of the
98+
form `sass-embedded-<os>-<arch>`. Each of these contains the published version
99+
of the embedded compiler that matches `compiler-version` in `package.json` for
100+
the given operating system/architecture combination.
101+
102+
If either `protocol-version` or `compiler-version` ends with `-dev`, the release
103+
will fail.
104+
105+
**Note:** As part of the holistic release process for Dart Sass, the embedded
106+
compiler's CI will automatically update this repository's `package.json` file
107+
with the latest `compiler-version` and optional dependency versions before
108+
tagging it for a release.

lib/src/legacy/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ function convertOptions<sync extends 'sync' | 'async'>(
131131
// does not.
132132
if (!signature.includes('(')) signature += '()';
133133

134-
functions[signature] = wrapFunction(self, callback, sync);
134+
functions[signature.trimLeft()] = wrapFunction(self, callback, sync);
135135
}
136136

137137
const importers =

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "sass-embedded",
33
"version": "1.56.2",
44
"protocol-version": "1.1.0",
5-
"compiler-version": "1.56.2",
5+
"compiler-version": "1.56.3-dev",
66
"description": "Node.js library that communicates with Embedded Dart Sass using the Embedded Sass protocol",
77
"repository": "sass/embedded-host-node",
88
"author": "Google Inc.",
@@ -16,7 +16,7 @@
1616
"node": ">=14.0.0"
1717
},
1818
"scripts": {
19-
"init": "ts-node ./tool/prepare-dev-environment.ts",
19+
"init": "ts-node ./tool/init.ts",
2020
"check": "npm-run-all check:gts check:tsc",
2121
"check:gts": "gts check",
2222
"check:tsc": "tsc --noEmit",

tool/get-embedded-compiler.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2022 Google Inc. 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 {promises as fs} from 'fs';
6+
import * as p from 'path';
7+
import * as yaml from 'yaml';
8+
import * as shell from 'shelljs';
9+
10+
import * as utils from './utils';
11+
12+
/**
13+
* Downlaods and builds the Embedded Dart Sass compiler.
14+
*
15+
* Can check out and build the source from a Git `ref` or build from the source
16+
* at `path`. By default, checks out the latest revision from GitHub.
17+
*/
18+
export async function getEmbeddedCompiler(
19+
outPath: string,
20+
options?: {ref: string} | {path: string}
21+
): Promise<void> {
22+
const repo = 'dart-sass-embedded';
23+
24+
let source: string;
25+
if (!options || 'ref' in options) {
26+
utils.fetchRepo({
27+
repo,
28+
outPath: utils.BUILD_PATH,
29+
ref: options?.ref ?? 'main',
30+
});
31+
source = p.join(utils.BUILD_PATH, repo);
32+
await maybeOverrideSassDependency(source);
33+
} else {
34+
source = options.path;
35+
}
36+
37+
buildDartSassEmbedded(source);
38+
await utils.link(p.join(source, 'build'), p.join(outPath, repo));
39+
}
40+
41+
/**
42+
* Overrides Embedded Dart Sass compiler's dependency on Dart Sass to use the
43+
* latest version of Dart Sass from the `main` branch.
44+
*
45+
* This allows us to avoid needing to commit a dependency override to the
46+
* embedded compiler when it doesn't actually require any local changes.
47+
*/
48+
async function maybeOverrideSassDependency(repo: string): Promise<void> {
49+
const pubspecPath = p.join(repo, 'pubspec.yaml');
50+
const pubspec = yaml.parse(
51+
await fs.readFile(pubspecPath, {encoding: 'utf-8'})
52+
);
53+
54+
console.log(`Overriding ${repo} to load Dart Sass from HEAD.`);
55+
56+
pubspec['dependency_overrides'] = {
57+
...pubspec['dependency_overrides'],
58+
sass: {git: 'https://github.com/sass/dart-sass.git'},
59+
};
60+
await fs.writeFile(pubspecPath, yaml.stringify(pubspec), {encoding: 'utf-8'});
61+
}
62+
63+
// Builds the Embedded Dart Sass executable from the source at `repoPath`.
64+
function buildDartSassEmbedded(repoPath: string): void {
65+
console.log('Downloading dart-sass-embedded dependencies.');
66+
shell.exec('dart pub upgrade', {
67+
cwd: repoPath,
68+
silent: true,
69+
});
70+
71+
console.log('Building dart-sass-embedded executable.');
72+
shell.exec('dart run grinder protobuf pkg-standalone-dev', {
73+
cwd: repoPath,
74+
silent: true,
75+
});
76+
}

tool/get-embedded-protocol.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright 2022 Google Inc. 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 {mkdirSync} from 'fs';
6+
import * as p from 'path';
7+
import * as shell from 'shelljs';
8+
9+
import * as pkg from '../package.json';
10+
import * as utils from './utils';
11+
12+
/**
13+
* Downloads and builds the Embedded Sass protocol definition.
14+
*
15+
* Can check out and build the source from a Git `ref` or build from the source
16+
* at `path`. By default, checks out the tagged version specified in
17+
* package.json's `protocol-version` field. If this version ends in `-dev`,
18+
* checks out the latest revision from GitHub instead.
19+
*/
20+
export async function getEmbeddedProtocol(
21+
outPath: string,
22+
options?: {ref: string} | {path: string}
23+
): Promise<void> {
24+
const repo = 'embedded-protocol';
25+
26+
let source: string;
27+
if (!options || 'ref' in options) {
28+
let ref = options?.ref;
29+
if (ref === undefined) {
30+
const version = pkg['protocol-version'] as string;
31+
ref = version.endsWith('-dev') ? 'main' : version;
32+
}
33+
34+
utils.fetchRepo({repo, outPath: utils.BUILD_PATH, ref});
35+
source = p.join(utils.BUILD_PATH, repo);
36+
} else {
37+
source = options.path;
38+
}
39+
40+
buildEmbeddedProtocol(source);
41+
await utils.link('build/embedded-protocol', p.join(outPath, repo));
42+
}
43+
44+
// Builds the embedded proto at `repoPath` into a pbjs with TS declaration file.
45+
function buildEmbeddedProtocol(repoPath: string): void {
46+
const proto = p.join(repoPath, 'embedded_sass.proto');
47+
const protocPath =
48+
process.platform === 'win32'
49+
? '%CD%/node_modules/protoc/protoc/bin/protoc.exe'
50+
: 'node_modules/protoc/protoc/bin/protoc';
51+
const version = shell
52+
.exec(`${protocPath} --version`, {silent: true})
53+
.stdout.trim();
54+
console.log(
55+
`Building pbjs and TS declaration file from ${proto} with ${version}.`
56+
);
57+
58+
const pluginPath =
59+
process.platform === 'win32'
60+
? '%CD%/node_modules/.bin/protoc-gen-ts.cmd'
61+
: 'node_modules/.bin/protoc-gen-ts';
62+
mkdirSync('build/embedded-protocol', {recursive: true});
63+
shell.exec(
64+
`${protocPath} \
65+
--plugin="protoc-gen-ts=${pluginPath}" \
66+
--js_out="import_style=commonjs,binary:build/embedded-protocol" \
67+
--ts_out="build/embedded-protocol" \
68+
--proto_path="${repoPath}" \
69+
${proto}`,
70+
{silent: true}
71+
);
72+
}

tool/get-js-api.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2022 Google Inc. 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 p from 'path';
6+
7+
import * as utils from './utils';
8+
9+
/**
10+
* Checks out JS API type definitions from the Sass language repo.
11+
*
12+
* Can check out a Git `ref` or link to the source at `path`. By default, checks
13+
* out the latest revision from GitHub.
14+
*/
15+
export async function getJSApi(
16+
outPath: string,
17+
options?: {ref: string} | {path: string}
18+
): Promise<void> {
19+
const repo = 'sass';
20+
21+
let source: string;
22+
if (!options || 'ref' in options) {
23+
utils.fetchRepo({
24+
repo,
25+
outPath: utils.BUILD_PATH,
26+
ref: options?.ref ?? 'main',
27+
});
28+
source = p.join(utils.BUILD_PATH, repo);
29+
} else {
30+
source = options.path;
31+
}
32+
33+
await utils.link(p.join(source, 'js-api-doc'), p.join(outPath, repo));
34+
}

0 commit comments

Comments
 (0)