Skip to content

🧩 moonrepo plugin assumes commands are strings #1228

@airtonix

Description

@airtonix

Discuss anything related to Knip

  1. installed knip
  2. described a monorepo config
  3. run knip...
  4. get error
something something something command.replace is not a function.

so i dived into the file with the error and discovered that your monorepo code assumes that all your plugins return commands to run as strings.

yet your tsc plugin returns the command to run as an array of strings.

Image

if i patch your project (using yarn patch) with

diff --git a/dist/plugins/moonrepo/index.js b/dist/plugins/moonrepo/index.js
index b477ddb7ba3e45cd05d0f010a74bb41d0a312081..621155266e87930d0bf5796f1b0924a1453ef27e 100644
--- a/dist/plugins/moonrepo/index.js
+++ b/dist/plugins/moonrepo/index.js
@@ -5,15 +5,30 @@ const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
 const isRootOnly = true;
 const config = ['moon.yml', '.moon/tasks.yml', '.moon/tasks/*.yml'];
 const resolveConfig = async (config, options) => {
+    const workspaceRootReplacer = createRecursiveReplace('$workspaceRoot', options.rootCwd);
+    const projectRootReplacer = createRecursiveReplace('$projectRoot', options.cwd);
+    
     const tasks = config.tasks ? Object.values(config.tasks) : [];
     const inputs = tasks
         .map(task => task.command)
         .filter(command => command)
-        .map(command => command.replace('$workspaceRoot', options.rootCwd))
-        .map(command => command.replace('$projectRoot', options.cwd))
+        .map(workspaceRootReplacer)
+        .map(projectRootReplacer)
         .flatMap(command => options.getInputsFromScripts(command));
     return [...inputs];
 };
+
+function createRecursiveReplace(search, replacement) {
+    return (stringOrArrayOfStrings) => {
+        if (Array.isArray(stringOrArrayOfStrings)) {
+            return stringOrArrayOfStrings.map(createRecursiveReplace(search, replacement));
+        }
+        if (typeof stringOrArrayOfStrings === 'string') {
+            return stringOrArrayOfStrings.replace(search, replacement);
+        }
+        return stringOrArrayOfStrings;
+    };
+}
 export default {
     title,
     enablers,

then it works.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions