Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): forward string array arguments #27761

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ThePlenkov
Copy link
Contributor

Original discussion:
#27760

Current Behavior

Currently if I create a task like:

{
  "targets": {
    "build-cds": {
      "options": {
        "schema": "SCHEMA_NAME ",
        "filter": [
          "TABLE1",
          "TABLE1"
        ]
      }
    } 
  }
}

it will still call my command like: mycommand --schema SCHEMA_NAME

Expected Behavior

After my change it would run mycommand --schema SCHEMA_NAME --filter=TABLE1,TABLE2,TABLE3

@ThePlenkov ThePlenkov requested a review from a team as a code owner September 4, 2024 11:50
Copy link

vercel bot commented Sep 4, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Skipped Deployment
Name Status Preview Updated (UTC)
nx-dev ⬜️ Ignored (Inspect) Visit Preview Sep 4, 2024 11:53am

Copy link

nx-cloud bot commented Sep 4, 2024

@ThePlenkov
Copy link
Contributor Author

I have also reached same goal by creating a plugin:

import {
  CreateNodesContextV2,
  createNodesFromFiles,
  CreateNodesV2,
  ProjectConfiguration,
  readJsonFile,
} from "@nx/devkit";
import { dirname } from "path";

interface Options {
  replace?: {
    regex?: string;
    with?: string;
  };
}

export const createNodesV2: CreateNodesV2<Options> = [
  "**/project.json",
  (projectConfigurationFiles, options, context) => {
    return createNodesFromFiles(
      (configFile, options, context) =>
        createNodesInternal(configFile, options, context),
      projectConfigurationFiles,
      options,
      context,
    );
  },
];

function createNodesInternal(
  configFilePath: string,
  options: Options,
  context: CreateNodesContextV2,
) {
  const root = dirname(configFilePath);
  const project = readJsonFile(configFilePath) as ProjectConfiguration;

  for (const targetName in project.targets) {
    const target = project.targets[targetName];
    for (const optionName in target.options) {
      const option = target.options[optionName];
      if (isArrayOfStrings(option)) {
        const targetOptionName = optionName.replace(/\[\]$/, "");
        target.options[targetOptionName] = option.toString();
      }
    }
  }

  return {
    projects: {
      [root]: project,
    },
  };
}

function isArrayOfStrings(arg: unknown): arg is Array<string> {
  if (Array.isArray(arg)) {
    return arg.every((item) => typeof item === "string");
  }
}

And then in configuration something like:

  "targets": {
    "build": {
      "options": {
        "schema": "MY_SCHEMA",
        "filter[]": [
          "Foo",
          "Bar"        
        ]
      }
    },

unfortunately with my apporach I had to introduce these array brackets in the name because simply replacing the value of the target options will not work. There is another core plugin which is reading project.json in the end and replacing plugin generated values with values from the file. So I'm generating two options, one array, another string. Array is ignored, string not.

With the current PR this plugin will not be needed because array will be directly parsed to comma-separated string.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants