Skip to content

Commit

Permalink
fix(pacmak): TypeError when operating with Worker threads (#2550)
Browse files Browse the repository at this point in the history
This works around isaacs/node-graceful-fs#204, where `graceful-fs`
cannot be loaded from within `Worker` threads. Since the language
generators are loaded in worker threads whenever they are available,
they cannot use `fs-extra` which itself uses `graceful-fs`.
    
This is hopefully a temporary measure, until isaacs/node-graceful-fs#205
is merged & released.

---

By submitting this pull request, I confirm that my contribution is made under the terms of the [Apache 2.0 license].

[Apache 2.0 license]: https://www.apache.org/licenses/LICENSE-2.0
  • Loading branch information
RomainMuller authored Feb 9, 2021
1 parent cf961f0 commit 5822e48
Showing 1 changed file with 47 additions and 20 deletions.
67 changes: 47 additions & 20 deletions packages/jsii-pacmak/lib/targets/go.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CodeMaker } from 'codemaker';
import * as fs from 'fs-extra';
import { promises as fs } from 'fs';
import { Assembly } from 'jsii-reflect';
import { Rosetta } from 'jsii-rosetta';
import * as path from 'path';
Expand Down Expand Up @@ -46,8 +46,19 @@ export class Golang extends Target {

// delete local.go.mod and local.go.sum from the output directory so it doesn't get published
const localGoSum = `${path.basename(localGoMod, '.mod')}.sum`;
await fs.remove(path.join(pkgDir, localGoMod));
await fs.remove(path.join(pkgDir, localGoSum));
await unlink(path.join(pkgDir, localGoMod));
await unlink(path.join(pkgDir, localGoSum));

async function unlink(file: string): Promise<void> {
try {
await fs.unlink(file);
} catch (err) {
// Ignore ENOENT, as this means the file already does not exist
if (err.code !== 'ENOENT') {
throw err;
}
}
}
}

/**
Expand Down Expand Up @@ -78,27 +89,33 @@ export class Golang extends Target {
// local build directory for this module. if
// we do, add a "replace" directive to point to it instead of download from
// the network.
const visit = (pkg: RootPackage) => {
for (const dep of pkg.packageDependencies) {
for (const baseDir of dirs) {
const moduleDir = tryFindLocalModule(baseDir, dep);
if (moduleDir) {
replace[dep.goModuleName] = moduleDir;
}
}

// recurse to transitive deps ("replace" is only considered at the top level go.mod)
visit(dep);
}
const visit = async (pkg: RootPackage): Promise<void> => {
await Promise.all(
pkg.packageDependencies.map(async (dep) => {
await Promise.all(
dirs.map((baseDir) =>
tryFindLocalModule(baseDir, dep).then((moduleDir) => {
if (moduleDir) {
replace[dep.goModuleName] = moduleDir;
}
}),
),
);
// recurse to transitive deps ("replace" is only considered at the top level go.mod)
return visit(dep);
}),
);
};

visit(this.goGenerator.rootPackage);
await visit(this.goGenerator.rootPackage);

// write `local.go.mod`

// read existing content
const goMod = path.join(pkgDir, GOMOD_FILENAME);
const lines = (await fs.readFile(goMod, 'utf-8')).split('\n');
const lines = await fs
.readFile(goMod, 'utf8')
.then((text) => text.split('\n'));

for (const [from, to] of Object.entries(replace)) {
logging.info(`Local replace: ${from} => ${to}`);
Expand Down Expand Up @@ -185,14 +202,24 @@ class GoGenerator implements IGenerator {
* @param baseDir the `dist/go` directory
* @returns `undefined` if not or the module directory otherwise.
*/
function tryFindLocalModule(baseDir: string, pkg: RootPackage) {
async function tryFindLocalModule(baseDir: string, pkg: RootPackage) {
const gomodPath = path.join(baseDir, pkg.packageName, GOMOD_FILENAME);
if (!fs.pathExistsSync(gomodPath)) {
if (
!(await fs.stat(gomodPath).then(
() => true, // File exists - we could stat it!
(err) =>
err.code === 'ENOENT'
? false // ENOENT means the file does not exist...
: Promise.reject(err), // Re-throw the error!
))
) {
return undefined;
}

// read `go.mod` and check that it is for the correct module
const gomod = fs.readFileSync(gomodPath, 'utf-8').split('\n');
const gomod = await fs
.readFile(gomodPath, 'utf8')
.then((text) => text.split('\n'));
const isExpectedModule = gomod.find(
(line) => line.trim() === `module ${pkg.goModuleName}`,
);
Expand Down

0 comments on commit 5822e48

Please sign in to comment.