Skip to content

Commit

Permalink
chore(plugin): add dependencies list to context
Browse files Browse the repository at this point in the history
As explained on the issue #124
This commit adds the projects dependencies list on the plugin context

Before:
```typescript
import { hasRubyDependency } from "./dependencies.ts";

const isDependency = await hasRubyDependency(context, "rubocop");
```
At every import and function call the application would go on the
dependencies files(package.json, Pipfile, etc ...) and search for
the requested dependencies. This made the application very slow
in addition to harming the organization of the code with many unnecessary imports.

After:
```typescript
const isDependency = await context.dependencies.includes("rubocop");
```
Now the dependency list is loaded before the introspection and
only need to read the necessary dependencies files once.

Resolves: #124
  • Loading branch information
joao10lima committed Jan 10, 2022
1 parent 279d9be commit bbe6513
Show file tree
Hide file tree
Showing 25 changed files with 120 additions and 751 deletions.
43 changes: 43 additions & 0 deletions cli/src/lib/context/dependencies/javascript.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Context } from "../../../../deps.ts";

const denoDepRegex = /\/\/.*\/(?<DependencyName>.+?)(?=\/|@)/gm;

function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
return value !== null && value !== undefined;
}

export const jsNodeDependency = async (context: Context) => {
const dependencies: string[] = [];

for await (const file of context.files.each("**/package.json")) {
const packageJson = await context.files.readJSON(file.path);

const nodeDeps = packageJson?.dependencies;
if (nodeDeps) {
dependencies.push(...Object.keys(nodeDeps));
}

const nodeDepsDev = packageJson?.devDependencies;
if (nodeDepsDev) {
dependencies.push(...Object.keys(nodeDepsDev));
}
}

return dependencies;
};

export const jsDenoDependency = async (context: Context) => {
for await (const file of await context.files.each("**/deps.ts")) {
const denoDepsText = await context.files.readText(file.path);

const depsDeno: string[] = Array.from(
denoDepsText.matchAll(denoDepRegex),
(match) => !match.groups ? null : match.groups.DependencyName,
).filter(notEmpty);

if (depsDeno) {
return depsDeno;
}
}
return [];
};
3 changes: 3 additions & 0 deletions cli/src/lib/context/dependencies/mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./javascript.ts";
export * from "./python.ts";
export * from "./ruby.ts";
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Context } from "../../../types.ts";
import { Context } from "../../../../deps.ts";

const readDependencyFile = async (context: Context) => {
export const pythonDependency = async (context: Context) => {
const dependencies: string[] = [];

for await (const file of context.files.each("./pyproject.toml")) {
Expand Down Expand Up @@ -42,19 +42,3 @@ const readDependencyFile = async (context: Context) => {

return dependencies;
};

export const hasPythonDependency = async (
context: Context,
dependencyName: string,
): Promise<boolean> => {
const dependencies = await readDependencyFile(context);
return dependencies.some((dep) => dep === dependencyName);
};

export const hasPythonDependencyAny = async (
context: Context,
dependencyList: Set<string>,
): Promise<boolean> => {
const dependencies = await readDependencyFile(context);
return dependencies.some((dep) => dependencyList.has(dep));
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Context } from "../../../types.ts";
import { Context } from "../../../../deps.ts";

const rubyDepRegex = /(?:(["'])(?<DependencyName>[a-zA-Z\-_\.]+)["'])/gm;

function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
return value !== null && value !== undefined;
}

const readDependencyFile = async (context: Context) => {
export const rubyDependency = async (context: Context) => {
for await (const file of await context.files.each("**/Gemfile")) {
const rubyDepsText = await context.files.readText(file.path);

Expand All @@ -21,19 +21,3 @@ const readDependencyFile = async (context: Context) => {
}
return [];
};

export const hasRubyDependency = async (
context: Context,
dependencyName: string,
): Promise<boolean> => {
const dependencies = await readDependencyFile(context);
return dependencies.some((dep) => dep === dependencyName);
};

export const hasRubyDependencyAny = async (
context: Context,
dependencyList: Set<string>,
): Promise<boolean> => {
const dependencies = await readDependencyFile(context);
return dependencies.some((dep) => dependencyList.has(dep));
};
27 changes: 27 additions & 0 deletions cli/src/lib/context/depsIntrospect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Context, introspectors } from "../../../deps.ts";
import {
jsDenoDependency,
jsNodeDependency,
pythonDependency,
rubyDependency,
} from "./dependencies/mod.ts";

type StacksList = ((typeof introspectors)[number]["name"])[];

export async function listDependencies(
stackList: StacksList,
context: Context,
): Promise<string[]> {
for (const stack of stackList) {
switch (stack) {
case "javascript":
return await jsNodeDependency(context) ||
await jsDenoDependency(context);
case "python":
return await pythonDependency(context);
case "ruby":
return await rubyDependency(context);
}
}
return [];
}
1 change: 1 addition & 0 deletions cli/src/lib/context/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const context: Context = {
suggestDefault: true,
strict: true,
version: PIPELINIT_VERSION,
dependencies: [],
};

/**
Expand Down
6 changes: 6 additions & 0 deletions cli/src/lib/introspect.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { introspectors, log, ProjectData } from "../../deps.ts";
import { context } from "./context/mod.ts";
import { listDependencies } from "./context/depsIntrospect.ts";

export type Stack = Record<string, ProjectData>;

Expand Down Expand Up @@ -45,6 +46,11 @@ export async function introspect() {
logger.info(`Detected stack: ${stackNames}`);
}

context.dependencies = await listDependencies(
stack.map((t) => t.name),
context,
);

const introspected = (await Promise.all(
stack.map<Promise<Maybe<ProjectData>>>((introspector) =>
introspector.introspect(context)
Expand Down
103 changes: 0 additions & 103 deletions core/plugins/stack/javascript/dependencies.test.ts

This file was deleted.

77 changes: 0 additions & 77 deletions core/plugins/stack/javascript/dependencies.ts

This file was deleted.

Loading

0 comments on commit bbe6513

Please sign in to comment.