83 | */
84 | public static final String NPM_SETTINGS_REGISTRY = "registry";
85 |
86 | /* since npm 9 each of these entries must be scoped with a registry */
87 | /**
88 | * The authentication base64 string >USER<:>PASSWORD< used to
89 | * login to the global registry.
90 | */
91 | public static final String NPM_SETTINGS_AUTH = "_auth";
92 | /**
93 | * The authentication token used to login to the global registry or scoped
94 | * registry.
95 | */
96 | public static final String NPM_SETTINGS_AUTHTOKEN = "_authToken";
97 | /**
98 | * The user name used to login to the scoped registry.
99 | */
100 | public static final String NPM_SETTINGS_USER = "username";
101 | /**
102 | * The authentication base64 string >PASSWORD< used to
103 | * login to the scoped registry.
104 | */
105 | public static final String NPM_SETTINGS_PASSWORD = "_password";
106 |
107 | }
108 |
--------------------------------------------------------------------------------
/src/main/java/jenkins/plugins/nodejs/NodeJSDescriptorUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs;
25 |
26 | import edu.umd.cs.findbugs.annotations.CheckForNull;
27 | import edu.umd.cs.findbugs.annotations.NonNull;
28 | import edu.umd.cs.findbugs.annotations.Nullable;
29 |
30 | import org.jenkinsci.lib.configprovider.model.Config;
31 | import org.jenkinsci.plugins.configfiles.ConfigFiles;
32 |
33 | import hudson.model.ItemGroup;
34 | import hudson.util.FormValidation;
35 | import hudson.util.ListBoxModel;
36 | import jenkins.plugins.nodejs.configfiles.NPMConfig;
37 | import jenkins.plugins.nodejs.configfiles.NPMConfig.NPMConfigProvider;
38 | import jenkins.plugins.nodejs.configfiles.VerifyConfigProviderException;
39 |
40 | /*package*/ final class NodeJSDescriptorUtils {
41 |
42 | private NodeJSDescriptorUtils() {
43 | }
44 |
45 | /**
46 | * Get all NPMConfig defined for the given context.
47 | *
48 | * @param context the context where lookup the config files
49 | * @return a collection of user npmrc files found for the given context
50 | * always including a system default.
51 | */
52 | @NonNull
53 | public static ListBoxModel getConfigs(@Nullable ItemGroup> context) {
54 | ListBoxModel items = new ListBoxModel();
55 | items.add(Messages.NPMConfig_default(), "");
56 | for (Config config : ConfigFiles.getConfigsInContext(context, NPMConfigProvider.class)) {
57 | items.add(config.name, config.id);
58 | }
59 | return items;
60 | }
61 |
62 | /**
63 | * Verify that the given configId exists in the given context.
64 | *
65 | * @param context where lookup
66 | * @param configId the identifier of an npmrc file
67 | * @return an validation form for the given npmrc file identifier, otherwise
68 | * returns {@code ok} if the identifier does not exists for the
69 | * given context.
70 | */
71 | public static FormValidation checkConfig(@Nullable ItemGroup> context, @CheckForNull String configId) {
72 | if (configId != null) {
73 | Config config = ConfigFiles.getByIdOrNull(context, configId);
74 | if (config != null) {
75 | try {
76 | ((NPMConfig) config).doVerify();
77 | } catch (VerifyConfigProviderException e) {
78 | return FormValidation.error(e.getMessage());
79 | }
80 | }
81 | }
82 | return FormValidation.ok();
83 | }
84 |
85 | }
--------------------------------------------------------------------------------
/src/main/java/jenkins/plugins/nodejs/NodeJSPlugin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco, Frédéric Camblor
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs;
25 |
26 | import hudson.Plugin;
27 | import hudson.model.Items;
28 |
29 | import java.io.IOException;
30 |
31 | import edu.umd.cs.findbugs.annotations.NonNull;
32 | import edu.umd.cs.findbugs.annotations.Nullable;
33 |
34 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
35 | import jenkins.model.Jenkins;
36 | import jenkins.plugins.nodejs.tools.NodeJSInstallation;
37 | import jenkins.plugins.nodejs.tools.NodeJSInstallation.DescriptorImpl;
38 |
39 | /**
40 | * @author fcamblor
41 | * @author Nikolas Falco
42 | * @deprecated Do not use this anymore. This class will be removed, actually is
43 | * kept to migrate persistence.
44 | */
45 | @Deprecated
46 | public class NodeJSPlugin extends Plugin {
47 |
48 | private NodeJSInstallation[] installations;
49 |
50 | @Override
51 | public void start() throws Exception {
52 | super.start();
53 | Items.XSTREAM2.addCompatibilityAlias("jenkins.plugins.nodejs.tools.NpmPackagesBuildWrapper", NodeJSBuildWrapper.class);
54 | Items.XSTREAM2.addCompatibilityAlias("jenkins.plugins.nodejs.NodeJsCommandInterpreter", NodeJSCommandInterpreter.class);
55 | try {
56 | load();
57 | } catch (IOException e) { // NOSONAR
58 | // ignore read XStream errors
59 | }
60 | }
61 |
62 | @SuppressFBWarnings("UWF_NULL_FIELD")
63 | @Override
64 | public void postInitialize() throws Exception {
65 | super.postInitialize();
66 | // If installations have been read in nodejs.xml, let's convert them to
67 | // the default persistence
68 | if (installations != null) {
69 | setInstallations(installations);
70 | getConfigXml().delete();
71 | installations = null;
72 | }
73 | }
74 |
75 | /**
76 | * Get all available NodeJS defined installation.
77 | *
78 | * @return an array of defined {@link NodeJSInstallation}
79 | * @deprecated Use {@link NodeJSUtils#getInstallations()} instead of this.
80 | */
81 | @Deprecated
82 | @NonNull
83 | public NodeJSInstallation[] getInstallations() {
84 | return NodeJSUtils.getInstallations();
85 | }
86 |
87 | @Nullable
88 | public NodeJSInstallation findInstallationByName(@Nullable String name) {
89 | return NodeJSUtils.getNodeJS(name);
90 | }
91 |
92 | /**
93 | * Set the NodeJS installation.
94 | *
95 | * @param installations an array of {@link NodeJSInstallation}
96 | * @deprecated You should not set manually system NodeJS installation, in
97 | * case use the standard
98 | * {@link Jenkins#getDescriptorByType(Class)
99 | * #setInstallations(NodeJSInstallation[])}
100 | */
101 | @Deprecated
102 | public void setInstallations(@NonNull NodeJSInstallation[] installations) {
103 | DescriptorImpl descriptor = Jenkins.getActiveInstance().getDescriptorByType(NodeJSInstallation.DescriptorImpl.class);
104 | if (descriptor != null) {
105 | descriptor.setInstallations(installations != null ? installations : new NodeJSInstallation[0]);
106 | descriptor.save();
107 | }
108 | }
109 |
110 | }
--------------------------------------------------------------------------------
/src/main/java/jenkins/plugins/nodejs/NodeJSUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs;
25 |
26 | import edu.umd.cs.findbugs.annotations.NonNull;
27 | import edu.umd.cs.findbugs.annotations.Nullable;
28 |
29 | import jenkins.model.Jenkins;
30 | import jenkins.plugins.nodejs.tools.NodeJSInstallation;
31 | import jenkins.plugins.nodejs.tools.NodeJSInstallation.DescriptorImpl;
32 |
33 | /*package*/final class NodeJSUtils {
34 |
35 | private NodeJSUtils() {
36 | // default constructor
37 | }
38 |
39 | /**
40 | * Gets the NodeJS to invoke, or null to invoke the default one.
41 | *
42 | * @param name
43 | * the name of NodeJS installation
44 | * @return a NodeJS installation for the given name if exists, {@code null}
45 | * otherwise.
46 | */
47 | @Nullable
48 | public static NodeJSInstallation getNodeJS(@Nullable String name) {
49 | if (name != null) {
50 | for (NodeJSInstallation installation : getInstallations()) {
51 | if (name.equals(installation.getName()))
52 | return installation;
53 | }
54 | }
55 | return null;
56 | }
57 |
58 | /**
59 | * Get all NodeJS installation defined in Jenkins.
60 | *
61 | * @return an array of NodeJS tool installation
62 | */
63 | @NonNull
64 | public static NodeJSInstallation[] getInstallations() {
65 | DescriptorImpl descriptor = Jenkins.get().getDescriptorByType(NodeJSInstallation.DescriptorImpl.class);
66 | if (descriptor == null) {
67 | throw new IllegalStateException("Impossible retrieve NodeJSInstallation descriptor");
68 | }
69 | return descriptor.getInstallations();
70 | }
71 |
72 | }
--------------------------------------------------------------------------------
/src/main/java/jenkins/plugins/nodejs/cache/CacheLocationLocator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2019, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.cache;
25 |
26 | import hudson.ExtensionPoint;
27 | import hudson.FilePath;
28 | import hudson.model.AbstractDescribableImpl;
29 | import edu.umd.cs.findbugs.annotations.NonNull;
30 |
31 | /**
32 | * Strategy pattern that decides the location of the NPM cache location for a
33 | * build.
34 | */
35 | public abstract class CacheLocationLocator extends AbstractDescribableImpl implements ExtensionPoint {
36 |
37 | /**
38 | * Called during the build on the master to determine the location of the
39 | * local cache location.
40 | *
41 | * @param workspace
42 | * the workspace file path locator
43 | * @return null to let NPM uses its default location. Otherwise this must be
44 | * located on the same node as described by this path.
45 | */
46 | public abstract FilePath locate(@NonNull FilePath workspace);
47 |
48 | @Override
49 | public CacheLocationLocatorDescriptor getDescriptor() {
50 | return (CacheLocationLocatorDescriptor) super.getDescriptor();
51 | }
52 |
53 | }
--------------------------------------------------------------------------------
/src/main/java/jenkins/plugins/nodejs/cache/CacheLocationLocatorDescriptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2019, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.cache;
25 |
26 | import hudson.model.Descriptor;
27 |
28 | public class CacheLocationLocatorDescriptor extends Descriptor {
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/jenkins/plugins/nodejs/cache/DefaultCacheLocationLocator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2019, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.cache;
25 |
26 | import hudson.Extension;
27 | import hudson.FilePath;
28 | import edu.umd.cs.findbugs.annotations.NonNull;
29 | import jenkins.plugins.nodejs.Messages;
30 | import org.jenkinsci.Symbol;
31 | import org.kohsuke.stapler.DataBoundConstructor;
32 |
33 | /**
34 | * Uses NPM's default global cache, which is actually {@code ~/.npm} on Unix
35 | * system or {@code %APP_DATA%\npm-cache} on Windows system.
36 | */
37 | public class DefaultCacheLocationLocator extends CacheLocationLocator {
38 |
39 | @DataBoundConstructor
40 | public DefaultCacheLocationLocator() {
41 | }
42 |
43 | @Override
44 | public FilePath locate(@NonNull FilePath workspace) {
45 | return null;
46 | }
47 |
48 | @Extension
49 | @Symbol("default")
50 | public static class DescriptorImpl extends CacheLocationLocatorDescriptor {
51 | @Override
52 | public String getDisplayName() {
53 | return Messages.DefaultCacheLocationLocator_displayName();
54 | }
55 | }
56 |
57 | }
--------------------------------------------------------------------------------
/src/main/java/jenkins/plugins/nodejs/cache/PerExecutorCacheLocationLocator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2019, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.cache;
25 |
26 | import hudson.Extension;
27 | import hudson.FilePath;
28 | import hudson.model.Computer;
29 | import hudson.model.Executor;
30 | import hudson.model.Node;
31 | import edu.umd.cs.findbugs.annotations.NonNull;
32 | import jenkins.plugins.nodejs.Messages;
33 | import org.jenkinsci.Symbol;
34 | import org.kohsuke.stapler.DataBoundConstructor;
35 |
36 | /**
37 | * Relocates the NPM's default cache to a folder specific for the executor in
38 | * the node home folder {@code ~/npm-cache/$executorNumber}.
39 | */
40 | public class PerExecutorCacheLocationLocator extends CacheLocationLocator {
41 |
42 | @DataBoundConstructor
43 | public PerExecutorCacheLocationLocator() {
44 | }
45 |
46 | @Override
47 | public FilePath locate(@NonNull FilePath workspace) {
48 | final Computer computer = workspace.toComputer();
49 | if (computer == null) {
50 | throw new IllegalStateException(Messages.NodeJSBuilders_nodeOffline());
51 | }
52 | final Node node = computer.getNode();
53 | if (node == null) {
54 | throw new IllegalStateException(Messages.NodeJSBuilders_nodeOffline());
55 | }
56 | final FilePath rootPath = node.getRootPath();
57 | final Executor executor = Executor.currentExecutor();
58 | if (rootPath == null || executor == null) {
59 | return null;
60 | }
61 | return rootPath.child("npm-cache/" + executor.getNumber());
62 | }
63 |
64 | @Extension
65 | @Symbol("executor")
66 | public static class DescriptorImpl extends CacheLocationLocatorDescriptor {
67 | @Override
68 | public String getDisplayName() {
69 | return Messages.ExecutorCacheLocationLocator_displayName();
70 | }
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/jenkins/plugins/nodejs/cache/PerJobCacheLocationLocator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2019, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.cache;
25 |
26 | import hudson.Extension;
27 | import hudson.FilePath;
28 | import edu.umd.cs.findbugs.annotations.NonNull;
29 | import jenkins.plugins.nodejs.Messages;
30 | import org.jenkinsci.Symbol;
31 | import org.kohsuke.stapler.DataBoundConstructor;
32 |
33 | /**
34 | * Relocates the NPM's default cache to the workspace folder. This allow clean
35 | * unused packages when the job is gone.
36 | */
37 | public class PerJobCacheLocationLocator extends CacheLocationLocator {
38 |
39 | @DataBoundConstructor
40 | public PerJobCacheLocationLocator() {
41 | }
42 |
43 | @Override
44 | public FilePath locate(@NonNull FilePath workspace) {
45 | return workspace.child(".npm");
46 | }
47 |
48 | @Extension
49 | @Symbol("workspace")
50 | public static class DescriptorImpl extends CacheLocationLocatorDescriptor {
51 | @Override
52 | public String getDisplayName() {
53 | return Messages.JobCacheLocationLocator_displayName();
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/jenkins/plugins/nodejs/configfiles/NPMConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.configfiles;
25 |
26 | import java.io.IOException;
27 | import java.io.InputStream;
28 | import java.util.ArrayList;
29 | import java.util.List;
30 | import java.util.Map;
31 |
32 | import org.apache.commons.io.IOUtils;
33 | import org.apache.commons.lang.StringUtils;
34 | import org.jenkinsci.lib.configprovider.AbstractConfigProviderImpl;
35 | import org.jenkinsci.lib.configprovider.model.Config;
36 | import org.jenkinsci.lib.configprovider.model.ContentType;
37 | import org.kohsuke.stapler.DataBoundConstructor;
38 | import org.kohsuke.stapler.DataBoundSetter;
39 |
40 | import com.cloudbees.plugins.credentials.common.StandardCredentials;
41 |
42 | import edu.umd.cs.findbugs.annotations.NonNull;
43 | import hudson.AbortException;
44 | import hudson.Extension;
45 | import hudson.FilePath;
46 | import hudson.Util;
47 | import hudson.model.Run;
48 | import hudson.model.TaskListener;
49 | import jenkins.plugins.nodejs.Messages;
50 |
51 | /**
52 | * A config/provider to handle the special case of a npmrc config file
53 | *
54 | * @author Nikolas Falco
55 | * @since 1.0
56 | */
57 | public class NPMConfig extends Config {
58 | private static final long serialVersionUID = 1L;
59 |
60 | private final List registries;
61 | private boolean npm9Format = false;
62 |
63 | @DataBoundConstructor
64 | public NPMConfig(@NonNull String id, String name, String comment, String content, List registries) {
65 | super(id, Util.fixEmptyAndTrim(name), Util.fixEmptyAndTrim(comment), Util.fixEmptyAndTrim(content));
66 | this.registries = registries == null ? new ArrayList(3) : registries;
67 | }
68 |
69 | public List getRegistries() {
70 | return registries;
71 | }
72 |
73 | /**
74 | * Perform a validation of the configuration.
75 | *
76 | * If validation pass then no {@link VerifyConfigProviderException} will be
77 | * raised.
78 | *
79 | * @throws VerifyConfigProviderException
80 | * in case this configuration is not valid.
81 | */
82 | public void doVerify() throws VerifyConfigProviderException {
83 | // check if more than registry is setup to be global
84 | NPMRegistry globalRegistry = null;
85 |
86 | for (NPMRegistry registry : registries) {
87 | registry.doVerify();
88 |
89 | if (!registry.isHasScopes()) {
90 | if (globalRegistry != null) {
91 | throw new VerifyConfigProviderException(Messages.NPMConfig_verifyTooGlobalRegistry());
92 | }
93 | globalRegistry = registry;
94 | }
95 | }
96 | }
97 |
98 | public boolean isNpm9Format() {
99 | return npm9Format;
100 | }
101 |
102 | /**
103 | * Sets if the generated .npmrc format is compatible with NPM version 9.
104 | *
105 | * @param npm9Format enable NPM version 9 or not
106 | */
107 | @DataBoundSetter
108 | public void setNpm9Format(boolean npm9Format) {
109 | this.npm9Format = npm9Format;
110 | }
111 |
112 | @Extension
113 | public static class NPMConfigProvider extends AbstractConfigProviderImpl {
114 |
115 | public NPMConfigProvider() {
116 | load();
117 | }
118 |
119 | @Override
120 | public ContentType getContentType() {
121 | return null;
122 | }
123 |
124 | @Override
125 | public String getDisplayName() {
126 | return Messages.NPMConfig_displayName();
127 | }
128 |
129 | @Override
130 | public Config newConfig(@NonNull String configId) {
131 | return new NPMConfig(configId, "MyNpmrcConfig", "user config", loadTemplateContent(), null);
132 | }
133 |
134 | protected String loadTemplateContent() {
135 | try (InputStream is = this.getClass().getResourceAsStream("template.npmrc")) {
136 | return IOUtils.toString(is, "UTF-8");
137 | } catch (IOException e) { // NOSONAR
138 | return null;
139 | }
140 | }
141 |
142 | @Override
143 | public String supplyContent(Config configFile, Run, ?> build, FilePath workDir, TaskListener listener, List tempFiles) throws IOException {
144 | String fileContent = configFile.content;
145 | if (configFile instanceof NPMConfig) {
146 | NPMConfig config = (NPMConfig) configFile;
147 |
148 | List registries = config.getRegistries();
149 | RegistryHelper helper = new RegistryHelper(registries);
150 | if (!registries.isEmpty()) {
151 | listener.getLogger().println("Adding all registry entries");
152 | Map registry2Credentials = helper.resolveCredentials(build);
153 | fileContent = helper.fillRegistry(fileContent, registry2Credentials, config.npm9Format);
154 | }
155 |
156 | try {
157 | if (StringUtils.isNotBlank(fileContent)) { // NOSONAR
158 | config.doVerify();
159 | }
160 | } catch (VerifyConfigProviderException e) {
161 | throw new AbortException("Invalid user config: " + e.getMessage());
162 | }
163 | }
164 | return fileContent;
165 | }
166 |
167 | @Override
168 | public @NonNull List getSensitiveContentForMasking(Config configFile, Run, ?> build) {
169 | List sensitiveContent = new ArrayList<>();
170 | if (configFile instanceof NPMConfig) {
171 | NPMConfig config = (NPMConfig) configFile;
172 | List registries = config.getRegistries();
173 | if (!registries.isEmpty()) {
174 | RegistryHelper helper = new RegistryHelper(registries);
175 | sensitiveContent = helper.secretsForMasking(build);
176 | }
177 | }
178 | return sensitiveContent;
179 | }
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/src/main/java/jenkins/plugins/nodejs/configfiles/VerifyConfigProviderException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.configfiles;
25 |
26 | /**
27 | * Signals an error in the a user configuration file when
28 | * {@link NPMConfig#doVerify()} is called.
29 | *
30 | * @author Nikolas Falco
31 | * @since 1.0
32 | */
33 | @SuppressWarnings("serial")
34 | public class VerifyConfigProviderException extends Exception {
35 |
36 | /**
37 | * Constructs a new exception with the specified detail message.
38 | *
39 | * @param message
40 | * the failure message.
41 | */
42 | public VerifyConfigProviderException(String message) {
43 | super(message);
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/jenkins/plugins/nodejs/package.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
28 |
29 |
30 |
31 | Classes implementing Jenkins API used in NodeJS Plugin.
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/main/java/jenkins/plugins/nodejs/tools/CPU.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.tools;
25 |
26 | import java.io.ByteArrayOutputStream;
27 | import java.io.File;
28 | import java.io.IOException;
29 | import java.nio.charset.Charset;
30 | import java.util.Locale;
31 | import java.util.Map;
32 |
33 | import edu.umd.cs.findbugs.annotations.NonNull;
34 | import edu.umd.cs.findbugs.annotations.Nullable;
35 |
36 | import org.apache.commons.io.output.NullOutputStream;
37 |
38 | import hudson.FilePath;
39 | import hudson.Launcher;
40 | import hudson.Proc;
41 | import hudson.model.Computer;
42 | import hudson.model.Node;
43 | import hudson.remoting.VirtualChannel;
44 | import hudson.util.StreamTaskListener;
45 | import jenkins.MasterToSlaveFileCallable;
46 | import jenkins.plugins.nodejs.Messages;
47 |
48 | /**
49 | * CPU type.
50 | */
51 | public enum CPU {
52 | i386, amd64, armv7l, armv6l, arm64, ppc64;
53 |
54 | /**
55 | * Determines the CPU of the given node.
56 | *
57 | * @param node
58 | * the computer node
59 | * @return a CPU value of the architecture of the given node
60 | * @throws DetectionFailedException
61 | * when the current CPU node is not supported.
62 | */
63 | public static CPU of(@NonNull Node node) throws DetectionFailedException {
64 | try {
65 | Computer computer = node.toComputer();
66 | if (computer == null) {
67 | throw new DetectionFailedException(Messages.SystemTools_nodeNotAvailable(node.getDisplayName()));
68 | }
69 | return detect(computer, computer.getSystemProperties());
70 | } catch (IOException | InterruptedException e) {
71 | throw new DetectionFailedException(Messages.SystemTools_failureOnProperties(), e);
72 | }
73 | }
74 |
75 | /**
76 | * Determines the CPU of the current JVM.
77 | *
78 | * @return the current CPU
79 | * @throws DetectionFailedException
80 | * when the current platform node is not supported.
81 | */
82 | public static CPU current() throws DetectionFailedException {
83 | return detect(null, System.getProperties());
84 | }
85 |
86 | private static CPU detect(@Nullable Computer computer, Map
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/src/main/resources/jenkins/plugins/nodejs/configfiles/NPMConfig/show-config.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2016, Nikolas Falco
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 |
24 | content.title=Content
25 | registry.title=NPM Registry
26 | registry.url=URL
27 | registry.format=Enforce NPM version 9 registry format
28 | registry.global=Global registry
29 | registry.scoped=This registry has the following scopes
30 | registry.scopes=Scopes
--------------------------------------------------------------------------------
/src/main/resources/jenkins/plugins/nodejs/configfiles/NPMRegistry/config.jelly:
--------------------------------------------------------------------------------
1 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/src/main/resources/jenkins/plugins/nodejs/configfiles/NPMRegistry/config.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2016, Nikolas Falco
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 |
24 | url.title=URL
25 | scopes.section.title=Use this registry for specific scoped packages
26 | scopes.title=Registry scopes
27 | scopes.description=a space separated list of scopes
28 | credentialsId.title=Credentials
29 | btnDelete.label=Delete
--------------------------------------------------------------------------------
/src/main/resources/jenkins/plugins/nodejs/configfiles/NPMRegistry/help-credentialsId.html:
--------------------------------------------------------------------------------
1 |
24 |
25 |
The credentials to be assigned to the defined registry. The
26 | credentials can be the plaintext password or the encrypted version of
27 | it if you use a private registry (like Artifactory or Nexus)
25 | A space separated list of scope. A scope follows the usual rules for
26 | package names (url-safe characters, no leading dots or underscores).
27 |
28 | In package names is preceded by an @-symbol and followed by a slash,
29 | e.g. @somescope/somepackagename. Scopes are a way of grouping
30 | related packages together, and also affect a few things about the way
31 | npm treats the package.
32 |
25 | To resolve packages by name and version, npm talks to a registry
26 | website that implements the CommonJS Package Registry specification for
27 | reading package info.
28 |
29 | The registry URL used is determined by the scope of the package (see npm-scope). If no scope
31 | is specified, the default registry is used, which is supplied by the
32 | registry config parameter
33 |
34 |
--------------------------------------------------------------------------------
/src/main/resources/jenkins/plugins/nodejs/configfiles/NPMRegistry/show.jelly:
--------------------------------------------------------------------------------
1 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/main/resources/jenkins/plugins/nodejs/configfiles/NPMRegistry/show.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2016, Nikolas Falco
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 |
24 | url.title=URL
25 | scopes.section.title=Use this registry for specific scoped packages
26 | scopes.title=Registry scopes
27 | scopes.description=a space separated list of scopes
28 | credentialsId.title=Credentials
29 | btnDelete.label=Delete
--------------------------------------------------------------------------------
/src/main/resources/jenkins/plugins/nodejs/configfiles/template.npmrc:
--------------------------------------------------------------------------------
1 | ; Force npm to always require authentication when accessing the registry, even for GET requests.
2 | ; always-auth = false
3 |
4 | ; The location of npm's cache directory. See npm-cache (https://docs.npmjs.com/cli/cache)
5 | ; Default: Windows: %AppData%\npm-cache, Posix: ~/.npm
6 | ; cache =
7 |
8 | ; What level of logs to report. On failure, all logs are written to npm-debug.log in the current working directory.
9 | ; Any logs of a higher level than the setting are shown. The default is "warn", which shows warn and error output.
10 | ; Default: "warn"
11 | ; Values: "silent", "error", "warn", "http", "info", "verbose", "silly"
12 | ; loglevel =
13 |
14 | ; The config file to read for global config options.
15 | ; Default: {prefix}/etc/npmrc
16 | ; globalconfig =
17 |
18 | ; The location to install global items. If set on the command line, then it forces non-global commands to run in the specified folder.
19 | ; Default: see npm-folders (https://docs.npmjs.com/files/folders)
20 | ; prefix =
21 |
22 | ; The base URL of the npm package registry.
23 | ; Default: https://registry.npmjs.org/
24 | ; registry =
25 |
26 | ; If set to false, then ignore npm-shrinkwrap.json files when installing.
27 | ; Default: true
28 | ; shrinkwrap =
--------------------------------------------------------------------------------
/src/main/resources/jenkins/plugins/nodejs/tools/MirrorNodeJSInstaller/config.jelly:
--------------------------------------------------------------------------------
1 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/src/main/resources/jenkins/plugins/nodejs/tools/MirrorNodeJSInstaller/config.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2021, Riain Condon
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 |
24 | mirrorURL.title=Mirror URL
25 | mirrorURL.description=Enter the URL of a mirror for the public NodeJS downloads repo here. You may need to do this if you use services like Artifactory to mirror public repos.
26 | credentials.title=Credentials
27 | credentials.description=Credentials for the nodejs.org mirror if required.
--------------------------------------------------------------------------------
/src/main/resources/jenkins/plugins/nodejs/tools/MirrorNodeJSInstaller/help-credentialsId.html:
--------------------------------------------------------------------------------
1 |
24 |
25 |
Credentials for the nodejs.org mirror if required. Only basic authentication is supported.
25 | A nodejs.org mirror URL from where download a valid
26 | installable package of NodeJS in case there are
27 | limitations or restrictions and you are not able
28 | to reach the official NodeJS.org distribution site.
29 |
--------------------------------------------------------------------------------
/src/main/resources/jenkins/plugins/nodejs/tools/NodeJSInstaller/config.jelly:
--------------------------------------------------------------------------------
1 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/main/resources/jenkins/plugins/nodejs/tools/NodeJSInstaller/config.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2016, Nikolas Falco
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 |
24 | id.title=Version
25 | npmPackages.title=Global npm packages to install
26 | npmPackages.description=Specify list of packages to install globally -- see npm install -g. Note that you can fix the package's version by using the syntax `packageName@version`
27 | npmPackagesRefreshHours.title=Global npm packages refresh hours
28 | npmPackagesRefreshHours.description=Duration, in hours, before 2 npm cache update. Note that 0 will always update npm cache
29 | force32Bit.title=Force 32bit architecture
30 | force32Bit.description=For the underlying architecture, if available, force the installation of the 32bit package. Otherwise the build will fail
--------------------------------------------------------------------------------
/src/main/resources/jenkins/plugins/nodejs/tools/NodeJSInstaller/global_it.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2016, Nikolas Falco
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 |
24 | NodeJS\ installation=Installazioni NodeJS
25 | List\ of\ NodeJS\ installations\ on\ this\ system=Lista delle installazioni di NodeJS nel sistema
--------------------------------------------------------------------------------
/src/main/webapp/help.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Executes a NodeJS script for building the project.
4 | The script will be run with the workspace as the current directory.
5 |
6 |
7 | The build is considered a failure if the script exits with a non-zero exit code.
8 |
9 |
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/CIBuilderHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs;
25 |
26 | import hudson.ExtensionList;
27 |
28 | import hudson.Launcher;
29 | import hudson.model.AbstractBuild;
30 | import hudson.model.Descriptor;
31 | import hudson.model.TaskListener;
32 | import hudson.tasks.Builder;
33 | import jenkins.plugins.nodejs.tools.NodeJSInstallation;
34 |
35 | /* package */ final class CIBuilderHelper {
36 |
37 | public static interface Verifier {
38 | void verify(AbstractBuild, ?> build, Launcher launcher, TaskListener listener) throws Exception;
39 | }
40 |
41 | public static NodeJSCommandInterpreter createMock(String command, NodeJSInstallation installation) {
42 | return createMock(command, installation, null, null);
43 | }
44 |
45 | public static NodeJSCommandInterpreter createMock(String command, NodeJSInstallation installation, String configId) {
46 | return createMock(command, installation, configId, null);
47 | }
48 |
49 | public static NodeJSCommandInterpreter createMock(String command, NodeJSInstallation installation, String configId,
50 | Verifier verifier) {
51 | MockCommandInterpreterBuilder spy = new MockCommandInterpreterBuilder(command, installation.getName(), configId);
52 | ExtensionList.lookupSingleton(NodeJSInstallation.DescriptorImpl.class).setInstallations(installation);
53 | spy.setVerifier(verifier);
54 | return spy;
55 | }
56 |
57 | static class MockCommandInterpreterBuilder extends NodeJSCommandInterpreter {
58 |
59 | // transient to ensure serialisation
60 | private transient CIBuilderHelper.Verifier verifier;
61 |
62 | private MockCommandInterpreterBuilder(String command, String nodeJSInstallationName, String configId) {
63 | super(command, nodeJSInstallationName, configId);
64 | }
65 |
66 | @Override
67 | protected boolean internalPerform(AbstractBuild, ?> build, Launcher launcher, TaskListener listener) throws InterruptedException {
68 | if (verifier != null) {
69 | try {
70 | verifier.verify(build, launcher, listener);
71 | } catch (Exception e) {
72 | throw new RuntimeException(e);
73 | }
74 | }
75 | return true;
76 | }
77 |
78 | private void setVerifier(Verifier verifier) {
79 | this.verifier = verifier;
80 | }
81 |
82 | @Override
83 | public Descriptor getDescriptor() {
84 | return ExtensionList.lookupSingleton(NodeJSCommandInterpreter.NodeJsDescriptor.class);
85 | }
86 |
87 | }
88 | }
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/JCasCTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2020, Evaristo Gutierrez
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs;
25 |
26 | import static org.hamcrest.MatcherAssert.assertThat;
27 | import static org.hamcrest.Matchers.allOf;
28 | import static org.hamcrest.Matchers.arrayWithSize;
29 | import static org.hamcrest.Matchers.containsInAnyOrder;
30 | import static org.hamcrest.Matchers.equalTo;
31 | import static org.hamcrest.Matchers.hasProperty;
32 | import static org.hamcrest.Matchers.hasSize;
33 | import static org.hamcrest.Matchers.instanceOf;
34 | import static org.junit.Assert.assertEquals;
35 | import static org.junit.Assert.assertTrue;
36 |
37 | import java.util.List;
38 |
39 | import org.jenkinsci.lib.configprovider.model.Config;
40 | import org.jenkinsci.plugins.configfiles.ConfigFiles;
41 | import org.junit.Assert;
42 | import org.jvnet.hudson.test.RestartableJenkinsRule;
43 |
44 | import hudson.tools.BatchCommandInstaller;
45 | import hudson.tools.CommandInstaller;
46 | import hudson.tools.InstallSourceProperty;
47 | import hudson.tools.ToolDescriptor;
48 | import hudson.tools.ToolInstallation;
49 | import hudson.tools.ToolProperty;
50 | import hudson.tools.ToolPropertyDescriptor;
51 | import hudson.tools.ZipExtractionInstaller;
52 | import hudson.util.DescribableList;
53 | import io.jenkins.plugins.casc.misc.RoundTripAbstractTest;
54 | import jenkins.model.Jenkins;
55 | import jenkins.plugins.nodejs.configfiles.NPMConfig;
56 | import jenkins.plugins.nodejs.configfiles.NPMRegistry;
57 | import jenkins.plugins.nodejs.tools.NodeJSInstallation;
58 | import jenkins.plugins.nodejs.tools.NodeJSInstaller;
59 |
60 | public class JCasCTest extends RoundTripAbstractTest {
61 |
62 | @Override
63 | protected void assertConfiguredAsExpected(RestartableJenkinsRule restartableJenkinsRule, String s) {
64 | checkConfigFile(restartableJenkinsRule.j.jenkins);
65 | checkInstallations(restartableJenkinsRule.j.jenkins);
66 | }
67 |
68 | private void checkConfigFile(Jenkins j) {
69 | Config config = ConfigFiles.getByIdOrNull(j, "myconfigfile");
70 | assertThat(config, instanceOf(NPMConfig.class));
71 |
72 | NPMConfig npmConfig = (NPMConfig) config;
73 | assertEquals("myComment", npmConfig.comment);
74 | assertEquals("myContent", npmConfig.content);
75 | assertEquals("myConfig", npmConfig.name);
76 | assertEquals(true, npmConfig.isNpm9Format());
77 |
78 | List registries = npmConfig.getRegistries();
79 | Assert.assertTrue(registries.size() == 1);
80 |
81 | NPMRegistry registry = registries.get(0);
82 | assertTrue(registry.isHasScopes());
83 | assertEquals("myScope", registry.getScopes());
84 | assertEquals("registryUrl", registry.getUrl());
85 | }
86 |
87 | private void checkInstallations(Jenkins j) {
88 | final ToolDescriptor descriptor = (ToolDescriptor) j.getDescriptor(NodeJSInstallation.class);
89 | final ToolInstallation[] installations = descriptor.getInstallations();
90 | assertThat(installations, arrayWithSize(2));
91 |
92 | ToolInstallation withInstaller = installations[0];
93 | assertEquals("myNode", withInstaller.getName());
94 |
95 | final DescribableList, ToolPropertyDescriptor> properties = withInstaller.getProperties();
96 | assertThat(properties, hasSize(1));
97 | final ToolProperty> property = properties.get(0);
98 |
99 | assertThat(((InstallSourceProperty)property).installers,
100 | containsInAnyOrder(
101 | allOf(instanceOf(NodeJSInstaller.class),
102 | hasProperty("npmPackagesRefreshHours", equalTo(75L)),
103 | hasProperty("npmPackages", equalTo("globalPackages")),
104 | hasProperty("force32Bit", equalTo(true))),
105 | allOf(instanceOf(CommandInstaller.class),
106 | hasProperty("command", equalTo("install npm")),
107 | hasProperty("toolHome", equalTo("/my/path/1")),
108 | hasProperty("label", equalTo("npm command"))),
109 | allOf(instanceOf(ZipExtractionInstaller.class),
110 | hasProperty("url", equalTo("http://fake.com")),
111 | hasProperty("subdir", equalTo("/my/path/2")),
112 | hasProperty("label", equalTo("npm zip"))),
113 | allOf(instanceOf(BatchCommandInstaller.class),
114 | hasProperty("command", equalTo("run batch command")),
115 | hasProperty("toolHome", equalTo("/my/path/3")),
116 | hasProperty("label", equalTo("npm batch")))
117 | ));
118 |
119 | ToolInstallation withoutInstaller = installations[1];
120 | assertThat(withoutInstaller,
121 | allOf(
122 | hasProperty("name", equalTo("anotherNodeWithNoInstall")),
123 | hasProperty("home", equalTo("/onePath")
124 | )));
125 | }
126 |
127 | @Override
128 | protected String stringInLogExpected() {
129 | return "Setting class jenkins.plugins.nodejs.configfiles.NPMConfig.id";
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/NodeJSSerialisationTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2019, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs;
25 |
26 | import org.assertj.core.api.Assertions;
27 | import org.junit.Rule;
28 | import org.junit.Test;
29 | import org.junit.rules.TemporaryFolder;
30 | import org.jvnet.hudson.test.Issue;
31 | import org.jvnet.hudson.test.JenkinsRule;
32 | import org.jvnet.hudson.test.recipes.LocalData;
33 |
34 | import hudson.model.FreeStyleProject;
35 | import jenkins.plugins.nodejs.cache.DefaultCacheLocationLocator;
36 | import jenkins.plugins.nodejs.cache.PerJobCacheLocationLocator;
37 |
38 | public class NodeJSSerialisationTest {
39 |
40 | @Rule
41 | public JenkinsRule j = new JenkinsRule();
42 | @Rule
43 | public TemporaryFolder fileRule = new TemporaryFolder();
44 |
45 | /**
46 | * Verify that the serialisation is backward compatible.
47 | */
48 | @LocalData
49 | @Test
50 | @Issue("JENKINS-57844")
51 | public void test_serialisation_is_compatible_with_version_1_2_x_interpreter() throws Exception {
52 | FreeStyleProject prj = j.jenkins.getAllItems(hudson.model.FreeStyleProject.class) //
53 | .stream() //
54 | .filter(p -> "test".equals(p.getName())) //
55 | .findFirst().get();
56 |
57 | NodeJSCommandInterpreter step = prj.getBuildersList().get(NodeJSCommandInterpreter.class);
58 | Assertions.assertThat(step.getCacheLocationStrategy()).isInstanceOf(DefaultCacheLocationLocator.class);
59 | }
60 |
61 | /**
62 | * Verify reloading jenkins job configuration use the saved cache strategy instead reset to default.
63 | */
64 | @LocalData
65 | @Test
66 | @Issue("JENKINS-58029")
67 | public void test_reloading_job_configuration_contains_saved_cache_strategy_interpreter() throws Exception {
68 | FreeStyleProject prj = j.jenkins.getAllItems(hudson.model.FreeStyleProject.class) //
69 | .stream() //
70 | .filter(p -> "test".equals(p.getName())) //
71 | .findFirst().get();
72 |
73 | NodeJSCommandInterpreter step = prj.getBuildersList().get(NodeJSCommandInterpreter.class);
74 | Assertions.assertThat(step.getCacheLocationStrategy()).isInstanceOf(PerJobCacheLocationLocator.class);
75 | }
76 |
77 | /**
78 | * Verify that the serialisation is backward compatible.
79 | */
80 | @LocalData
81 | @Test
82 | @Issue("JENKINS-57844")
83 | public void test_serialisation_is_compatible_with_version_1_2_x_buildWrapper() throws Exception {
84 | FreeStyleProject prj = j.jenkins.getAllItems(hudson.model.FreeStyleProject.class) //
85 | .stream() //
86 | .filter(p -> "test".equals(p.getName())) //
87 | .findFirst().get();
88 |
89 | NodeJSBuildWrapper step = prj.getBuildWrappersList().get(NodeJSBuildWrapper.class);
90 | Assertions.assertThat(step.getCacheLocationStrategy()).isInstanceOf(DefaultCacheLocationLocator.class);
91 | }
92 |
93 | /**
94 | * Verify reloading jenkins job configuration use the saved cache strategy instead reset to default.
95 | */
96 | @LocalData
97 | @Test
98 | @Issue("JENKINS-58029")
99 | public void test_reloading_job_configuration_contains_saved_cache_strategy_buildWrapper() throws Exception {
100 | FreeStyleProject prj = j.jenkins.getAllItems(hudson.model.FreeStyleProject.class) //
101 | .stream() //
102 | .filter(p -> "test".equals(p.getName())) //
103 | .findFirst().get();
104 |
105 | NodeJSBuildWrapper step = prj.getBuildWrappersList().get(NodeJSBuildWrapper.class);
106 | Assertions.assertThat(step.getCacheLocationStrategy()).isInstanceOf(PerJobCacheLocationLocator.class);
107 | }
108 |
109 | }
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/NpmrcFileSupplyTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs;
25 |
26 | import static org.junit.Assert.assertEquals;
27 | import static org.junit.Assert.assertTrue;
28 |
29 | import java.io.File;
30 | import java.util.ArrayList;
31 | import java.util.Arrays;
32 | import java.util.List;
33 |
34 | import org.jenkinsci.lib.configprovider.model.Config;
35 | import org.jenkinsci.lib.configprovider.model.ConfigFile;
36 | import org.jenkinsci.lib.configprovider.model.ConfigFileManager;
37 | import org.jenkinsci.plugins.configfiles.GlobalConfigFiles;
38 | import org.junit.Rule;
39 | import org.junit.Test;
40 | import org.jvnet.hudson.test.JenkinsRule;
41 |
42 | import com.cloudbees.plugins.credentials.CredentialsScope;
43 | import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials;
44 | import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl;
45 |
46 | import hudson.FilePath;
47 | import hudson.model.FreeStyleBuild;
48 | import hudson.model.Descriptor.FormException;
49 | import jenkins.plugins.nodejs.configfiles.NPMConfig;
50 | import jenkins.plugins.nodejs.configfiles.NPMRegistry;
51 | import jenkins.plugins.nodejs.configfiles.Npmrc;
52 |
53 | public class NpmrcFileSupplyTest {
54 |
55 | @Rule
56 | public JenkinsRule j = new JenkinsRule();
57 |
58 | @Test
59 | public void test_supply_npmrc_with_registry() throws Exception {
60 | StandardUsernameCredentials user = createUser("test-user-id", "myuser", "mypassword");
61 | NPMRegistry privateRegistry = new NPMRegistry("https://private.organization.com/", user.getId(), null);
62 | NPMRegistry officalRegistry = new NPMRegistry("https://registry.npmjs.org/", null, "@user1 user2");
63 |
64 | Config config = createSetting("mytest", "email=guest@example.com", Arrays.asList(privateRegistry, officalRegistry));
65 |
66 | FreeStyleBuild build = j.buildAndAssertSuccess(j.createFreeStyleProject());
67 |
68 | FilePath npmrcFile = ConfigFileManager.provisionConfigFile(new ConfigFile(config.id, null, true), null, build, build.getWorkspace(), j.createTaskListener(), new ArrayList(1));
69 | assertTrue(npmrcFile.exists());
70 | assertTrue(npmrcFile.length() > 0);
71 |
72 | Npmrc npmrc = Npmrc.load(new File(npmrcFile.getRemote()));
73 | assertTrue("Missing setting email", npmrc.contains("email"));
74 | assertEquals("Unexpected value from settings email", "guest@example.com", npmrc.get("email"));
75 | }
76 |
77 | private StandardUsernameCredentials createUser(String id, String username, String password) throws FormException {
78 | return new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, id, null, username, password);
79 | }
80 |
81 | private Config createSetting(String id, String content, List registries) {
82 | Config config = new NPMConfig(id, null, null, content, registries);
83 |
84 | GlobalConfigFiles globalConfigFiles = j.jenkins.getExtensionList(GlobalConfigFiles.class)
85 | .get(GlobalConfigFiles.class);
86 | globalConfigFiles.save(config);
87 | return config;
88 | }
89 |
90 | }
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/SimpleNodeJSCommandInterpreterTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs;
25 |
26 | import hudson.FilePath;
27 | import hudson.model.Descriptor;
28 | import jenkins.plugins.nodejs.Messages;
29 | import jenkins.plugins.nodejs.tools.NodeJSInstallation;
30 | import hudson.tasks.Builder;
31 | import hudson.tools.ToolProperty;
32 |
33 | import org.junit.Before;
34 | import org.junit.Rule;
35 | import org.junit.Test;
36 | import org.junit.rules.TemporaryFolder;
37 |
38 | import java.io.IOException;
39 | import java.util.Collections;
40 |
41 | import static org.junit.Assert.*;
42 |
43 | public class SimpleNodeJSCommandInterpreterTest {
44 |
45 | private static final String COMMAND = "var sys = require('sys'); sys.puts('build number: ' + process.env['BUILD_NUMBER']);";
46 |
47 | private NodeJSCommandInterpreter interpreter;
48 | private Descriptor descriptor;
49 | private NodeJSInstallation installation;
50 |
51 | @Rule
52 | public TemporaryFolder tempFolder = new TemporaryFolder();
53 |
54 | @Before
55 | public void setUp() {
56 | installation = new NodeJSInstallation("11.0.0", "", Collections.>emptyList());
57 | interpreter = new NodeJSCommandInterpreter(COMMAND, installation.getName(), null);
58 | descriptor = new NodeJSCommandInterpreter.NodeJsDescriptor();
59 | }
60 |
61 | @Test
62 | public void testGetContentsShouldGiveExpectedValue() {
63 | assertEquals(COMMAND, interpreter.getCommand());
64 | }
65 |
66 | @Test
67 | public void testGetContentWithEmptyCommandShouldGiveExpectedValue() {
68 | assertEquals("", new NodeJSCommandInterpreter("", installation.getName(), null).getCommand());
69 | }
70 |
71 | @Test
72 | public void testGetContentWithNullCommandShouldGiveExpectedValue() {
73 | assertNull(new NodeJSCommandInterpreter(null, installation.getName(), null).getCommand());
74 | }
75 |
76 | @Test
77 | public void testGetFileExtensionShouldGiveExpectedValue() throws IOException, InterruptedException {
78 | assertEquals(true, interpreter.createScriptFile(new FilePath(tempFolder.newFolder())).getName().endsWith(".js"));
79 | }
80 |
81 | @Test
82 | public void testGetDescriptorShouldGiveExpectedValue() {
83 | assertNotNull(descriptor);
84 | assertTrue(descriptor instanceof Descriptor>);
85 | }
86 |
87 | @Test
88 | public void testDescriptorGetDisplayNameShouldGiveExpectedValue() {
89 | assertEquals(Messages.NodeJSCommandInterpreter_displayName(), descriptor.getDisplayName());
90 | }
91 |
92 | @Test
93 | public void testDescriptorGetHelpFileShouldGiveExpectedValue() {
94 | assertEquals("/plugin/nodejs/help.html", descriptor.getHelpFile());
95 | }
96 | }
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/TestCacheLocationLocator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2019, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs;
25 |
26 | import hudson.Extension;
27 | import hudson.FilePath;
28 | import java.io.File;
29 | import jenkins.plugins.nodejs.cache.CacheLocationLocator;
30 | import jenkins.plugins.nodejs.cache.CacheLocationLocatorDescriptor;
31 |
32 | public class TestCacheLocationLocator extends CacheLocationLocator {
33 |
34 | private File location;
35 |
36 | public TestCacheLocationLocator(File location) {
37 | this.location = location;
38 | }
39 |
40 | @Override
41 | public FilePath locate(FilePath workspace) {
42 | return new FilePath(location);
43 | }
44 |
45 | @Extension
46 | public static class DescriptorImpl extends CacheLocationLocatorDescriptor {
47 | @Override
48 | public String getDisplayName() {
49 | return "test cache locator";
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/VerifyEnvVariableBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs;
25 |
26 | import static org.junit.Assert.*;
27 |
28 | import java.io.File;
29 | import java.io.IOException;
30 |
31 | import hudson.EnvVars;
32 | import hudson.Launcher;
33 | import hudson.model.AbstractBuild;
34 | import hudson.model.BuildListener;
35 | import hudson.tasks.Builder;
36 |
37 | abstract class VerifyEnvVariableBuilder extends Builder {
38 | @Override
39 | public boolean perform(AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
40 | EnvVars env = build.getEnvironment(listener);
41 | verify(env);
42 | return true;
43 | }
44 |
45 | public abstract void verify(EnvVars env);
46 |
47 | public static final class FileVerifier extends VerifyEnvVariableBuilder {
48 | @Override
49 | public void verify(EnvVars env) {
50 | String var = NodeJSConstants.NPM_USERCONFIG;
51 | String value = env.get(var);
52 |
53 | assertTrue("variable " + var + " not set", env.containsKey(var));
54 | assertNotNull("empty value for environment variable " + var, value);
55 | assertTrue("file of variable " + var + " does not exists or is not a file", new File(value).isFile());
56 | }
57 | }
58 |
59 | public static final class EnvVarVerifier extends VerifyEnvVariableBuilder {
60 |
61 | private final String name;
62 | private final String value;
63 |
64 | public EnvVarVerifier(String name, String value) {
65 | this.name = name;
66 | this.value = value;
67 | }
68 |
69 | @Override
70 | public void verify(EnvVars env) {
71 | String envValue = env.get(name);
72 |
73 | assertTrue("variable " + name + " not set", env.containsKey(name));
74 | assertEquals(value, envValue);
75 | }
76 | }
77 | }
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/cache/CacheLocationLocatorTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.cache;
25 |
26 | import hudson.FilePath;
27 | import hudson.model.Computer;
28 | import hudson.model.Executor;
29 | import hudson.model.Node;
30 | import org.junit.Assert;
31 | import org.junit.Before;
32 | import org.junit.Rule;
33 | import org.junit.Test;
34 | import org.junit.rules.TemporaryFolder;
35 | import org.mockito.MockedStatic;
36 |
37 | import static org.mockito.Mockito.mock;
38 | import static org.mockito.Mockito.mockStatic;
39 | import static org.mockito.Mockito.when;
40 |
41 | public class CacheLocationLocatorTest {
42 |
43 | @Rule
44 | public TemporaryFolder fileRule = new TemporaryFolder();
45 | private FilePath workspace;
46 |
47 | @Before
48 | public void setup() throws Exception {
49 | workspace = new FilePath(fileRule.newFolder());
50 | }
51 |
52 | @Test
53 | public void test_default() {
54 | Assert.assertNull("expect null location path", new DefaultCacheLocationLocator().locate(workspace));
55 | }
56 |
57 | @Test
58 | public void test_per_job() throws Exception {
59 | Assert.assertEquals("expect the same location path passes as input", workspace.child(".npm"), new PerJobCacheLocationLocator().locate(workspace));
60 | }
61 |
62 | @Test
63 | public void test_per_executor() throws Exception {
64 | FilePath wc = mock(FilePath.class);
65 | Executor executor = mock(Executor.class);
66 | int executorNumber = 7;
67 | when(executor.getNumber()).thenReturn(executorNumber);
68 |
69 | try (MockedStatic staticExecutor = mockStatic(Executor.class)) {
70 | staticExecutor.when(Executor::currentExecutor).thenReturn(executor);
71 |
72 | Computer computer = mock(Computer.class);
73 | Node node = mock(Node.class);
74 | when(computer.getNode()).thenReturn(node);
75 | FilePath rootPath = new FilePath(fileRule.newFolder());
76 | when(node.getRootPath()).thenReturn(rootPath);
77 | when(wc.toComputer()).thenReturn(computer);
78 |
79 | FilePath expectedLocation = rootPath.child("npm-cache").child(String.valueOf(executorNumber));
80 | Assert.assertEquals("expect null location path", expectedLocation, new PerExecutorCacheLocationLocator().locate(wc));
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/configfiles/NPMConfigTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.configfiles;
25 |
26 | import static org.junit.Assert.assertNotNull;
27 |
28 | import org.assertj.core.api.Assertions;
29 | import org.jenkinsci.lib.configprovider.model.Config;
30 | import org.junit.Rule;
31 | import org.junit.Test;
32 | import org.jvnet.hudson.test.JenkinsRule;
33 |
34 | import hudson.model.Descriptor;
35 | import jenkins.plugins.nodejs.configfiles.NPMConfig.NPMConfigProvider;
36 |
37 | public class NPMConfigTest {
38 |
39 | @Rule
40 | public JenkinsRule j = new JenkinsRule();
41 |
42 | @Test
43 | public void test_load_template() {
44 | Descriptor> descriptor = j.jenkins.getDescriptor(NPMConfig.class);
45 | assertNotNull("NPMConfig descriptor not registered", descriptor);
46 | Assertions.assertThat(descriptor).isInstanceOf(NPMConfigProvider.class).describedAs("Unexpected descriptor class");
47 |
48 | NPMConfigProvider provider = (NPMConfigProvider) descriptor;
49 | Config config = provider.newConfig("testId");
50 | Assertions.assertThat(config).isInstanceOf(NPMConfig.class).describedAs("Unexpected config class");
51 | Assertions.assertThat(config.content).isNotBlank().describedAs("Expected the default template, instead got empty");
52 | }
53 |
54 | }
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/configfiles/NPMConfigValidationTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.configfiles;
25 |
26 | import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
27 | import static org.junit.Assert.assertEquals;
28 | import static org.junit.Assert.assertNotNull;
29 | import static org.junit.Assert.assertNull;
30 |
31 | import java.util.Arrays;
32 |
33 | import org.junit.Test;
34 |
35 | public class NPMConfigValidationTest {
36 |
37 | @Test
38 | public void test_new_config() {
39 | String id = "test_id";
40 | NPMConfig config = new NPMConfig(id, "", "", "", null);
41 | assertEquals(id, config.id);
42 | assertNull(config.name);
43 | assertNull(config.comment);
44 | assertNull(config.content);
45 | assertNotNull(config.getRegistries());
46 | }
47 |
48 | @Test
49 | public void test_too_many_global_registries() throws Exception {
50 | NPMRegistry privateRegistry = new NPMRegistry("https://private.organization.com/", null, null);
51 | NPMRegistry officalRegistry = new NPMRegistry("https://registry.npmjs.org/", null, null);
52 |
53 | NPMConfig config = new NPMConfig("too_many_registry", null, null, null, Arrays.asList(privateRegistry, officalRegistry));
54 |
55 | assertThatExceptionOfType(VerifyConfigProviderException.class) //
56 | .isThrownBy(() -> config.doVerify());
57 | }
58 |
59 | @Test
60 | public void test_empty_URL() throws Exception {
61 | NPMRegistry registry = new NPMRegistry("", null, null);
62 |
63 | NPMConfig config = new NPMConfig("empty_URL", null, null, null, Arrays.asList(registry));
64 |
65 | assertThatExceptionOfType(VerifyConfigProviderException.class) //
66 | .isThrownBy(() -> config.doVerify());
67 | }
68 |
69 | @Test
70 | public void test_no_exception_if_URL_has_variable() throws Exception {
71 | NPMRegistry registry = new NPMRegistry("${URL}", null, null);
72 |
73 | NPMConfig config = new NPMConfig("no_exception_if_URL_has_variable", null, null, null, Arrays.asList(registry));
74 | config.doVerify();
75 | }
76 |
77 | }
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/configfiles/NPMRegistryValidator2Test.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.configfiles;
25 |
26 | import static org.mockito.ArgumentMatchers.any;
27 | import static org.mockito.ArgumentMatchers.anyString;
28 | import static org.mockito.ArgumentMatchers.isA;
29 | import static org.mockito.Mockito.mock;
30 | import static org.mockito.Mockito.when;
31 |
32 | import java.util.Arrays;
33 | import java.util.HashMap;
34 | import java.util.List;
35 | import java.util.Map;
36 |
37 | import org.assertj.core.api.Assertions;
38 | import org.junit.ClassRule;
39 | import org.junit.Test;
40 | import org.jvnet.hudson.test.JenkinsRule;
41 |
42 | import com.cloudbees.plugins.credentials.Credentials;
43 | import com.cloudbees.plugins.credentials.CredentialsScope;
44 | import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
45 | import com.cloudbees.plugins.credentials.domains.Domain;
46 | import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl;
47 |
48 | import hudson.model.FreeStyleProject;
49 | import hudson.model.Item;
50 | import hudson.security.Permission;
51 | import hudson.util.FormValidation;
52 | import hudson.util.FormValidation.Kind;
53 | import jenkins.plugins.nodejs.configfiles.NPMRegistry.DescriptorImpl;
54 |
55 | /**
56 | * Test input form validation.
57 | *
58 | * @author Nikolas Falco
59 | */
60 | public class NPMRegistryValidator2Test {
61 |
62 |
63 | @ClassRule
64 | public static JenkinsRule rule = new JenkinsRule();
65 |
66 | @Test
67 | public void test_credentials_ok() throws Exception {
68 | String credentialsId = "secret";
69 | Credentials credentials = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "", "user", "password");
70 | Map> credentialsMap = new HashMap<>();
71 | credentialsMap.put(Domain.global(), Arrays.asList(credentials));
72 | SystemCredentialsProvider.getInstance().setDomainCredentialsMap(credentialsMap);
73 |
74 | FreeStyleProject prj = mock(FreeStyleProject.class);
75 | when(prj.hasPermission(isA(Permission.class))).thenReturn(true);
76 |
77 | DescriptorImpl descriptor = mock(DescriptorImpl.class);
78 | when(descriptor.doCheckCredentialsId(any(Item.class), (String) any(), anyString())).thenCallRealMethod();
79 |
80 | String serverURL = "http://acme.com";
81 |
82 | FormValidation result = descriptor.doCheckCredentialsId(prj, credentialsId, serverURL);
83 | Assertions.assertThat(result.kind).isEqualTo(Kind.OK);
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/configfiles/NPMRegistryValidatorTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.configfiles;
25 |
26 | import static org.mockito.ArgumentMatchers.any;
27 | import static org.mockito.ArgumentMatchers.anyString;
28 | import static org.mockito.ArgumentMatchers.isA;
29 | import static org.mockito.Mockito.mock;
30 | import static org.mockito.Mockito.when;
31 |
32 | import org.assertj.core.api.Assertions;
33 | import org.junit.Test;
34 |
35 | import hudson.model.FreeStyleProject;
36 | import hudson.model.Item;
37 | import hudson.security.Permission;
38 | import hudson.util.FormValidation;
39 | import hudson.util.FormValidation.Kind;
40 | import jenkins.plugins.nodejs.Messages;
41 | import jenkins.plugins.nodejs.configfiles.NPMRegistry.DescriptorImpl;
42 |
43 | /**
44 | * Test input form validation.
45 | *
46 | * @author Nikolas Falco
47 | */
48 | public class NPMRegistryValidatorTest {
49 |
50 | @Test
51 | public void test_empty_scopes() throws Exception {
52 | DescriptorImpl descriptor = new DescriptorImpl();
53 |
54 | FormValidation result = descriptor.doCheckScopes(true, "");
55 | Assertions.assertThat(result.kind).isEqualTo(Kind.ERROR);
56 | Assertions.assertThat(result.getMessage()).isEqualTo(Messages.NPMRegistry_DescriptorImpl_emptyScopes());
57 | }
58 |
59 | @Test
60 | public void test_scopes_with_at_in_name() throws Exception {
61 | DescriptorImpl descriptor = new DescriptorImpl();
62 |
63 | FormValidation result = descriptor.doCheckScopes(true, "@scope1");
64 | Assertions.assertThat(result.kind).isEqualTo(Kind.WARNING);
65 | Assertions.assertThat(result.getMessage()).isEqualTo(Messages.NPMRegistry_DescriptorImpl_invalidCharInScopes());
66 | }
67 |
68 | @Test
69 | public void test_invalid_scopes() throws Exception {
70 | DescriptorImpl descriptor = new DescriptorImpl();
71 |
72 | FormValidation result = descriptor.doCheckScopes(true, "@");
73 | Assertions.assertThat(result.kind).isEqualTo(Kind.ERROR);
74 | Assertions.assertThat(result.getMessage()).isEqualTo(Messages.NPMRegistry_DescriptorImpl_invalidScopes());
75 | }
76 |
77 | @Test
78 | public void test_scopes_ok() throws Exception {
79 | DescriptorImpl descriptor = new DescriptorImpl();
80 |
81 | FormValidation result = descriptor.doCheckScopes(true, "scope1 scope2 scope3");
82 | Assertions.assertThat(result.kind).isEqualTo(Kind.OK);
83 | }
84 |
85 | @Test
86 | public void test_empty_server_url() throws Exception {
87 | DescriptorImpl descriptor = new DescriptorImpl();
88 |
89 | FormValidation result = descriptor.doCheckUrl("");
90 | Assertions.assertThat(result.kind).isEqualTo(Kind.ERROR);
91 | Assertions.assertThat(result.getMessage()).isEqualTo(Messages.NPMRegistry_DescriptorImpl_emptyRegistryURL());
92 | }
93 |
94 | @Test
95 | public void test_server_url_that_contains_variable() throws Exception {
96 | DescriptorImpl descriptor = new DescriptorImpl();
97 |
98 | FormValidation result = descriptor.doCheckUrl("${REGISTRY_URL}/root");
99 | Assertions.assertThat(result.kind).isEqualTo(Kind.OK);
100 | result = descriptor.doCheckUrl("http://${SERVER_NAME}/root");
101 | Assertions.assertThat(result.kind).isEqualTo(Kind.OK);
102 | result = descriptor.doCheckUrl("http://acme.com/${CONTEXT_ROOT}");
103 | Assertions.assertThat(result.kind).isEqualTo(Kind.OK);
104 | }
105 |
106 | @Test
107 | public void test_empty_server_url_is_ok() throws Exception {
108 | DescriptorImpl descriptor = new DescriptorImpl();
109 |
110 | FormValidation result = descriptor.doCheckUrl("http://acme.com");
111 | Assertions.assertThat(result.kind).isEqualTo(Kind.OK);
112 | }
113 |
114 | @Test
115 | public void test_server_url_invalid_protocol() throws Exception {
116 | DescriptorImpl descriptor = new DescriptorImpl();
117 |
118 | FormValidation result = descriptor.doCheckUrl("hpp://acme.com/root");
119 | Assertions.assertThat(result.kind).isEqualTo(Kind.ERROR);
120 | Assertions.assertThat(result.getMessage()).isEqualTo(Messages.NPMRegistry_DescriptorImpl_invalidRegistryURL());
121 | }
122 |
123 | @Test
124 | public void test_invalid_credentials() throws Exception {
125 | FreeStyleProject prj = mock(FreeStyleProject.class);
126 | when(prj.hasPermission(isA(Permission.class))).thenReturn(true);
127 |
128 | DescriptorImpl descriptor = mock(DescriptorImpl.class);
129 | when(descriptor.doCheckCredentialsId(any(Item.class), (String) any(), anyString())).thenCallRealMethod();
130 |
131 | String credentialsId = "secret";
132 | String serverURL = "http://acme.com";
133 |
134 | FormValidation result = descriptor.doCheckCredentialsId(prj, credentialsId, serverURL);
135 | Assertions.assertThat(result.kind).isEqualTo(Kind.ERROR);
136 | Assertions.assertThat(result.getMessage()).isEqualTo(Messages.NPMRegistry_DescriptorImpl_invalidCredentialsId());
137 |
138 | when(prj.hasPermission(isA(Permission.class))).thenReturn(false);
139 | result = descriptor.doCheckCredentialsId(prj, credentialsId, serverURL);
140 | Assertions.assertThat(result.kind).isEqualTo(Kind.OK);
141 | }
142 |
143 | @Test
144 | public void test_empty_credentials() throws Exception {
145 | FreeStyleProject prj = mock(FreeStyleProject.class);
146 | when(prj.hasPermission(isA(Permission.class))).thenReturn(true);
147 |
148 | DescriptorImpl descriptor = mock(DescriptorImpl.class);
149 | when(descriptor.doCheckCredentialsId(any(Item.class), (String) any(), anyString())).thenCallRealMethod();
150 |
151 | String serverURL = "http://acme.com";
152 |
153 | FormValidation result = descriptor.doCheckCredentialsId(prj, "", serverURL);
154 | Assertions.assertThat(result.kind).isEqualTo(Kind.WARNING);
155 | Assertions.assertThat(result.getMessage()).isEqualTo(Messages.NPMRegistry_DescriptorImpl_emptyCredentialsId());
156 | result = descriptor.doCheckCredentialsId(prj, null, serverURL);
157 | Assertions.assertThat(result.kind).isEqualTo(Kind.WARNING);
158 | Assertions.assertThat(result.getMessage()).isEqualTo(Messages.NPMRegistry_DescriptorImpl_emptyCredentialsId());
159 | }
160 |
161 | }
162 |
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/configfiles/NpmrcTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.configfiles;
25 |
26 | import static org.junit.Assert.assertEquals;
27 | import static org.junit.Assert.assertFalse;
28 | import static org.junit.Assert.assertTrue;
29 |
30 | import java.io.File;
31 | import java.io.FileInputStream;
32 | import java.io.IOException;
33 | import java.io.InputStream;
34 | import java.util.List;
35 |
36 | import org.apache.commons.io.IOUtils;
37 | import org.junit.Before;
38 | import org.junit.Rule;
39 | import org.junit.Test;
40 | import org.junit.rules.TemporaryFolder;
41 |
42 | public class NpmrcTest {
43 |
44 | @Rule
45 | public TemporaryFolder folder = new TemporaryFolder();
46 | private File file;
47 |
48 | @Before
49 | public void setUp() throws IOException {
50 | InputStream is = null;
51 | try {
52 | is = getClass().getResourceAsStream("npmrc.config");
53 | file = folder.newFile(".npmrc");
54 | hudson.util.IOUtils.copy(is, file);
55 | } finally {
56 | IOUtils.closeQuietly(is);
57 | }
58 | }
59 |
60 | @Test
61 | public void testLoad() throws Exception {
62 | Npmrc npmrc = Npmrc.load(file);
63 | assertTrue(npmrc.contains("always-auth"));
64 | assertEquals("true", npmrc.get("always-auth"));
65 | assertEquals("\"/var/lib/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_6.x\"",
66 | npmrc.get("prefix"));
67 | }
68 |
69 | @Test
70 | public void testAvoidParseError() throws Exception {
71 | Npmrc npmrc = Npmrc.load(file);
72 | assertFalse(npmrc.contains("browser"));
73 | }
74 |
75 | @Test
76 | public void testSave() throws Exception {
77 | String testKey = "test";
78 | String testValue = "value";
79 |
80 | Npmrc npmrc = Npmrc.load(file);
81 | npmrc.set(testKey, testValue);
82 | npmrc.save(file);
83 |
84 | // reload content
85 | npmrc = Npmrc.load(file);
86 | assertTrue(npmrc.contains(testKey));
87 | assertEquals(testValue, npmrc.get(testKey));
88 | }
89 |
90 | @Test
91 | public void testCommandAtLast() throws Exception {
92 | String comment = "test comment";
93 |
94 | Npmrc npmrc = Npmrc.load(file);
95 | npmrc.addComment(comment);
96 | npmrc.save(file);
97 |
98 | try (InputStream is = new FileInputStream(file)) {
99 | List lines = IOUtils.readLines(is, "UTF-8");
100 | assertEquals(';' + comment, lines.get(lines.size() - 1));
101 | }
102 | }
103 |
104 | }
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/configfiles/RegistryHelperTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.configfiles;
25 |
26 | import static org.junit.Assert.assertEquals;
27 | import static org.junit.Assert.assertFalse;
28 |
29 | import java.util.Arrays;
30 | import java.util.Map;
31 |
32 | import org.assertj.core.api.Assertions;
33 | import org.jenkinsci.plugins.plaincredentials.StringCredentials;
34 | import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl;
35 | import org.junit.Before;
36 | import org.junit.ClassRule;
37 | import org.junit.Test;
38 | import org.jvnet.hudson.test.JenkinsRule;
39 |
40 | import com.cloudbees.plugins.credentials.CredentialsProvider;
41 | import com.cloudbees.plugins.credentials.CredentialsScope;
42 | import com.cloudbees.plugins.credentials.CredentialsStore;
43 | import com.cloudbees.plugins.credentials.common.StandardCredentials;
44 | import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials;
45 | import com.cloudbees.plugins.credentials.domains.Domain;
46 | import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl;
47 |
48 | import hudson.model.FreeStyleBuild;
49 | import hudson.util.Secret;
50 |
51 | public class RegistryHelperTest {
52 |
53 | @ClassRule
54 | public static JenkinsRule j = new JenkinsRule();
55 |
56 | private StandardUsernameCredentials user;
57 | private StringCredentials token;
58 |
59 | @Before
60 | public void setUp() throws Exception {
61 | user = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, "privateId", "dummy desc", "myuser", "mypassword");
62 | token = new StringCredentialsImpl(CredentialsScope.GLOBAL, "privateToken", "dummy desc", Secret.fromString("mysecret"));
63 | CredentialsStore store = CredentialsProvider.lookupStores(j.getInstance()).iterator().next();
64 | store.addCredentials(Domain.global(), user);
65 | store.addCredentials(Domain.global(), token);
66 | }
67 |
68 | @Test
69 | public void test_registry_credentials_resolution() throws Exception {
70 | NPMRegistry privateRegistry = new NPMRegistry("https://private.organization.com/", user.getId(), null);
71 | NPMRegistry officalRegistry = new NPMRegistry("https://registry.npmjs.org/", null, "@user1 user2");
72 |
73 | FreeStyleBuild build = j.createFreeStyleProject().createExecutable();
74 |
75 | RegistryHelper helper = new RegistryHelper(Arrays.asList(privateRegistry, officalRegistry));
76 | Map resolvedCredentials = helper.resolveCredentials(build);
77 | assertFalse(resolvedCredentials.isEmpty());
78 | assertEquals(1, resolvedCredentials.size());
79 |
80 | Assertions.assertThat(resolvedCredentials.keySet().contains(privateRegistry.getUrl()));
81 | Assertions.assertThat(resolvedCredentials.get(privateRegistry.getUrl())).isEqualTo(user);
82 | }
83 |
84 | @Test
85 | public void test_registry_auth_token_credentials_resolution() throws Exception {
86 | NPMRegistry privateRegistry = new NPMRegistry("https://private.organization.com/", token.getId(), null);
87 | NPMRegistry officalRegistry = new NPMRegistry("https://registry.npmjs.org/", token.getId(), "@user1 user2");
88 |
89 | FreeStyleBuild build = j.createFreeStyleProject().createExecutable();
90 |
91 | RegistryHelper helper = new RegistryHelper(Arrays.asList(privateRegistry, officalRegistry));
92 | Map resolvedCredentials = helper.resolveCredentials(build);
93 | assertFalse(resolvedCredentials.isEmpty());
94 | assertEquals(2, resolvedCredentials.size());
95 |
96 | Assertions.assertThat(resolvedCredentials.keySet().contains(privateRegistry.getUrl()));
97 | Assertions.assertThat(resolvedCredentials.get(privateRegistry.getUrl())).isEqualTo(token);
98 | Assertions.assertThat(resolvedCredentials.get(officalRegistry.getUrl())).isEqualTo(token);
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/tools/CPUTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2021, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.tools;
25 |
26 | import org.assertj.core.api.Assertions;
27 | import org.junit.Test;
28 | import org.jvnet.hudson.test.Issue;
29 |
30 | public class CPUTest {
31 |
32 | @Test
33 | @Issue("JENKINS-64311")
34 | public void verify_aarch64() throws DetectionFailedException {
35 | String systemProperty = "os.arch";
36 |
37 | String current = System.setProperty(systemProperty, "aarch64");
38 | try {
39 | Assertions.assertThat(CPU.current()).isEqualTo(CPU.arm64);
40 | } finally {
41 | if (current != null) {
42 | System.setProperty(systemProperty, current);
43 | } else {
44 | System.clearProperty(systemProperty);
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/tools/InstallerPathResolversTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.tools;
25 |
26 | import static org.junit.Assert.assertTrue;
27 |
28 | import java.io.IOException;
29 | import java.io.InputStream;
30 | import java.net.HttpURLConnection;
31 | import java.net.URL;
32 | import java.nio.charset.StandardCharsets;
33 | import java.util.ArrayList;
34 | import java.util.Collection;
35 | import java.util.TreeSet;
36 |
37 | import org.apache.commons.io.IOUtils;
38 | import org.assertj.core.api.Assertions;
39 | import org.junit.Test;
40 | import org.junit.runner.RunWith;
41 | import org.junit.runners.Parameterized;
42 |
43 | import com.google.common.base.Charsets;
44 | import com.google.common.io.Resources;
45 |
46 | import hudson.tools.DownloadFromUrlInstaller;
47 | import net.sf.json.JSONArray;
48 | import net.sf.json.JSONObject;
49 |
50 | @RunWith(Parameterized.class)
51 | public class InstallerPathResolversTest {
52 | private static Collection expectedURLs;
53 |
54 | private DownloadFromUrlInstaller.Installable installable;
55 | private final Platform platform;
56 | private final CPU cpu;
57 | private final boolean testDownload = false;
58 | private final boolean showDownloadURL = false;
59 |
60 | public InstallerPathResolversTest(DownloadFromUrlInstaller.Installable installable, Platform platform, CPU cpu, String testName) {
61 | this.installable = installable;
62 | this.platform = platform;
63 | this.cpu = cpu;
64 | }
65 |
66 | @Parameterized.Parameters(name = "{index}: {3}")
67 | public static Collection data() throws Exception {
68 | Collection testPossibleParams = new ArrayList();
69 |
70 | try (InputStream is = InstallerPathResolversTest.class.getResourceAsStream("expectedURLs.txt")) {
71 | expectedURLs = new TreeSet<>(IOUtils.readLines(is, StandardCharsets.UTF_8));
72 | }
73 |
74 | String installablesJSONStr = Resources.toString(Resources.getResource("updates/jenkins.plugins.nodejs.tools.NodeJSInstaller.json"), Charsets.UTF_8);
75 | JSONArray installables = JSONObject.fromObject(installablesJSONStr).getJSONArray("list");
76 | for (int i = 0; i < installables.size(); i++) {
77 | DownloadFromUrlInstaller.Installable installable = (DownloadFromUrlInstaller.Installable) installables.getJSONObject(i).toBean(DownloadFromUrlInstaller.Installable.class);
78 |
79 | // Not testing pre-0.8.6 version because at the moment, installer
80 | // structure is not handled
81 | if (InstallerPathResolver.Factory.isVersionBlacklisted(installable.id)) {
82 | continue;
83 | }
84 |
85 | for (Platform platform : Platform.values()) {
86 | for (CPU cpu : CPU.values()) {
87 | if (cpu.name().equals("arm64") && (platform == Platform.WINDOWS || platform == Platform.SUNOS)) {
88 | // arm64 are only supported on linux and OSX
89 | continue;
90 | }
91 | if ((cpu.name().equals("armv6l") || cpu.name().equals("armv7l")) && platform != Platform.LINUX) {
92 | // armXl are only supported on linux
93 | continue;
94 | }
95 | if (platform == Platform.AIX && !cpu.name().equals("ppc64")) {
96 | // AIX only supports ppc64
97 | continue;
98 | }
99 | String testName = String.format("version=%s,cpu=%s,platform=%s", installable.id, cpu.name(), platform.name());
100 | testPossibleParams.add(new Object[] { installable, platform, cpu, testName });
101 | }
102 | }
103 | }
104 |
105 | return testPossibleParams;
106 | }
107 |
108 | @Test
109 | public void shouldNodeJSInstallerResolvedPathExist() throws IOException {
110 | InstallerPathResolver installerPathResolver = InstallerPathResolver.Factory.findResolverFor(this.installable.id);
111 | try {
112 | String path = installerPathResolver.resolvePathFor(installable.id, this.platform, this.cpu);
113 | URL url = new URL(installable.url + path);
114 |
115 | if (testDownload) {
116 | assertDownload(url);
117 | } else {
118 | Assertions.assertThat(expectedURLs).contains(url.toString());
119 | }
120 |
121 | if (showDownloadURL) {
122 | System.out.println(url);
123 | }
124 | } catch (IllegalArgumentException e) {
125 | // some combo of platform and cpu are not supported by nodejs
126 | }
127 | }
128 |
129 | private void assertDownload(URL url) throws IOException {
130 | HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
131 | try {
132 | urlConnection.setRequestMethod("GET");
133 | urlConnection.setConnectTimeout(2000);
134 | urlConnection.connect();
135 | int code = urlConnection.getResponseCode();
136 | assertTrue(code >= 200 && code < 300);
137 | } finally {
138 | if (urlConnection != null) {
139 | urlConnection.disconnect();
140 | }
141 | }
142 | }
143 |
144 | }
145 |
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/tools/MirrorNodeJSInstallerTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.tools;
25 |
26 | import static org.mockito.ArgumentMatchers.any;
27 | import static org.mockito.Mockito.mock;
28 | import static org.mockito.Mockito.spy;
29 | import static org.mockito.Mockito.verify;
30 | import static org.mockito.Mockito.when;
31 |
32 | import java.io.IOException;
33 | import java.util.Arrays;
34 | import java.util.HashMap;
35 | import java.util.List;
36 | import java.util.Map;
37 |
38 | import org.assertj.core.api.Assertions;
39 | import org.junit.ClassRule;
40 | import org.junit.Test;
41 | import org.jvnet.hudson.test.JenkinsRule;
42 | import org.mockito.ArgumentCaptor;
43 |
44 | import com.cloudbees.plugins.credentials.Credentials;
45 | import com.cloudbees.plugins.credentials.CredentialsScope;
46 | import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
47 | import com.cloudbees.plugins.credentials.domains.Domain;
48 | import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl;
49 |
50 | import hudson.FilePath;
51 | import hudson.model.Node;
52 | import hudson.model.TaskListener;
53 | import hudson.tools.ToolInstallation;
54 | import hudson.tools.ToolInstallerDescriptor;
55 | import hudson.tools.DownloadFromUrlInstaller.Installable;
56 |
57 | public class MirrorNodeJSInstallerTest {
58 |
59 | @ClassRule
60 | public static JenkinsRule r = new JenkinsRule();
61 |
62 | public static class MockMirrorNodeJSInstaller extends MirrorNodeJSInstaller {
63 |
64 | private Installable installable;
65 |
66 | public MockMirrorNodeJSInstaller(Installable installable, String mirrorURL) {
67 | super(installable.id, mirrorURL, null, 0);
68 | this.installable = installable;
69 | }
70 |
71 | @Override
72 | public boolean isUpToDate(FilePath expectedLocation, Installable i) throws IOException, InterruptedException {
73 | return true;
74 | }
75 |
76 | @SuppressWarnings({ "rawtypes", "unchecked" })
77 | @Override
78 | public ToolInstallerDescriptor> getDescriptor() {
79 | hudson.tools.DownloadFromUrlInstaller.DescriptorImpl> descriptor = mock(hudson.tools.DownloadFromUrlInstaller.DescriptorImpl.class);
80 | try {
81 | when(descriptor.getInstallables()).thenReturn((List) Arrays.asList(installable));
82 | } catch (IOException e) {
83 | }
84 | return descriptor;
85 | }
86 | }
87 |
88 | @Test
89 | public void verify_mirror_url_replacing() throws Exception {
90 | String installationId = "8.2.1";
91 | String mirror = "http://npm.taobao.org/mirrors/node/";
92 |
93 | Installable installable = new Installable();
94 | installable.id = installationId;
95 | installable.url = "https://nodejs.org/dist/v8.2.1/";
96 |
97 | MockMirrorNodeJSInstaller installer = spy(new MockMirrorNodeJSInstaller(installable, mirror));
98 |
99 | ToolInstallation tool = mock(ToolInstallation.class);
100 | when(tool.getHome()).thenReturn("home");
101 |
102 | Node node = r.getInstance().getComputer("").getNode();
103 | installer.performInstallation(tool, node, mock(TaskListener.class));
104 |
105 | ArgumentCaptor captor = ArgumentCaptor.forClass(Installable.class);
106 | verify(installer).isUpToDate(any(FilePath.class), captor.capture());
107 | Assertions.assertThat(captor.getValue().url).startsWith("http://npm.taobao.org/mirrors/node/v8.2.1/node-v8.2.1");
108 | }
109 |
110 | @Test
111 | public void verify_credentials_on_mirror_url() throws Exception {
112 | String credentialsId = "secret";
113 | String installationId = "8.2.1";
114 | String mirror = "http://npm.taobao.org/mirrors/node/";
115 |
116 | Installable installable = new Installable();
117 | installable.id = installationId;
118 | installable.url = "https://nodejs.org/dist/v8.2.1/";
119 |
120 | Credentials credentials = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "", "user", "password");
121 | Map> credentialsMap = new HashMap<>();
122 | credentialsMap.put(Domain.global(), Arrays.asList(credentials));
123 | SystemCredentialsProvider.getInstance().setDomainCredentialsMap(credentialsMap);
124 |
125 | MockMirrorNodeJSInstaller installer = spy(new MockMirrorNodeJSInstaller(installable, mirror));
126 | installer.setCredentialsId(credentialsId);
127 |
128 | ToolInstallation tool = mock(ToolInstallation.class);
129 | when(tool.getHome()).thenReturn("home");
130 |
131 | Node node = r.getInstance().getComputer("").getNode();
132 | installer.performInstallation(tool, node, mock(TaskListener.class));
133 |
134 | ArgumentCaptor captor = ArgumentCaptor.forClass(Installable.class);
135 | verify(installer).isUpToDate(any(FilePath.class), captor.capture());
136 | Assertions.assertThat(captor.getValue().url).startsWith("http://user:password@npm.taobao.org/mirrors/node/node-v8.2.1");
137 | }
138 |
139 | }
140 |
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/tools/NodeJSInstallationMockitoTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.tools;
25 |
26 | import static jenkins.plugins.nodejs.NodeJSConstants.*;
27 | import static org.junit.Assert.assertEquals;
28 | import static org.junit.Assert.assertNull;
29 | import static org.mockito.Mockito.anyMap;
30 | import static org.mockito.Mockito.anyString;
31 | import static org.mockito.Mockito.never;
32 | import static org.mockito.Mockito.spy;
33 | import static org.mockito.Mockito.verify;
34 |
35 | import hudson.EnvVars;
36 | import hudson.Functions;
37 | import org.junit.Test;
38 | import org.jvnet.hudson.test.Issue;
39 |
40 | public class NodeJSInstallationMockitoTest {
41 |
42 | /**
43 | * Ensure the use of {@link EnvVars#put(String, String)} instead
44 | * {@code EnvVars#override(String, String)} to respect the
45 | * {@link ToolInstallation#buildEnvVars(EnvVars)) API documentation.
46 | *
47 | * A lot stuff rely on that logic.
48 | */
49 | @Issue("JENKINS-41947")
50 | @Test
51 | public void test_installer_environment() throws Exception {
52 | String nodeJSHome = "/home/nodejs";
53 | String bin = nodeJSHome + "/bin";
54 |
55 | NodeJSInstallation installer = spy(new NodeJSInstallation("test", nodeJSHome, null));
56 |
57 | EnvVars env = spy(new EnvVars());
58 | installer.buildEnvVars(env);
59 | verify(env, never()).override(anyString(), anyString());
60 | verify(env, never()).overrideAll(anyMap());
61 |
62 | assertEquals("Unexpected value for " + ENVVAR_NODEJS_HOME, nodeJSHome, env.get(ENVVAR_NODEJS_HOME));
63 | assertEquals("Unexpected value for " + ENVVAR_NODE_HOME, nodeJSHome, env.get(ENVVAR_NODE_HOME));
64 | assertEquals("Unexpected value for " + ENVVAR_NODEJS_PATH, Functions.isWindows() ? nodeJSHome : bin, env.get(ENVVAR_NODEJS_PATH));
65 | assertNull("PATH variable should not appear in this environment", env.get("PATH"));
66 | }
67 |
68 | }
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/tools/NodeJSInstallationTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.tools;
25 |
26 | import org.htmlunit.html.HtmlButton;
27 | import org.htmlunit.html.HtmlForm;
28 | import org.htmlunit.html.HtmlPage;
29 | import hudson.model.Computer;
30 | import hudson.tools.InstallSourceProperty;
31 | import hudson.tools.ToolProperty;
32 | import hudson.tools.ToolPropertyDescriptor;
33 | import hudson.util.DescribableList;
34 | import java.io.File;
35 | import java.io.IOException;
36 | import java.lang.reflect.Method;
37 | import jenkins.model.Jenkins;
38 | import jenkins.plugins.nodejs.tools.NodeJSInstallation.DescriptorImpl;
39 | import org.junit.Rule;
40 | import org.junit.Test;
41 | import org.jvnet.hudson.test.Issue;
42 | import org.jvnet.hudson.test.JenkinsRule;
43 | import org.jvnet.hudson.test.recipes.LocalData;
44 | import org.xml.sax.SAXException;
45 |
46 | import static org.junit.Assert.assertEquals;
47 | import static org.junit.Assert.assertFalse;
48 | import static org.junit.Assert.assertNotNull;
49 | import static org.junit.Assert.assertNull;
50 | import static org.junit.Assert.assertTrue;
51 |
52 | public class NodeJSInstallationTest {
53 |
54 | @Rule
55 | public JenkinsRule r = new JenkinsRule();
56 |
57 | /**
58 | * Verify node executable is begin initialised correctly on a slave
59 | * node where {@link Computer#currentComputer()} is {@code null}.
60 | */
61 | @Issue("JENKINS-42232")
62 | @Test
63 | public void test_executable_resolved_on_slave_node() throws Exception {
64 | assertNull(Computer.currentComputer());
65 | NodeJSInstallation installation = new NodeJSInstallation("test_executable_resolved_on_slave_node", "/home/nodejs", null);
66 | Method method = installation.getClass().getDeclaredMethod("getPlatform");
67 | method.setAccessible(true);
68 | Platform platform = (Platform) method.invoke(installation);
69 | assertEquals(Platform.current(), platform);
70 | }
71 |
72 | /**
73 | * Verify that the singleton installation descriptor load data from disk
74 | * when its constructor is called.
75 | */
76 | @LocalData
77 | @Test
78 | @Issue("JENKINS-41535")
79 | public void test_load_at_startup() throws Exception {
80 | File jenkinsHome = r.jenkins.getRootDir();
81 | File installationsFile = new File(jenkinsHome, NodeJSInstallation.class.getName() + ".xml");
82 |
83 | assertTrue("NodeJS installations file has not been copied", installationsFile.exists());
84 | verify();
85 | }
86 |
87 | /**
88 | * Simulates the addition of the new NodeJS via UI and makes sure it works
89 | * and persistent file was created.
90 | */
91 | @Test
92 | @Issue("JENKINS-41535")
93 | public void test_persist_of_nodejs_installation() throws Exception {
94 | File jenkinsHome = r.jenkins.getRootDir();
95 | File installationsFile = new File(jenkinsHome, NodeJSInstallation.class.getName() + ".xml");
96 |
97 | assertFalse("NodeJS installations file already exists", installationsFile.exists());
98 |
99 | HtmlPage p = getConfigurePage();
100 | HtmlForm f = p.getFormByName("config");
101 | HtmlButton b = r.getButtonByCaption(f, "Add NodeJS");
102 | b.click();
103 | r.findPreviousInputElement(b, "name").setValue("myNode");
104 | r.findPreviousInputElement(b, "home").setValue("/tmp/foo");
105 | r.submit(f);
106 | verify();
107 |
108 | assertTrue("NodeJS installations file has not been saved", installationsFile.exists());
109 |
110 | // another submission and verify it survives a roundtrip
111 | p = getConfigurePage();
112 | f = p.getFormByName("config");
113 | r.submit(f);
114 | verify();
115 | }
116 |
117 | private HtmlPage getConfigurePage() throws IOException, SAXException {
118 | return Jenkins.getVersion().toString().startsWith("2") ?
119 | r.createWebClient().goTo("configureTools")
120 | : r.createWebClient().goTo("configure");
121 | }
122 |
123 | private void verify() throws Exception {
124 | NodeJSInstallation[] l = r.get(DescriptorImpl.class).getInstallations();
125 | assertEquals(1, l.length);
126 | r.assertEqualBeans(l[0], new NodeJSInstallation("myNode", "/tmp/foo", JenkinsRule.NO_PROPERTIES), "name,home");
127 |
128 | // by default we should get the auto installer
129 | DescribableList, ToolPropertyDescriptor> props = l[0].getProperties();
130 | assertEquals(1, props.size());
131 | InstallSourceProperty isp = props.get(InstallSourceProperty.class);
132 | assertEquals(1, isp.installers.size());
133 | assertNotNull(isp.installers.get(NodeJSInstaller.class));
134 | }
135 |
136 | }
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/tools/NodeJSInstallerProxyTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.tools;
25 |
26 | import java.lang.reflect.Method;
27 | import java.net.MalformedURLException;
28 | import java.net.URL;
29 | import java.nio.charset.Charset;
30 |
31 | import org.assertj.core.api.Assertions;
32 | import org.junit.ClassRule;
33 | import org.junit.Test;
34 | import org.junit.runner.RunWith;
35 | import org.junit.runners.Parameterized;
36 | import org.junit.runners.Parameterized.Parameters;
37 | import org.jvnet.hudson.test.Issue;
38 | import org.jvnet.hudson.test.JenkinsRule;
39 |
40 | import hudson.EnvVars;
41 | import hudson.ProxyConfiguration;
42 | import hudson.model.StreamBuildListener;
43 | import hudson.model.TaskListener;
44 |
45 | @RunWith(Parameterized.class)
46 | public class NodeJSInstallerProxyTest {
47 |
48 | @Parameters(name = "proxy url = {0}")
49 | public static String[][] data() throws MalformedURLException {
50 | return new String[][] { { "http://proxy.example.org:8080", "*.npm.org\n\nregistry.npm.org" },
51 | { "http://user:password@proxy.example.org:8080", "*.npm.org\n\nregistry.npm.org" }
52 | };
53 | }
54 |
55 | @ClassRule
56 | public static JenkinsRule r = new JenkinsRule();
57 |
58 | private String host;
59 | private int port;
60 | private String username;
61 | private String password;
62 | private String expectedURL;
63 | private TaskListener log;
64 | private String noProxy;
65 |
66 | public NodeJSInstallerProxyTest(String url, String noProxy) throws Exception {
67 | URL proxyURL = new URL(url);
68 |
69 | this.log = new StreamBuildListener(System.out, Charset.defaultCharset());
70 | this.expectedURL = url;
71 | this.noProxy = noProxy;
72 | this.host = proxyURL.getHost();
73 | this.port = proxyURL.getPort();
74 | if (proxyURL.getUserInfo() != null) {
75 | String[] userInfo = proxyURL.getUserInfo().split(":");
76 | this.username = userInfo[0];
77 | this.password = userInfo[1];
78 | }
79 | }
80 |
81 | @Issue("JENKINS-29266")
82 | @Test
83 | public void test_proxy_settings() throws Exception {
84 | r.getInstance().proxy = new ProxyConfiguration(host, port, username, password);
85 |
86 | NodeJSInstaller installer = new NodeJSInstaller("test-id", "grunt", NodeJSInstaller.DEFAULT_NPM_PACKAGES_REFRESH_HOURS);
87 | EnvVars env = new EnvVars();
88 | Method method = installer.getClass().getDeclaredMethod("buildProxyEnvVars", EnvVars.class, TaskListener.class);
89 | method.setAccessible(true);
90 | method.invoke(installer, env, log);
91 |
92 | Assertions.assertThat(env.keySet()).contains("HTTP_PROXY", "HTTPS_PROXY");
93 | Assertions.assertThat(env.get("HTTP_PROXY")).isEqualTo(expectedURL);
94 | Assertions.assertThat(env.get("HTTPS_PROXY")).isEqualTo(expectedURL);
95 | Assertions.assertThat(env.keySet()).doesNotContain("NO_PROXY");
96 | }
97 |
98 | @Test
99 | public void test_no_proxy_settings() throws Exception {
100 | r.getInstance().proxy = new ProxyConfiguration(host, port, username, password, noProxy);
101 |
102 | NodeJSInstaller installer = new NodeJSInstaller("test-id", "grunt", NodeJSInstaller.DEFAULT_NPM_PACKAGES_REFRESH_HOURS);
103 | EnvVars env = new EnvVars();
104 | Method method = installer.getClass().getDeclaredMethod("buildProxyEnvVars", EnvVars.class, TaskListener.class);
105 | method.setAccessible(true);
106 | method.invoke(installer, env, log);
107 |
108 | Assertions.assertThat(env.keySet()).contains("HTTP_PROXY", "HTTPS_PROXY");
109 | Assertions.assertThat(env.get("NO_PROXY")).isEqualTo("*.npm.org,registry.npm.org");
110 | }
111 |
112 | }
--------------------------------------------------------------------------------
/src/test/java/jenkins/plugins/nodejs/tools/ToolsUtilsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018, Nikolas Falco
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package jenkins.plugins.nodejs.tools;
25 |
26 | import static org.mockito.Mockito.mock;
27 | import static org.mockito.Mockito.mockStatic;
28 | import static org.mockito.Mockito.when;
29 |
30 | import hudson.model.Node;
31 | import org.assertj.core.api.Assertions;
32 | import org.junit.After;
33 | import org.junit.Before;
34 | import org.junit.Test;
35 | import org.mockito.MockedStatic;
36 |
37 | public class ToolsUtilsTest {
38 |
39 | private MockedStatic staticCpu;
40 |
41 | @Before
42 | public void setup() {
43 | CPU[] cpuValues = CPU.values();
44 | staticCpu = mockStatic(CPU.class);
45 | staticCpu.when(CPU::values).thenReturn(cpuValues);
46 | }
47 |
48 | @After
49 | public void tearDown() {
50 | staticCpu.close();
51 | }
52 |
53 | @Test
54 | public void nodejs_supports_32bit_64bit_on_windows_linux_mac() throws Exception {
55 | Node currentNode = mock(Node.class);
56 |
57 | when(CPU.of(currentNode)).thenReturn(CPU.amd64);
58 | CPU cpu = ToolsUtils.getCPU(currentNode, true);
59 | Assertions.assertThat(cpu).isEqualTo(CPU.i386);
60 |
61 | cpu = ToolsUtils.getCPU(currentNode);
62 | Assertions.assertThat(cpu).isEqualTo(CPU.amd64);
63 | }
64 |
65 | @Test(expected = DetectionFailedException.class)
66 | public void nodejs_doesn_t_supports_32bit_on_armv64() throws Exception {
67 | Node currentNode = mock(Node.class);
68 |
69 | when(CPU.of(currentNode)).thenReturn(CPU.arm64);
70 | ToolsUtils.getCPU(currentNode, true);
71 | }
72 |
73 | @Test
74 | public void nodejs_supports_32bit_on_armv6_armv7() throws Exception {
75 | Node currentNode = mock(Node.class);
76 |
77 | when(CPU.of(currentNode)).thenReturn(CPU.armv7l);
78 | CPU cpu = ToolsUtils.getCPU(currentNode, true);
79 | Assertions.assertThat(cpu).isEqualTo(CPU.armv7l);
80 |
81 | when(CPU.of(currentNode)).thenReturn(CPU.armv6l);
82 | cpu = ToolsUtils.getCPU(currentNode, true);
83 | Assertions.assertThat(cpu).isEqualTo(CPU.armv6l);
84 | }
85 |
86 | }
--------------------------------------------------------------------------------
/src/test/resources/jenkins/plugins/nodejs/NodeJSSerialisationTest/test_reloading_job_configuration_contains_saved_cache_strategy_buildWrapper/jobs/test/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | false
6 |
7 |
8 | true
9 | false
10 | false
11 | false
12 |
13 | false
14 |
15 |
16 |
17 |
18 | NodeJS test
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/test/resources/jenkins/plugins/nodejs/NodeJSSerialisationTest/test_reloading_job_configuration_contains_saved_cache_strategy_interpreter/jobs/test/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | false
6 |
7 |
8 | true
9 | false
10 | false
11 | false
12 |
13 | false
14 |
15 |
16 |
17 |
18 |
19 | NodeJS test
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/test/resources/jenkins/plugins/nodejs/NodeJSSerialisationTest/test_serialisation_is_compatible_with_version_1_2_x_buildWrapper/jobs/test/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | false
6 |
7 |
8 | true
9 | false
10 | false
11 | false
12 |
13 | false
14 |
15 |
16 |
17 |
18 | NodeJS test
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/test/resources/jenkins/plugins/nodejs/NodeJSSerialisationTest/test_serialisation_is_compatible_with_version_1_2_x_interpreter/jobs/test/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | false
6 |
7 |
8 | true
9 | false
10 | false
11 | false
12 |
13 | false
14 |
15 |
16 |
17 |
18 |
19 | NodeJS test
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/test/resources/jenkins/plugins/nodejs/configfiles/npmrc.config:
--------------------------------------------------------------------------------
1 | ; cli configs
2 | global = true
3 | long = true
4 | user-agent = "npm/3.10.3 node/v0.10.42 linux x64"
5 |
6 | ; userconfig /var/lib/jenkins/.npmrc
7 | always-auth = true
8 |
9 | ; builtin config undefined
10 | prefix="/var/lib"
11 |
12 | ; globalconfig /var/lib/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_6.x/etc/npmrc
13 | prefix = "/var/lib/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_6.x"
14 |
15 | ; default values
16 | access = null
17 | also = null
18 | ; always-auth = false (overridden)
19 | bin-links = true
20 | ca = null
21 | cache = "/var/lib/jenkins/.npm"
22 | cache-lock-retries = 10
23 | cache-lock-stale = 60000
24 |
25 | ; parse error test
26 | browser
--------------------------------------------------------------------------------
/src/test/resources/jenkins/plugins/nodejs/configuration-as-code.yaml:
--------------------------------------------------------------------------------
1 | unclassified:
2 | globalConfigFiles:
3 | configs:
4 | - npm:
5 | comment: "myComment"
6 | content: "myContent"
7 | id: "myconfigfile"
8 | name: "myConfig"
9 | providerId: "jenkins.plugins.nodejs.configfiles.NPMConfig"
10 | npm9Format: true
11 | registries:
12 | - hasScopes: true
13 | scopes: "myScope"
14 | url: "registryUrl"
15 | tool:
16 | nodejs:
17 | installations:
18 | - name: "myNode"
19 | properties:
20 | - installSource:
21 | installers:
22 | - nodeJSInstaller:
23 | force32Bit: true
24 | id: "14.4.0"
25 | npmPackages: "globalPackages"
26 | npmPackagesRefreshHours: 75
27 | - command:
28 | command: "install npm"
29 | label: "npm command"
30 | toolHome: "/my/path/1"
31 | - zip:
32 | label: "npm zip"
33 | subdir: "/my/path/2"
34 | url: "http://fake.com"
35 | - batchFile:
36 | command: "run batch command"
37 | label: "npm batch"
38 | toolHome: "/my/path/3"
39 | - home: "/onePath"
40 | name: "anotherNodeWithNoInstall"
41 |
--------------------------------------------------------------------------------
/src/test/resources/jenkins/plugins/nodejs/dsl/NodeJSBuild.pipeline:
--------------------------------------------------------------------------------
1 | pipeline {
2 | agent any
3 |
4 | stages {
5 | stage('Build') {
6 | steps {
7 | nodejs(nodeJSInstallationName: 'Node 6.x', configId: null) {
8 | sh 'npm config ls'
9 | }
10 | }
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/src/test/resources/jenkins/plugins/nodejs/dsl/NodeJSInstallation.pipeline:
--------------------------------------------------------------------------------
1 | pipeline {
2 | agent any
3 |
4 | tools {
5 | nodejs 'Node 6.x'
6 | }
7 |
8 | stages {
9 | stage('Build') {
10 | steps {
11 | sh 'npm -version'
12 | }
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/test/resources/jenkins/plugins/nodejs/tools/NodeJSInstallationTest/test_load_at_startup/jenkins.plugins.nodejs.tools.NodeJSInstallation.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | myNode
6 | /tmp/foo
7 |
8 |
9 |
10 |
11 |
12 | 72
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/test/resources/jenkins/plugins/nodejs/tools/test.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenkinsci/nodejs-plugin/2f4929d6ecfd4d09b947a50a0ca0095ed175d0e4/src/test/resources/jenkins/plugins/nodejs/tools/test.tar.gz
--------------------------------------------------------------------------------