eirslett / frontend-maven-plugin

"Maven-node-grunt-gulp-npm-node-plugin to end all maven-node-grunt-gulp-npm-plugins." A Maven plugin that downloads/installs Node and NPM locally, runs NPM install, Grunt, Gulp and/or Karma.
Apache License 2.0
4.21k stars 867 forks source link

Proxy options are passed to npx as extra arguments #1030

Open karstenspang opened 2 years ago

karstenspang commented 2 years ago

Do you want to request a feature or report a bug? A bug

What is the current behavior? With proxies specified in maven, the proxy options are passed to npx as file names, i.e. after the --. This is seen in this log snippet on the line 3. The application fails on line 8 when it tries to open a file using the --https-proxy option as file name.

[INFO] --- frontend-maven-plugin:1.12.1:npx (avrodoc) @ myapp ---
[INFO] Found proxies: [http-proxy{protocol='http', host='myproxy.mycompany.com', port=3128, nonProxyHosts='localhost|127.0.0.1|*.mycompany.com'}, https-proxy{protocol='https', host='myproxy.mycompany.com', port=3128, nonProxyHosts='localhost|127.0.0.1|*.mycompany.com'}]
[INFO] Running 'npx @mikaello/avrodoc-plus -i /app/jenkins/gitlab-runner/builds/4zvR6wsn/1/mycompany1/mymodule/target/generated-sources/avsc -o /app/jenkins/gitlab-runner/builds/4zvR6wsn/1/mycompany1/mymodule/target/site/avrodoc.html -- --https-proxy=http://myproxy.mycompany.com:3128 --proxy=http://myproxy.mycompany.com:3128' in /app/jenkins/gitlab-runner/builds/4zvR6wsn/1/mycompany1/mymodule
[INFO] node:fs:585
[INFO]   handleErrorFromBinding(ctx);
[INFO]   ^
[INFO] 
[INFO] Error: ENOENT: no such file or directory, open '/app/jenkins/gitlab-runner/builds/4zvR6wsn/1/mycompany1/mymodule/--https-proxy=http:/myproxy.mycompany.com:3128'
[INFO]     at Object.openSync (node:fs:585:3)
[INFO]     at Object.readFileSync (node:fs:453:35)
[INFO]     at readJSON (file:///app/jenkins/gitlab-runner/builds/4zvR6wsn/1/mycompany1/mymodule/node_modules/@mikaello/avrodoc-plus/src/avrodoc.js:67:13)
[INFO]     at file:///app/jenkins/gitlab-runner/builds/4zvR6wsn/1/mycompany1/mymodule/node_modules/@mikaello/avrodoc-plus/src/avrodoc.js:30:20
[INFO]     at Array.map (<anonymous>)
[INFO]     at createAvroDoc (file:///app/jenkins/gitlab-runner/builds/4zvR6wsn/1/mycompany1/mymodule/node_modules/@mikaello/avrodoc-plus/src/avrodoc.js:29:6)
[INFO]     at file:///app/jenkins/gitlab-runner/builds/4zvR6wsn/1/mycompany1/mymodule/node_modules/@mikaello/avrodoc-plus/src/cli.js:96:1
[INFO]     at ModuleJob.run (node:internal/modules/esm/module_job:195:25)
[INFO]     at async Promise.all (index 0)
[INFO]     at async ESMLoader.import (node:internal/modules/esm/loader:337:24) {
[INFO]   errno: -2,
[INFO]   syscall: 'open',
[INFO]   code: 'ENOENT',
[INFO]   path: '/app/jenkins/gitlab-runner/builds/4zvR6wsn/1/mycompany1/mymodule/--https-proxy=http:/myproxy.mycompany.com:3128'
[INFO] }

If the current behavior is a bug, please provide the steps to reproduce. In your ~/.m2/settings.xml file, set up proxies like

  <proxies>
   <proxy>
      <id>http-proxy</id>
      <active>true</active>
      <protocol>http</protocol>
      <host>myproxy.mycompany.com</host>
      <port>3128</port>
      <nonProxyHosts>localhost|127.0.0.1|*.mycompany.com</nonProxyHosts>
    </proxy>
   <proxy>
      <id>https-proxy</id>
      <active>true</active>
      <protocol>https</protocol>
      <host>myproxy.mycompany.com</host>
      <port>3128</port>
      <nonProxyHosts>localhost|127.0.0.1|*.mycompany.com</nonProxyHosts>
    </proxy>
  </proxies>

In your pom.xml specify

    </pluginManagement>
      </plugins>
        <plugin>
          <groupId>com.github.eirslett</groupId>
          <artifactId>frontend-maven-plugin</artifactId>
          <version>1.12.1</version>
        </plugin>
      </plugins>
    </pluginManagement>
...
     <plugins>
      <plugin>
        <groupId>com.github.eirslett</groupId>
        <artifactId>frontend-maven-plugin</artifactId>
        <executions>
          <execution>
            <!-- optional: you don't really need execution ids, but it looks nice in your build log. -->
            <id>install node and npm</id>
            <goals>
                <goal>install-node-and-npm</goal>
            </goals>
            <!-- optional: default phase is "generate-resources" -->
            <phase>pre-site</phase>
          </execution>
          <execution>
            <id>npm install avrodoc</id>
            <goals>
              <goal>npm</goal>
            </goals>
            <!-- optional: default phase is "generate-resources" -->
            <phase>pre-site</phase>
            <configuration>
              <arguments>install @mikaello/avrodoc-plus</arguments>
            </configuration>
          </execution>
          <execution>
            <id>avrodoc</id>
            <goals>
              <goal>npx</goal>
            </goals>
            <phase>pre-site</phase>
            <configuration>
              <arguments>@mikaello/avrodoc-plus -i ${avsc.dir} -o ${project.build.directory}/site/avrodoc.html</arguments>
            </configuration>
          </execution>
        </executions>
        <configuration>
          <installDirectory>${project.build.directory}</installDirectory>
          <nodeVersion>v16.14.0</nodeVersion>
        </configuration>
      </plugin>
    </plugins>

What is the expected behavior? The proxy options are passed before the --, or the -- is omitted altogether.

Please mention your frontend-maven-plugin and operating system version. Plugin version is 1.12.1 Output at the start of Maven execution should show it all

Apache Maven 3.8.1 (05c21c65bdfed0f71a2f2ada8b84da59348c4c5d)
Maven home: /opt/maven
Java version: 11.0.12, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-11-openjdk-11.0.12.0.7-0.el7_9.x86_64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-1160.[25](https://gitlab.com/mycompany1/mymodule/-/jobs/xxxxxxxxxx#Lyy).1.el7.x86_64", arch: "amd64", family: "unix"
karstenspang commented 2 years ago

Should have added that the avrodoc-plus application uses the NPM arg package for parsing arguments. arg interprets "options" after -- as extra arguments, and avrodoc-plus interprets extra arguments as file names. Apparently, arguments after -- are not consumed by NPM itself, but rather passed to the application.

karstenspang commented 2 years ago

I see what went wrong. In issue 1005, it was requested to handle such options. But it was done the wrong way in 0e2b66d. These options need to go before the command, like

npm exec --npm-option -- package args...

c.f. npm exec. From npm version 8, it seems that the npx command supports this syntax as well.

123Haynes commented 8 months ago

I just ran into this bug as well.
I agree with @karstenspang. The arguments should be before the package name.
This is also documented by npm:
https://docs.npmjs.com/cli/v8/commands/npm-exec#npx-vs-npm-exec

When run via the npx binary, all flags and options must be set prior to any positional arguments. When run via npm exec, a double-hyphen -- flag can be used to suppress npm's parsing of switches and options that should be sent to the executed command.

mojavelinux commented 3 months ago

I added a reproducible case here: https://github.com/eirslett/frontend-maven-plugin/pull/1120#issuecomment-2051358680