Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

#353 Implement tool commandlet for pip #1097

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions .github/workflows/nightly-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,27 @@ jobs:
with:
name: natives-${{ matrix.os }}
path: cli/target/ideasy*
- name: Build MSI with WixToolSet
if: runner.os == 'Windows'
shell: bash
run: |
cd documentation
mvn -B -ntp clean install
cd ..
mkdir -p windows-installer/msi-files
cp documentation/target/generated-docs/IDEasy.pdf windows-installer/msi-files
cp -r cli/target/package/* windows-installer/msi-files
cd windows-installer
dotnet tool install --global wix --version 5.0.2
wix extension add WixToolset.UI.wixext/5.0.2
wix extension add WixToolset.Util.wixext/5.0.2
wix build Package.wxs WixUI_IDEasySetup.wxs -loc Package.en-us.wxl -ext WixToolset.UI.wixext -ext WixToolset.Util.wixext -o ideasy.msi
- name: Upload MSI
if: runner.os == 'Windows'
uses: actions/upload-artifact@v4
with:
name: msi
path: windows-installer/ideasy.msi

# Downloads all native image artifacts to cli/target and builds the project using assemblies for final deployment to OSSRH Nexus
deploy:
Expand All @@ -52,10 +73,9 @@ jobs:
- name: Download natives and build project
uses: actions/download-artifact@v4
with:
pattern: natives-*
path: ./cli/target/
- name: Deploy to OSSRH nexus
env:
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
run: mvn --settings .mvn/settings.xml -DskipTests=true -Darchetype.test.skip=true -Dgpg.skip=true -Dstyle.color=always -B -ntp -Passembly,deploy deploy
run: mvn --settings .mvn/settings.xml -DskipTests=true -Darchetype.test.skip=true -Dgpg.skip=true -Dstyle.color=always -B -ntp -Passembly,msi,deploy deploy
25 changes: 23 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,27 @@ jobs:
with:
name: natives-${{ matrix.os }}
path: cli/target/ideasy*
- name: Build MSI with WixToolSet
if: runner.os == 'Windows'
shell: bash
run: |
cd documentation
mvn -B -ntp clean install
cd ..
mkdir -p windows-installer/msi-files
cp documentation/target/generated-docs/IDEasy.pdf windows-installer/msi-files
cp -r cli/target/package/* windows-installer/msi-files
cd windows-installer
dotnet tool install --global wix --version 5.0.2
wix extension add WixToolset.UI.wixext/5.0.2
wix extension add WixToolset.Util.wixext/5.0.2
wix build Package.wxs WixUI_IDEasySetup.wxs -loc Package.en-us.wxl -ext WixToolset.UI.wixext -ext WixToolset.Util.wixext -o ideasy.msi
- name: Upload MSI
if: runner.os == 'Windows'
uses: actions/upload-artifact@v4
with:
name: msi
path: windows-installer/ideasy.msi

# Downloads all native image artifacts to cli/target and builds the project using assemblies for final deployment to Maven Central.
# The version number for the next build will be incremented automatically.
Expand All @@ -62,7 +83,6 @@ jobs:
- name: Download natives and build project
uses: actions/download-artifact@v4
with:
pattern: natives-*
path: ./cli/target/
- name: Create assemblies and publish to Apache Maven Central
run: |
Expand All @@ -78,7 +98,7 @@ jobs:
git tag -a "release/${next_version}" -m "tagged version ${next_version}"
export GPG_TTY=$TTY
mkdir -p ./cli/target/
mvn --settings .mvn/settings.xml -B -ntp deploy -Passembly,deploy -Dgpg.pin.entry.mode=loopback -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }}
mvn --settings .mvn/settings.xml -B -ntp deploy -Passembly,msi,deploy -Dgpg.pin.entry.mode=loopback -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }}
env:
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
Expand All @@ -102,6 +122,7 @@ jobs:
git push --tags
noDotVersion="${current_version//.}"
gh release create "release/${current_version}" ./cli/target/*.tar.gz --title "${current_version}" --notes "# Download
* Windows-MSI: https://repo1.maven.org/maven2/com/devonfw/tools/IDEasy/ide-cli/${current_version}/ide-cli-${current_version}.msi
* Windows: https://repo1.maven.org/maven2/com/devonfw/tools/IDEasy/ide-cli/${current_version}/ide-cli-${current_version}-windows-x64.tar.gz
* Mac(arm): https://repo1.maven.org/maven2/com/devonfw/tools/IDEasy/ide-cli/${current_version}/ide-cli-${current_version}-mac-arm.tar.gz
* Mac(x64): https://repo1.maven.org/maven2/com/devonfw/tools/IDEasy/ide-cli/${current_version}/ide-cli-${current_version}-mac-x64.tar.gz
Expand Down
2 changes: 1 addition & 1 deletion .mvn/maven.config
Original file line number Diff line number Diff line change
@@ -1 +1 @@
-Drevision=2025.02.002-beta-SNAPSHOT
-Drevision=2025.02.002-SNAPSHOT
3 changes: 3 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ This file documents all notable changes to https://github.com/devonfw/IDEasy[IDE

Release with new features and bugfixes:

* https://github.com/devonfw/IDEasy/issues/420[#420]: Add MSI Build and Deployment
* https://github.com/devonfw/IDEasy/issues/1061[#1061]: Mac: no such file or directory: /_ide/installation/functions
* https://github.com/devonfw/IDEasy/issues/38[#38]: Implement ToolCommandlet for Python
* https://github.com/devonfw/IDEasy/issues/38[#353]: Implement ToolCommandlet for pip

The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/22?closed=1[milestone 2025.02.002].

Expand Down
52 changes: 50 additions & 2 deletions cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<jline.version>3.24.1</jline.version>
<jansi.version>2.4.1</jansi.version>
<jackson.version>2.18.2</jackson.version>
<build.helper.maven.plugin.version>3.6.0</build.helper.maven.plugin.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -64,7 +65,7 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.3</version>
<version>1.5.16</version>
<!--optional>true</optional-->
</dependency>
<dependency>
Expand Down Expand Up @@ -250,13 +251,60 @@
<arg>--enable-url-protocols=http,https</arg>
<arg>-march=compatibility</arg>
<arg>--initialize-at-build-time=org.apache.commons</arg>
<arg>-H:IncludeResourceBundles=com.sun.org.apache.xml.internal.res.XMLErrorResources,com.sun.org.apache.xerces.internal.impl.msg.XMLMessages</arg>
<arg>-H:IncludeResourceBundles=com.sun.org.apache.xml.internal.res.XMLErrorResources,com.sun.org.apache.xerces.internal.impl.msg.XMLMessages
</arg>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>msi</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<move file="${project.basedir}/target/msi/ideasy.msi"
tofile="${project.basedir}/target/${project.artifactId}-${revision}.msi"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>${build.helper.maven.plugin.version}</version>
<executions>
<execution>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.basedir}/target/${project.artifactId}-${revision}.msi</file>
<type>msi</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ private void createStartScript(String ide, String workspace) {
scriptContent = "#!/usr/bin/env bash\n"
+ "cd \"$(dirname \"$0\")\"\n"
+ "cd workspaces/" + workspace + "\n"
+ "ide " + ide + "\n";
+ "ideasy " + ide + "\n";
}
FileAccess fileAccess = this.context.getFileAccess();
fileAccess.writeFileContent(scriptContent, scriptPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
import com.devonfw.tools.ide.tool.npm.Npm;
import com.devonfw.tools.ide.tool.oc.Oc;
import com.devonfw.tools.ide.tool.pgadmin.PgAdmin;
import com.devonfw.tools.ide.tool.python.Python;
import com.devonfw.tools.ide.tool.pip.Pip;
import com.devonfw.tools.ide.tool.quarkus.Quarkus;
import com.devonfw.tools.ide.tool.sonar.Sonar;
import com.devonfw.tools.ide.tool.terraform.Terraform;
Expand Down Expand Up @@ -124,6 +126,8 @@ public CommandletManagerImpl(IdeContext context) {
add(new GraalVm(context));
add(new PgAdmin(context));
add(new LazyDocker(context));
add(new Python(context));
add(new Pip(context));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.property.ToolProperty;
import com.devonfw.tools.ide.tool.IdeasyCommandlet;
import com.devonfw.tools.ide.tool.ToolCommandlet;

/**
Expand All @@ -21,7 +22,7 @@ public UninstallCommandlet(IdeContext context) {

super(context);
addKeyword(getName());
this.tools = add(new ToolProperty("", true, true, "tool"));
this.tools = add(new ToolProperty("", false, true, "tool"));
}

@Override
Expand All @@ -30,10 +31,27 @@ public String getName() {
return "uninstall";
}

@Override
public boolean isIdeRootRequired() {

return this.tools.getValueCount() > 0;
}

@Override
public void run() {

for (int i = 0; i < this.tools.getValueCount(); i++) {
int valueCount = this.tools.getValueCount();
if (valueCount == 0) {
if (!this.context.isForceMode()) {
this.context.askToContinue("Sub-command uninstall without any further arguments will perform the entire uninstallation of IDEasy.\n"
+ "Since this is typically not to be called manually, you may have forgotten to specify the tool to install as extra argument.\n"
+ "The current command will uninstall IDEasy from your computer. Are you sure?");
}
IdeasyCommandlet ideasy = new IdeasyCommandlet(this.context);
ideasy.uninstallIdeasy();
return;
}
for (int i = 0; i < valueCount; i++) {
ToolCommandlet toolCommandlet = this.tools.getValue(i);
if (toolCommandlet.getInstalledVersion() != null) {
toolCommandlet.uninstall();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.devonfw.tools.ide.commandlet;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.function.Function;
Expand All @@ -10,6 +8,7 @@
import com.devonfw.tools.ide.environment.EnvironmentVariables;
import com.devonfw.tools.ide.environment.EnvironmentVariablesPropertiesFile;
import com.devonfw.tools.ide.environment.EnvironmentVariablesType;
import com.devonfw.tools.ide.io.FileAccess;
import com.devonfw.tools.ide.merge.DirectoryMerger;
import com.devonfw.tools.ide.tool.mvn.Mvn;
import com.devonfw.tools.ide.tool.repository.CustomToolsJson;
Expand Down Expand Up @@ -55,16 +54,16 @@ private void updateLegacyFolders() {
}

private void updateLegacyFolder(Path folder, String legacyName, String newName) {

FileAccess fileAccess = this.context.getFileAccess();
Path legacyFolder = folder.resolve(legacyName);
Path newFolder = folder.resolve(newName);
if (Files.isDirectory(legacyFolder)) {
if (fileAccess.isExpectedFolder(legacyFolder)) {
try {
if (!Files.exists(newFolder)) {
Files.move(legacyFolder, newFolder, StandardCopyOption.REPLACE_EXISTING);
if (!fileAccess.exists(newFolder)) {
fileAccess.move(legacyFolder, newFolder, StandardCopyOption.REPLACE_EXISTING);
this.context.success("Successfully renamed folder '{}' to '{}' in {}.", legacyName, newName, folder);
}
} catch (IOException e) {
} catch (IllegalStateException e) {
this.context.error(e, "Error renaming folder {} to {} in {}", legacyName, newName, folder);
}
}
Expand All @@ -73,15 +72,16 @@ private void updateLegacyFolder(Path folder, String legacyName, String newName)
private void updateWorkspaceTemplates() {
this.context.info("Updating workspace templates (replace legacy variables and change variable syntax)...");

FileAccess fileAccess = this.context.getFileAccess();
DirectoryMerger merger = this.context.getWorkspaceMerger();
Path settingsDir = this.context.getSettingsPath();
Path workspaceDir = settingsDir.resolve(IdeContext.FOLDER_WORKSPACE);
if (Files.isDirectory(workspaceDir)) {
if (fileAccess.isExpectedFolder(workspaceDir)) {
merger.upgrade(workspaceDir);
}
this.context.getFileAccess().listChildrenMapped(settingsDir, child -> {
fileAccess.listChildrenMapped(settingsDir, child -> {
Path childWorkspaceDir = child.resolve(IdeContext.FOLDER_WORKSPACE);
if (Files.isDirectory(childWorkspaceDir)) {
if (fileAccess.isExpectedFolder(childWorkspaceDir)) {
merger.upgrade(childWorkspaceDir);
}
return null;
Expand All @@ -106,8 +106,9 @@ private void updateProperties() {
}
environmentVariables = environmentVariables.getParent();
}
FileAccess fileAccess = this.context.getFileAccess();
Path templatePropertiesDir = this.context.getSettingsTemplatePath().resolve(IdeContext.FOLDER_CONF);
if (Files.exists(templatePropertiesDir)) {
if (fileAccess.exists(templatePropertiesDir)) {
EnvironmentVariablesPropertiesFile environmentVariablesProperties = new EnvironmentVariablesPropertiesFile(null, EnvironmentVariablesType.CONF,
templatePropertiesDir, null, this.context);
updateProperties(environmentVariablesProperties);
Expand Down
Loading