Skip to content

Commit

Permalink
feat: generating a shrinkwrap-ish on workspaces
Browse files Browse the repository at this point in the history
  • Loading branch information
jsantos98 committed Mar 12, 2024
1 parent 33eb6d6 commit 5d03e4e
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 2 deletions.
2 changes: 2 additions & 0 deletions generators/packagePacker/inversify.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Log } from "./processors/log";
import { Paths } from "./processors/paths";
import { DriverTemplatesProcessor } from "./processors/driverTemplates";
import { LibraryTemplatesProcessor } from "./processors/libraryTemplates";
import { ShrinkwrapGenerator } from "./processors/shrinkwrapGenerator";


const container = new Container();
Expand All @@ -15,5 +16,6 @@ container.bind<Paths>(TYPES.Paths).to(Paths).inSingletonScope();

container.bind<DriverTemplatesProcessor>(TYPES.Processors.DriverTemplates).to(DriverTemplatesProcessor).inSingletonScope();
container.bind<LibraryTemplatesProcessor>(TYPES.Processors.LibraryTemplates).to(LibraryTemplatesProcessor).inSingletonScope();
container.bind<ShrinkwrapGenerator>(TYPES.Processors.ShrinkwrapGenerator).to(ShrinkwrapGenerator).inSingletonScope();

export { container };
12 changes: 11 additions & 1 deletion generators/packagePacker/packagePacker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { DriverTemplatesProcessor } from "./processors/driverTemplates";
import { LibraryTemplatesProcessor } from "./processors/libraryTemplates";
import { TYPES } from "./types";
import { Paths } from "./processors/paths";
import { Log } from "./processors/log";
import { ShrinkwrapGenerator } from "./processors/shrinkwrapGenerator";

export class PackagePacker {

Expand All @@ -23,6 +25,8 @@ export class PackagePacker {
const debug: boolean = <boolean>options.d || <boolean>options.debug || false;
// let mappedAddons: string | undefined = undefined;

const _logger: Log = container.get<Log>(TYPES.Logger);

console.log(`Using the following settings:`);
console.log(` Source : ${source}`);
console.log(` Destination : ${destination}`);
Expand Down Expand Up @@ -121,7 +125,13 @@ export class PackagePacker {
if (configuration.type !== ComponentType.TasksPackage) {
// Copy necessary files to generate package

this.copyFile("npm-shrinkwrap.json", source, temp);
if (!io.existsSync("npm-shrinkwrap.json")) {
_logger.Warn("npm-shrinkwrap.json file not found. Trying to generate it...");
container.get<ShrinkwrapGenerator>(TYPES.Processors.ShrinkwrapGenerator).process(source, "npm-shrinkwrap.json");
this.copyFile("npm-shrinkwrap.json", source, temp);
} else {
this.copyFile("npm-shrinkwrap.json", source, temp);
}
this.copyFile(".npmignore", source, temp);
this.copyFile(".npmrc", source, temp);
this.copyFile("README.md", source, temp);
Expand Down
125 changes: 125 additions & 0 deletions generators/packagePacker/processors/shrinkwrapGenerator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { Log } from "./log";
import * as io from "fs-extra";
import * as path from "path";
import { inject, injectable } from "inversify";
import { TYPES } from "../types";
import { Paths } from "./paths";

@injectable()
export class ShrinkwrapGenerator {

@inject(TYPES.Logger)
private _logger: Log;

public process(source: string , fileName: string): void {
let lockFilePath = path.join(source, "package-lock.json");
let isWorkspaces = false;
if (!io.existsSync(lockFilePath)) {
this._logger.Warn(`Package Lock file not found. Assuming this environment is using workspaces`);

// Search up to 3 levels up
for (let i = 0; i < 3; i++) {
const levels = [];
for (let j = 0; j <= i; j++) {
levels.push("..");
}

lockFilePath = path.resolve(source, ...levels, "package-lock.json")
if (io.existsSync(lockFilePath)) {
isWorkspaces = true;
break;
}
}
}

if (!io.existsSync(lockFilePath)) {
this._logger.Error(`Unable to find a suitable package lock file in the directory tree!`);
} else {
if (!isWorkspaces) {
this._logger.Info(`Since this is not a workspace environment, copying package-lock.json file as ${fileName}`);
io.copyFileSync(lockFilePath, path.join(source, fileName));
} else {
const packageJsonLocation = path.join(source, "package.json");
this._logger.Info(`Reading original package from '${packageJsonLocation}'`);
const packageJson = io.readJSONSync(packageJsonLocation);
this._logger.Info(`Reading lock file from '${lockFilePath}'`);
const lockJson = io.readJSONSync(lockFilePath);

// now, cleanup the file
const prefix = source.slice(path.dirname(lockFilePath).length + 1).replace("\\", "/");

let dependencies: string[] = [];
for (const key in packageJson.dependencies ?? {}) {
dependencies.push(key);
}
for (const key in packageJson.peerDependencies ?? {}) {
dependencies.push(key);
}

// Reprocess the important packages (@criticalmanufacturing/);
for(const dep of dependencies) {
if (dep.startsWith("@criticalmanufacturing/")) {
const importantPack = this.searchImportantPackage(lockJson.packages ?? {}, dep);
for (const key in importantPack.dependencies ?? {}) {
dependencies.push(key);
}
for (const key in importantPack.peerDependencies ?? {}) {
dependencies.push(key);
}
}
}

// Remove duplicates
dependencies = dependencies.filter((item, index) => dependencies.indexOf(item) === index);

const result: any = {};

// First add all entries that match the same name of this path
for (const key in lockJson.packages) {
if (key.startsWith(prefix)) {
result[key] = lockJson.packages[key];
}
}

dependencies.forEach((pack) => {
this._logger.Info(` Adding resolved package information for '${pack}'`);
const results = this.searchPackage(lockJson.packages ?? {}, pack);
for (const key in results) {
result[key] = results[key];
}
});


this._logger.Info(`Generating '${fileName}' file with relevant dependencies information for this package`)
io.writeJSONSync(path.join(source, fileName), {
name: packageJson.name,
version: packageJson.version,
packages: result
}, {
spaces: 2
});
}
}
}

private searchPackage(full: any, search: string): any {
const result: any = {};
for (const key in full) {
if (key === ("node_modules/" + search) || key.startsWith("node_modules/" + search + "/") || full[key].name === search) {
result[key] = full[key]
}
}

return (result);
}

private searchImportantPackage(full: any, search: string): any {
for (const key in full) {
if (full[key].name === search) {
return (full[key]);
}
}

return ({});
}
}
1 change: 1 addition & 0 deletions generators/packagePacker/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export const TYPES = {
Processors: {
DriverTemplates: Symbol("DriverTemplatesProcessor"),
LibraryTemplates: Symbol("LibraryTemplatesProcessor"),
ShrinkwrapGenerator: Symbol("ShrinkwrapGenerator"),
}
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@criticalmanufacturing/generator-iot",
"version": "10.2.7",
"version": "10.2.9",
"description": "Connect IoT Scaffolding",
"files": [
"generators/*.js",
Expand Down

0 comments on commit 5d03e4e

Please sign in to comment.