-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
ecc2e58
commit b6a41bd
Showing
29 changed files
with
646 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
148 changes: 148 additions & 0 deletions
148
cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractUpdateCommandlet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
package com.devonfw.tools.ide.commandlet; | ||
|
||
import com.devonfw.tools.ide.common.StepContainer; | ||
import com.devonfw.tools.ide.context.IdeContext; | ||
import com.devonfw.tools.ide.property.StringProperty; | ||
import com.devonfw.tools.ide.repo.CustomTool; | ||
import com.devonfw.tools.ide.tool.CustomToolCommandlet; | ||
import com.devonfw.tools.ide.tool.ToolCommandlet; | ||
import com.devonfw.tools.ide.variable.IdeVariables; | ||
|
||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
public abstract class AbstractUpdateCommandlet extends Commandlet { | ||
|
||
protected final StringProperty settingsRepo; | ||
|
||
/** | ||
* The constructor. | ||
* | ||
* @param context the {@link IdeContext}. | ||
*/ | ||
public AbstractUpdateCommandlet(IdeContext context) { | ||
|
||
super(context); | ||
settingsRepo = new StringProperty("", false, "settingsRepository"); | ||
} | ||
|
||
@Override | ||
public void run() { | ||
|
||
updateSettings(); | ||
Path templatesFolder = this.context.getSettingsPath().resolve(IdeContext.FOLDER_TEMPLATES); | ||
|
||
if (!Files.exists(templatesFolder)) { | ||
Path legacyTemplatesFolder = this.context.getSettingsPath().resolve(IdeContext.FOLDER_LEGACY_TEMPLATES); | ||
if (Files.exists(legacyTemplatesFolder)) { | ||
templatesFolder = legacyTemplatesFolder; | ||
} else { | ||
this.context.warning("Templates folder is missing in settings repository."); | ||
return; | ||
} | ||
} | ||
|
||
setupConf(templatesFolder, this.context.getIdeHome()); | ||
updateSoftware(); | ||
} | ||
|
||
private void setupConf(Path template, Path conf) { | ||
|
||
List<Path> children = this.context.getFileAccess().listChildren(template, f -> true); | ||
for (Path child : children) { | ||
|
||
String basename = child.getFileName().toString(); | ||
Path confPath = conf.resolve(basename); | ||
|
||
if (Files.isDirectory(child)) { | ||
if (!Files.isDirectory(confPath)) { | ||
this.context.getFileAccess().mkdirs(confPath); | ||
} | ||
setupConf(child, confPath); | ||
} else if (Files.isRegularFile(child)) { | ||
if (Files.isRegularFile(confPath)) { | ||
this.context.debug("Configuration {} already exists - skipping to copy from {}", confPath, child); | ||
} else { | ||
if (!basename.equals("settings.xml")) { | ||
this.context.info("Copying template {} to {}.", child, confPath); | ||
this.context.getFileAccess().copy(child, confPath); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
private void updateSettings() { | ||
|
||
this.context.info("Updating settings repository ..."); | ||
Path settingsPath = this.context.getSettingsPath(); | ||
if (Files.isDirectory(settingsPath) && !this.context.getFileAccess().isEmptyDir(settingsPath)) { | ||
// perform git pull on the settings repo | ||
this.context.getGitContext().pull(settingsPath); | ||
this.context.success("Successfully updated settings repository."); | ||
} else { | ||
// check if a settings repository is given then clone, otherwise prompt user for a repository. | ||
String repository = settingsRepo.getValue(); | ||
if (repository == null) { | ||
String message = "Missing your settings at " + settingsPath + " and no SETTINGS_URL is defined.\n" + | ||
"Further details can be found here: https://github.com/devonfw/IDEasy/blob/main/documentation/settings.asciidoc\n" + | ||
"Please contact the technical lead of your project to get the SETTINGS_URL for your project.\n" + | ||
"In case you just want to test IDEasy you may simply hit return to install the default settings.\n" + | ||
"Settings URL [" + IdeContext.DEFAULT_SETTINGS_REPO_URL + "]:"; | ||
repository = this.context.askForInput(message, IdeContext.DEFAULT_SETTINGS_REPO_URL); | ||
} | ||
this.context.getGitContext().pullOrClone(repository, settingsPath); | ||
this.context.success("Successfully cloned settings repository."); | ||
} | ||
} | ||
|
||
private void updateSoftware() { | ||
|
||
Set<ToolCommandlet> toolCommandlets = new HashSet<>(); | ||
|
||
// installed tools in IDE_HOME/software | ||
List<Path> softwares = this.context.getFileAccess().listChildren(this.context.getSoftwarePath(), Files::isDirectory); | ||
for (Path software : softwares) { | ||
String toolName = software.getFileName().toString(); | ||
ToolCommandlet toolCommandlet = this.context.getCommandletManager().getToolCommandletOrNull(toolName); | ||
if (toolCommandlet != null) { | ||
toolCommandlets.add(toolCommandlet); | ||
} | ||
} | ||
|
||
// regular tools in $IDE_TOOLS | ||
List<String> regularTools = IdeVariables.IDE_TOOLS.get(this.context); | ||
if (regularTools != null) { | ||
for (String regularTool : regularTools) { | ||
toolCommandlets.add(this.context.getCommandletManager().getToolCommandlet(regularTool)); | ||
} | ||
} | ||
|
||
// custom tools in ide-custom-tools.json | ||
for (CustomTool customTool : this.context.getCustomToolRepository().getTools()) { | ||
CustomToolCommandlet customToolCommandlet = new CustomToolCommandlet(this.context, customTool); | ||
toolCommandlets.add(customToolCommandlet); | ||
} | ||
|
||
// update/install the toolCommandlets | ||
StepContainer container = new StepContainer(this.context); | ||
for (ToolCommandlet toolCommandlet : toolCommandlets) { | ||
try { | ||
container.startStep(toolCommandlet.getName()); | ||
toolCommandlet.install(false); | ||
container.endStep(toolCommandlet.getName(), true, null); | ||
} catch (Exception e) { | ||
container.endStep(toolCommandlet.getName(), false, e); | ||
} | ||
} | ||
// summary | ||
if (!toolCommandlets.isEmpty()) { | ||
container.complete(); | ||
} | ||
} | ||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package com.devonfw.tools.ide.commandlet; | ||
|
||
import com.devonfw.tools.ide.context.AbstractIdeContext; | ||
import com.devonfw.tools.ide.context.IdeContext; | ||
import com.devonfw.tools.ide.io.FileAccess; | ||
import com.devonfw.tools.ide.property.StringProperty; | ||
|
||
import java.nio.file.Path; | ||
|
||
/** | ||
* {@link Commandlet} to create a new IDEasy instance | ||
*/ | ||
public class CreateCommandlet extends AbstractUpdateCommandlet { | ||
|
||
public final StringProperty newProject; | ||
|
||
|
||
/** | ||
* The constructor. | ||
* | ||
* @param context the {@link IdeContext}. | ||
*/ | ||
public CreateCommandlet(IdeContext context) { | ||
|
||
super(context); | ||
addKeyword(getName()); | ||
newProject = add(new StringProperty("", true, "project")); | ||
add(this.settingsRepo); | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
|
||
return "create"; | ||
} | ||
|
||
@Override | ||
public boolean isIdeHomeRequired() { | ||
|
||
return false; | ||
} | ||
|
||
@Override | ||
public void run() { | ||
|
||
String newProjectName = newProject.getValue(); | ||
Path newProjectPath = this.context.getIdeRoot().resolve(newProjectName); | ||
|
||
this.context.info("Creating new IDEasy project in {}", newProjectPath); | ||
if (!this.context.getFileAccess().isEmptyDir(newProjectPath)) { | ||
this.context.askToContinue("Directory " + newProjectPath + " already exists. Do you want to continue?"); | ||
} else { | ||
this.context.getFileAccess().mkdirs(newProjectPath); | ||
} | ||
|
||
initializeProject(newProjectPath); | ||
this.context.setIdeHome(newProjectPath); | ||
super.run(); | ||
updateRepositories(); | ||
this.context.success("Successfully created new project '{}'.", newProjectName); | ||
} | ||
|
||
private void initializeProject(Path newInstancePath) { | ||
|
||
FileAccess fileAccess = this.context.getFileAccess(); | ||
fileAccess.mkdirs(newInstancePath.resolve(IdeContext.FOLDER_SOFTWARE)); | ||
fileAccess.mkdirs(newInstancePath.resolve(IdeContext.FOLDER_PLUGINS)); | ||
fileAccess.mkdirs(newInstancePath.resolve(IdeContext.FOLDER_WORKSPACES).resolve(IdeContext.WORKSPACE_MAIN)); | ||
} | ||
|
||
private void updateRepositories() { | ||
|
||
this.context.getCommandletManager().getCommandlet(RepositoryCommandlet.class).run(); | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
cli/src/main/java/com/devonfw/tools/ide/commandlet/UpdateCommandlet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.devonfw.tools.ide.commandlet; | ||
|
||
import com.devonfw.tools.ide.context.IdeContext; | ||
import com.devonfw.tools.ide.property.StringProperty; | ||
|
||
/** | ||
* {@link Commandlet} to update settings, software and repositories | ||
*/ | ||
public class UpdateCommandlet extends AbstractUpdateCommandlet { | ||
|
||
/** | ||
* The constructor. | ||
* | ||
* @param context the {@link IdeContext}. | ||
*/ | ||
public UpdateCommandlet(IdeContext context) { | ||
|
||
super(context); | ||
addKeyword(getName()); | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
|
||
return "update"; | ||
} | ||
|
||
@Override | ||
public void run() { | ||
|
||
super.run(); | ||
} | ||
} |
89 changes: 89 additions & 0 deletions
89
cli/src/main/java/com/devonfw/tools/ide/common/StepContainer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package com.devonfw.tools.ide.common; | ||
|
||
import com.devonfw.tools.ide.cli.CliException; | ||
import com.devonfw.tools.ide.context.IdeContext; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
/** | ||
* A utility class to manage and log the progress of steps in a process. | ||
* Each step can be started, ended with success or failure, and the overall completion | ||
* status can be checked. | ||
* @throws CliException if one or more steps fail. | ||
*/ | ||
public class StepContainer { | ||
|
||
private final IdeContext context; | ||
|
||
/** List of steps that ended successfully. */ | ||
private List<String> successfulSteps; | ||
|
||
/** List of steps that failed. */ | ||
private List<String> failedSteps; | ||
|
||
/** | ||
* The constructor. | ||
* | ||
* @param context the {@link IdeContext}. | ||
*/ | ||
public StepContainer(IdeContext context) { | ||
|
||
this.context = context; | ||
successfulSteps = new ArrayList<>(); | ||
failedSteps = new ArrayList<>(); | ||
} | ||
|
||
/** | ||
* Logs the start of a step. | ||
* | ||
* @param stepName the name of the step. | ||
*/ | ||
public void startStep(String stepName) { | ||
|
||
this.context.step("Starting step: {}", stepName); | ||
} | ||
|
||
/** | ||
* Logs the end of a step, indicating success or failure. | ||
* | ||
* @param stepName the name of the step. | ||
* @param success {@code true} if the step succeeded, {@code false} otherwise. | ||
* @param e the exception associated with the failure, or {@code null} if the step succeeded. | ||
*/ | ||
public void endStep(String stepName, boolean success, Throwable e) { | ||
|
||
if (success) { | ||
successfulSteps.add(stepName); | ||
this.context.success("Step '{}' succeeded.", stepName); | ||
} else { | ||
failedSteps.add(stepName); | ||
this.context.warning("Step '{}' failed.", stepName); | ||
if (e != null) { | ||
this.context.error(e); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Checks the overall completion status of all steps. | ||
* | ||
* @throws CliException if one or more steps fail, providing a detailed summary. | ||
*/ | ||
public void complete() { | ||
|
||
if (failedSteps.isEmpty()) { | ||
this.context.success("All {} steps ended successfully!", successfulSteps.size()); | ||
} else { | ||
throw new CliException(String.format("%d step(s) failed (%d%%) and %d step(s) succeeded (%d%%) out of %d step(s)!", | ||
failedSteps.size(), calculatePercentage(failedSteps.size()), successfulSteps.size(), | ||
100 - calculatePercentage(failedSteps.size()), successfulSteps.size() + failedSteps.size())); | ||
} | ||
} | ||
|
||
private int calculatePercentage(int count) { | ||
|
||
return (count * 100) / (successfulSteps.size() + failedSteps.size()); | ||
} | ||
|
||
} |
Oops, something went wrong.