-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#317: added BuildCommandlet #340
base: main
Are you sure you want to change the base?
Changes from all commits
ebc970a
c5a3df1
99eb686
fdf83cb
ea88658
efc9081
fbfec39
66dcb1a
823b241
ed33422
f9cdca7
976abb3
72075c9
c129a41
1299a62
6afebdb
61a4c9f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package com.devonfw.tools.ide.commandlet; | ||
|
||
import com.devonfw.tools.ide.cli.CliException; | ||
import com.devonfw.tools.ide.context.IdeContext; | ||
import com.devonfw.tools.ide.property.StringProperty; | ||
import com.devonfw.tools.ide.tool.ToolCommandlet; | ||
import com.devonfw.tools.ide.tool.gradle.Gradle; | ||
import com.devonfw.tools.ide.tool.mvn.Mvn; | ||
import com.devonfw.tools.ide.tool.npm.Npm; | ||
|
||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
|
||
import static com.devonfw.tools.ide.variable.IdeVariables.GRADLE_BUILD_OPTS; | ||
import static com.devonfw.tools.ide.variable.IdeVariables.MVN_BUILD_OPTS; | ||
import static com.devonfw.tools.ide.variable.IdeVariables.NPM_BUILD_OPTS; | ||
|
||
/** | ||
* Build tool {@link Commandlet} for automatically detecting build configuration files and running the respective tool. | ||
*/ | ||
public class BuildCommandlet extends Commandlet { | ||
|
||
/** | ||
* The arguments to build with. | ||
*/ | ||
public StringProperty arguments; | ||
|
||
/** | ||
* The constructor. | ||
* | ||
* @param context the {@link IdeContext}. | ||
*/ | ||
public BuildCommandlet(IdeContext context) { | ||
|
||
super(context); | ||
addKeyword(getName()); | ||
this.arguments = add(new StringProperty("", false, true, "args")); | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
|
||
return "build"; | ||
} | ||
|
||
@Override | ||
public void run() { | ||
|
||
Path buildPath = this.context.getCwd(); | ||
String[] defaultToolOptions = new String[0]; | ||
|
||
if (buildPath != null) { | ||
ToolCommandlet commandlet = null; | ||
if (Files.exists(buildPath.resolve("pom.xml"))) { | ||
commandlet = this.context.getCommandletManager().getCommandlet(Mvn.class); | ||
defaultToolOptions = getDefaultToolOptions(MVN_BUILD_OPTS.getName()); | ||
} else if (Files.exists(buildPath.resolve("build.gradle"))) { | ||
commandlet = this.context.getCommandletManager().getCommandlet(Gradle.class); | ||
defaultToolOptions = getDefaultToolOptions(GRADLE_BUILD_OPTS.getName()); | ||
} else if (Files.exists(buildPath.resolve("package.json"))) { | ||
if (Files.exists(buildPath.resolve("yarn.lock"))) { | ||
// TODO: add yarn here | ||
} else { | ||
commandlet = this.context.getCommandletManager().getCommandlet(Npm.class); | ||
|
||
defaultToolOptions = getDefaultToolOptions(NPM_BUILD_OPTS.getName()); | ||
} | ||
} else { | ||
throw new CliException("Could not find build descriptor - no pom.xml, build.gradle, or package.json found!"); | ||
} | ||
jan-vcapgemini marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if (this.arguments.asArray().length != 0) { | ||
defaultToolOptions = this.arguments.asArray(); | ||
} | ||
|
||
if (commandlet != null) { | ||
commandlet.runTool(null, defaultToolOptions); | ||
} | ||
} | ||
|
||
} | ||
|
||
private String[] getDefaultToolOptions(String buildOptionName) { | ||
|
||
String[] defaultToolOptions; | ||
defaultToolOptions = this.context.getVariables().get(buildOptionName).split(" "); | ||
return defaultToolOptions; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -52,6 +52,18 @@ public interface IdeVariables { | |||||
|
||||||
/** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getWorkspaceName() WORKSPACE}. */ | ||||||
|
||||||
/** {@link VariableDefinition} for default build options of mvn */ | ||||||
VariableDefinitionString MVN_BUILD_OPTS = new VariableDefinitionString("MVN_BUILD_OPTS", null, c -> ""); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As pointed out: https://github.com/devonfw/ide/blob/cdf4af5de21489f3fdcbfdab41af858822e0d598/scripts/src/main/resources/scripts/command/mvn#L354
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the code snippet it uses |
||||||
|
||||||
/** {@link VariableDefinition} for default build options of npm */ | ||||||
VariableDefinitionString NPM_BUILD_OPTS = new VariableDefinitionString("NPM_BUILD_OPTS", null, c -> ""); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one seems more tricky - see Maybe we should address this one in a separate PR and merge as is? So far this would be my suggestion to make better progress... So either create an issue for this and link here as comment so I can resolve or already address in this PR adding even more new features and complexity. |
||||||
|
||||||
/** {@link VariableDefinition} for default build options of gradle */ | ||||||
VariableDefinitionString GRADLE_BUILD_OPTS = new VariableDefinitionString("GRADLE_BUILD_OPTS", null, c -> ""); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again see here: https://github.com/devonfw/ide/blob/cdf4af5de21489f3fdcbfdab41af858822e0d598/scripts/src/main/resources/scripts/command/gradle#L91
Suggested change
|
||||||
|
||||||
/** {@link VariableDefinition} for default build options of yarn */ | ||||||
VariableDefinitionString YARN_BUILD_OPTS = new VariableDefinitionString("YARN_BUILD_OPTS", null, c -> ""); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
|
||||||
/** {@link VariableDefinition} for options of jasypt */ | ||||||
VariableDefinitionString JASYPT_OPTS = new VariableDefinitionString("JASYPT_OPTS", null, | ||||||
c -> "algorithm=PBEWITHHMACSHA512ANDAES_256 ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator"); | ||||||
|
@@ -61,7 +73,7 @@ public interface IdeVariables { | |||||
|
||||||
/** A {@link Collection} with all pre-defined {@link VariableDefinition}s. */ | ||||||
Collection<VariableDefinition<?>> VARIABLES = List.of(PATH, HOME, WORKSPACE_PATH, IDE_HOME, IDE_ROOT, WORKSPACE, IDE_TOOLS, CREATE_START_SCRIPTS, | ||||||
IDE_MIN_VERSION, MVN_VERSION, M2_REPO, DOCKER_EDITION, JASYPT_OPTS, MAVEN_ARGS, PROJECT_NAME); | ||||||
IDE_MIN_VERSION, MVN_VERSION, M2_REPO, DOCKER_EDITION, MVN_BUILD_OPTS, NPM_BUILD_OPTS, GRADLE_BUILD_OPTS, YARN_BUILD_OPTS, JASYPT_OPTS, MAVEN_ARGS, PROJECT_NAME); | ||||||
|
||||||
/** | ||||||
* @param name the name of the requested {@link VariableDefinition}. | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package com.devonfw.tools.ide.commandlet; | ||
|
||
import com.devonfw.tools.ide.context.AbstractIdeContextTest; | ||
import com.devonfw.tools.ide.context.IdeTestContext; | ||
import com.devonfw.tools.ide.log.IdeLogLevel; | ||
import com.devonfw.tools.ide.os.SystemInfo; | ||
import com.devonfw.tools.ide.os.SystemInfoMock; | ||
import org.junit.jupiter.api.Test; | ||
|
||
/** | ||
* Test of {@link BuildCommandlet}. | ||
*/ | ||
public class BuildCommandletTest extends AbstractIdeContextTest { | ||
|
||
private static final String PROJECT_BUILD = "build"; | ||
|
||
/** | ||
* Tests a {@link com.devonfw.tools.ide.tool.mvn.Mvn} build without arguments and expects defaults to be taken from ide.properties. | ||
*/ | ||
@Test | ||
public void testMvnBuildWithoutProvidedArgumentsUsesDefaultOptions() { | ||
|
||
IdeTestContext context = newContext(PROJECT_BUILD); | ||
BuildCommandlet buildCommandlet = context.getCommandletManager().getCommandlet(BuildCommandlet.class); | ||
context.setCwd(context.getWorkspacePath().resolve("mvn"), context.getWorkspacePath().toString(), context.getIdeHome()); | ||
buildCommandlet.run(); | ||
assertLogMessage(context, IdeLogLevel.SUCCESS, "Successfully installed java in version 17.0.10_7"); | ||
assertLogMessage(context, IdeLogLevel.SUCCESS, "Successfully installed mvn in version 3.9.6"); | ||
assertLogMessage(context, IdeLogLevel.INFO, "mvn clean install"); | ||
} | ||
|
||
/** | ||
* Tests a {@link com.devonfw.tools.ide.tool.mvn.Mvn} build with provided arguments. | ||
*/ | ||
@Test | ||
public void testMvnBuildWithProvidedArguments() { | ||
|
||
IdeTestContext context = newContext(PROJECT_BUILD); | ||
BuildCommandlet buildCommandlet = context.getCommandletManager().getCommandlet(BuildCommandlet.class); | ||
context.setCwd(context.getWorkspacePath().resolve("mvn"), context.getWorkspacePath().toString(), context.getIdeHome()); | ||
buildCommandlet.arguments.addValue("clean"); | ||
buildCommandlet.arguments.addValue("install"); | ||
buildCommandlet.run(); | ||
assertLogMessage(context, IdeLogLevel.SUCCESS, "Successfully installed java in version 17.0.10_7"); | ||
assertLogMessage(context, IdeLogLevel.SUCCESS, "Successfully installed mvn in version 3.9.6"); | ||
assertLogMessage(context, IdeLogLevel.INFO, "mvn clean install"); | ||
} | ||
|
||
/** | ||
* Tests a {@link com.devonfw.tools.ide.tool.gradle.Gradle} build with provided arguments. | ||
*/ | ||
@Test | ||
public void testGradleBuildWithProvidedArguments() { | ||
|
||
IdeTestContext context = newContext(PROJECT_BUILD); | ||
BuildCommandlet buildCommandlet = context.getCommandletManager().getCommandlet(BuildCommandlet.class); | ||
context.setCwd(context.getWorkspacePath().resolve("gradle"), context.getWorkspacePath().toString(), context.getIdeHome()); | ||
buildCommandlet.arguments.addValue("task1"); | ||
buildCommandlet.arguments.addValue("task2"); | ||
buildCommandlet.run(); | ||
assertLogMessage(context, IdeLogLevel.SUCCESS, "Successfully installed java in version 17.0.10_7"); | ||
assertLogMessage(context, IdeLogLevel.SUCCESS, "Successfully installed gradle in version 8.7"); | ||
assertLogMessage(context, IdeLogLevel.INFO, "gradle task1 task2"); | ||
} | ||
|
||
/** | ||
* Tests a {@link com.devonfw.tools.ide.tool.npm.Npm} build with provided arguments. | ||
*/ | ||
@Test | ||
public void testNpmBuildWithProvidedArguments() { | ||
|
||
SystemInfo systemInfo = SystemInfoMock.of("linux"); | ||
IdeTestContext context = newContext(PROJECT_BUILD); | ||
context.setSystemInfo(systemInfo); | ||
BuildCommandlet buildCommandlet = context.getCommandletManager().getCommandlet(BuildCommandlet.class); | ||
context.setCwd(context.getWorkspacePath().resolve("npm"), context.getWorkspacePath().toString(), context.getIdeHome()); | ||
buildCommandlet.arguments.addValue("start"); | ||
buildCommandlet.arguments.addValue("test"); | ||
buildCommandlet.run(); | ||
assertLogMessage(context, IdeLogLevel.SUCCESS, "Successfully installed node in version v18.19.1"); | ||
assertLogMessage(context, IdeLogLevel.SUCCESS, "Successfully installed npm in version 9.9.2"); | ||
assertLogMessage(context, IdeLogLevel.INFO, "npm start test"); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
JAVA_VERSION=17.0.10_7 | ||
MAVEN_VERSION=3.9.6 | ||
NODE_VERSION=v18.19.1 | ||
NPM_VERSION=9.9.2 | ||
GRADLE_VERSION=8.7 | ||
MVN_BUILD_OPTS=clean install | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the default that is supposed to be build-in. Either remove or override with something else to test the overriding mechanism. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#!/bin/bash | ||
echo "gradle $*" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#!/bin/bash | ||
echo "mvn $*" |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#!/bin/bash | ||
echo "npm $*" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
:toc: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As discussed in our meetings we do not want to come back to having help documentation on github in asciidoc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For this we already agreed in the team to add yet another help property for the detailed description of a commandlet. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Implemented: |
||
toc::[] | ||
|
||
= build | ||
The `build` commandlet is an abstraction of build systems like link:mvn.asciidoc[maven], link:gradle.asciidoc[gradle], link:npm.asciidoc[yarn], link:npm.asciidoc[npm], etc. | ||
It will auto-detect your build-system (via existence of files like `pom.xml`, `package.json`, etc.). According to this detection, it will simply delegate to the according commandlet of the specific build system. If that build-system is not yet available it will be downloaded and installed automatically. | ||
|
||
So `ide build` allows users to build any project without bothering about the build-system. Further specific build options can be configured per project. This makes `ide build` a universal part of every _definition of done_. Before pushing your changes, please always run the following command to verify the build: | ||
|
||
`ide build` | ||
|
||
You may also supply additional arguments as `ide build «args»`. This will simply delegate these arguments to the detected build command (e.g. call `mvn «args»`). |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
:toc: | ||
toc::[] | ||
|
||
= gradle | ||
|
||
The `gradle` commandlet allows to install, configure, and launch https://gradle.org/[gradle]. It is similar to https://docs.gradle.org/5.3.1/userguide/gradle_wrapper.html[gradle-wrapper]. So calling `ide gradle «args»` is more or less the same as calling `gradle «args»` but with the benefit that the version of gradle preferred by your project is used (and will be installed if not yet available). | ||
|
||
The arguments (`ide gradle «args»`) are explained by the following table: | ||
|
||
.Usage of `ide gradle` | ||
[options="header"] | ||
|======================= | ||
|*Argument(s)* |*Meaning* | ||
|`«args»` |run gradle with the given arguments (`«args»`) | ||
|======================= | ||
|
||
There are link:variables.asciidoc[variables] that can be used for gradle. | ||
These are explained by the following table: | ||
|
||
.Variables of IDEasy for gradle | ||
[options="header"] | ||
|======================= | ||
|*Variable*|*Meaning* | ||
|*`GRADLE_VERSION`* |The version of the tool gradle to install and use. | ||
|*`GRADLE_BUILD_OPTS`* |The default arguments to use for the gradle build process e.g. `project1`. | ||
|======================= |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
:toc: | ||
toc::[] | ||
|
||
= mvn | ||
|
||
The `mvn` commandlet allows to install, configure, and launch https://maven.apache.org/[maven]. It is similar to https://github.com/takari/maven-wrapper[maven-wrapper] and https://github.com/dansomething/mdub[mdub]. So calling `ide mvn «args»` is more or less the same as calling `mvn «args»` but with the benefit that the version of maven preferred by your project is used (and will be installed if not yet available). | ||
|
||
The arguments (`ide mvn «args»`) are explained by the following table: | ||
|
||
.Usage of `ide mvn` | ||
[options="header"] | ||
|======================= | ||
|*Argument(s)* |*Meaning* | ||
| |run default build, link:configuration.asciidoc[configurable] via `MVN_BUILD_OPTS` | ||
|`«args»` |run maven with the given arguments (`«args»`) | ||
|======================= | ||
|
||
There are link:variables.asciidoc[variables] that can be used for mvn. | ||
These are explained by the following table: | ||
|
||
.Variables of IDEasy for mvn | ||
[options="header"] | ||
|======================= | ||
|*Variable*|*Meaning* | ||
|*`MVN_VERSION`* |The version of the tool mvn to install and use. | ||
|*`MVN_BUILD_OPTS`* |The default options to use for the mvn build process e.g. `clean install`. | ||
|======================= |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
:toc: | ||
toc::[] | ||
|
||
= npm | ||
|
||
The `npm` commandlet allows to install, configure, and launch https://www.npmjs.com/[npm]. Calling `ide npm «args»` is more or less the same as calling `npm «args»` but with the benefit that the version of npm preferred by your project is used (and will be installed if not yet available). | ||
|
||
The arguments (`ide npm «args»`) are explained by the following table: | ||
|
||
.Usage of `ide npm` | ||
[options="header"] | ||
|======================= | ||
|*Argument(s)* |*Meaning* | ||
| |run default build, link:configuration.asciidoc[configurable] via `NPM_BUILD_OPTS` | ||
|`«args»` |run NPM with the given arguments (`«args»`) | ||
|======================= | ||
|
||
There are link:variables.asciidoc[variables] that can be used for npm. | ||
These are explained by the following table: | ||
|
||
.Variables of IDEasy for npm | ||
[options="header"] | ||
|======================= | ||
|*Variable*|*Meaning* | ||
|*`NPM_VERSION`* |The version of the tool npm to install and use. | ||
|*`NPM_BUILD_OPTS`* |The default options to use for the npm build process e.g. `run start`. | ||
|======================= |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
:toc: | ||
toc::[] | ||
|
||
= yarn | ||
|
||
The `yarn` commandlet allows to install, configure, and launch https://www.npmjs.com/[npm]. Calling `ide yarn «args»` is more or less the same as calling `yarn «args»` but with the benefit that the version of npm preferred by your project is used (and will be installed if not yet available). | ||
|
||
The arguments (`ide yarn «args»`) are explained by the following table: | ||
|
||
.Usage of `ide yarn` | ||
[options="header"] | ||
|======================= | ||
|*Argument(s)* |*Meaning* | ||
|`«args»` |run yarn with the given arguments (`«args»`) | ||
|======================= | ||
|
||
There are link:variables.asciidoc[variables] that can be used for yarn. | ||
These are explained by the following table: | ||
|
||
.Variables of IDEasy for yarn | ||
[options="header"] | ||
|======================= | ||
|*Variable*|*Meaning* | ||
|*`YARN_VERSION`* |The version of the tool yarn to install and use. | ||
|*`YARN_BUILD_OPTS`* |The default options to use for the yarn build process e.g. `run start`. | ||
|======================= |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so if
buildPath
(akacwd
) would benull
then we do nothing?IMHO this will never happen but if we want to handle this explicitly, I would rather do something like this: