• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

devonfw / IDEasy / 13011549187

28 Jan 2025 01:29PM UTC coverage: 68.278% (-0.2%) from 68.45%
13011549187

Pull #990

github

web-flow
Merge f75f88113 into 05af7d1fc
Pull Request #990: #954: improve repository support

2841 of 4577 branches covered (62.07%)

Branch coverage included in aggregate %.

7342 of 10337 relevant lines covered (71.03%)

3.09 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.82
cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractUpdateCommandlet.java
1
package com.devonfw.tools.ide.commandlet;
2

3
import java.nio.file.Files;
4
import java.nio.file.Path;
5
import java.util.HashSet;
6
import java.util.List;
7
import java.util.Set;
8

9
import com.devonfw.tools.ide.context.AbstractIdeContext;
10
import com.devonfw.tools.ide.context.IdeContext;
11
import com.devonfw.tools.ide.git.GitContext;
12
import com.devonfw.tools.ide.git.GitUrl;
13
import com.devonfw.tools.ide.git.repository.RepositoryCommandlet;
14
import com.devonfw.tools.ide.property.FlagProperty;
15
import com.devonfw.tools.ide.property.StringProperty;
16
import com.devonfw.tools.ide.step.Step;
17
import com.devonfw.tools.ide.tool.CustomToolCommandlet;
18
import com.devonfw.tools.ide.tool.ToolCommandlet;
19
import com.devonfw.tools.ide.tool.repository.CustomToolMetadata;
20
import com.devonfw.tools.ide.variable.IdeVariables;
21

22
/**
23
 * Abstract {@link Commandlet} base-class for both {@link UpdateCommandlet} and {@link CreateCommandlet}.
24
 */
25
public abstract class AbstractUpdateCommandlet extends Commandlet {
26

27
  /** {@link StringProperty} for the settings repository URL. */
28
  public final StringProperty settingsRepo;
29

30
  /** {@link FlagProperty} for skipping installation/updating of tools. */
31
  public final FlagProperty skipTools;
32

33
  /** {@link FlagProperty} for skipping the setup of git repositories. */
34
  public final FlagProperty skipRepositories;
35

36
  /**
37
   * The constructor.
38
   *
39
   * @param context the {@link IdeContext}.
40
   */
41
  public AbstractUpdateCommandlet(IdeContext context) {
42

43
    super(context);
3✔
44
    addKeyword(getName());
4✔
45
    this.skipTools = add(new FlagProperty("--skip-tools"));
9✔
46
    this.skipRepositories = add(new FlagProperty("--skip-repositories"));
9✔
47
    this.settingsRepo = new StringProperty("", false, "settingsRepository");
8✔
48
  }
1✔
49

50
  @Override
51
  public void run() {
52

53
    if (!this.context.isSettingsRepositorySymlinkOrJunction() || this.context.isForceMode()) {
4!
54
      updateSettings();
2✔
55
    }
56
    updateConf();
2✔
57
    reloadContext();
2✔
58

59
    updateSoftware();
2✔
60
    updateRepositories();
2✔
61
  }
1✔
62

63
  private void reloadContext() {
64

65
    ((AbstractIdeContext) this.context).reload();
4✔
66
  }
1✔
67

68
  private void updateConf() {
69

70
    Path templatesFolder = this.context.getSettingsPath().resolve(IdeContext.FOLDER_TEMPLATES);
6✔
71
    if (!Files.exists(templatesFolder)) {
5✔
72
      Path legacyTemplatesFolder = this.context.getSettingsPath().resolve(IdeContext.FOLDER_LEGACY_TEMPLATES);
6✔
73
      if (Files.exists(legacyTemplatesFolder)) {
5!
74
        templatesFolder = legacyTemplatesFolder;
×
75
      } else {
76
        this.context.warning("Templates folder is missing in settings repository.");
4✔
77
        return;
1✔
78
      }
79
    }
80

81
    try (Step step = this.context.newStep("Copy configuration templates", templatesFolder)) {
11✔
82
      setupConf(templatesFolder, this.context.getIdeHome());
6✔
83
      step.success();
2✔
84
    }
85
  }
1✔
86

87
  private void setupConf(Path template, Path conf) {
88

89
    List<Path> children = this.context.getFileAccess().listChildren(template, f -> true);
9✔
90
    for (Path child : children) {
10✔
91

92
      String basename = child.getFileName().toString();
4✔
93
      Path confPath = conf.resolve(basename);
4✔
94

95
      if (Files.isDirectory(child)) {
5✔
96
        if (!Files.isDirectory(confPath)) {
5!
97
          this.context.getFileAccess().mkdirs(confPath);
5✔
98
        }
99
        setupConf(child, confPath);
5✔
100
      } else if (Files.isRegularFile(child)) {
5!
101
        if (Files.isRegularFile(confPath)) {
5!
102
          this.context.debug("Configuration {} already exists - skipping to copy from {}", confPath, child);
×
103
        } else {
104
          if (!basename.equals("settings.xml")) {
4!
105
            this.context.info("Copying template {} to {}.", child, conf);
14✔
106
            this.context.getFileAccess().copy(child, conf);
6✔
107
          }
108
        }
109
      }
110
    }
1✔
111
  }
1✔
112

113
  /**
114
   * Updates the settings repository in IDE_HOME/settings by either cloning if no such repository exists or pulling if the repository exists then saves the
115
   * latest current commit ID in the file ".commit.id".
116
   */
117
  protected void updateSettings() {
118

119
    Path settingsPath = this.context.getSettingsPath();
4✔
120
    GitContext gitContext = this.context.getGitContext();
4✔
121
    Step step = null;
2✔
122
    try {
123
      // here we do not use pullOrClone to prevent asking a pointless question for repository URL...
124
      if (Files.isDirectory(settingsPath) && !this.context.getFileAccess().isEmptyDir(settingsPath)) {
11!
125
        step = this.context.newStep("Pull settings repository");
5✔
126
        gitContext.pull(settingsPath);
4✔
127
      } else {
128
        step = this.context.newStep("Clone settings repository");
5✔
129
        // check if a settings repository is given, otherwise prompt user for a repository.
130
        String repository = this.settingsRepo.getValue();
5✔
131
        if (repository == null) {
2!
132
          String message = "Missing your settings at " + settingsPath + " and no SETTINGS_URL is defined.\n"
×
133
              + "Further details can be found here: https://github.com/devonfw/IDEasy/blob/main/documentation/settings.asciidoc\n"
134
              + "Please contact the technical lead of your project to get the SETTINGS_URL for your project.\n"
135
              + "In case you just want to test IDEasy you may simply hit return to install the default settings.\n" + "Settings URL ["
136
              + IdeContext.DEFAULT_SETTINGS_REPO_URL + "]:";
137
          repository = this.context.askForInput(message, IdeContext.DEFAULT_SETTINGS_REPO_URL);
×
138
        } else if ("-".equals(repository)) {
4!
139
          repository = IdeContext.DEFAULT_SETTINGS_REPO_URL;
×
140
        }
141
        gitContext.pullOrClone(GitUrl.of(repository), settingsPath);
5✔
142
      }
143
      this.context.getGitContext().saveCurrentCommitId(settingsPath, this.context.getSettingsCommitIdPath());
8✔
144
      step.success("Successfully updated settings repository.");
3✔
145
    } finally {
146
      if (step != null) {
2!
147
        step.close();
2✔
148
      }
149
    }
150
  }
1✔
151

152
  private void updateSoftware() {
153

154
    if (this.skipTools.isTrue()) {
4✔
155
      this.context.info("Skipping installation/update of tools as specified by the user.");
4✔
156
      return;
1✔
157
    }
158
    try (Step step = this.context.newStep("Install or update software")) {
5✔
159
      Set<ToolCommandlet> toolCommandlets = new HashSet<>();
4✔
160
      // installed tools in IDE_HOME/software
161
      List<Path> softwarePaths = this.context.getFileAccess().listChildren(this.context.getSoftwarePath(), Files::isDirectory);
14✔
162
      for (Path softwarePath : softwarePaths) {
10✔
163
        String toolName = softwarePath.getFileName().toString();
4✔
164
        ToolCommandlet toolCommandlet = this.context.getCommandletManager().getToolCommandlet(toolName);
6✔
165
        if (toolCommandlet != null) {
2!
166
          toolCommandlets.add(toolCommandlet);
4✔
167
        }
168
      }
1✔
169

170
      // regular tools in $IDE_TOOLS
171
      List<String> regularTools = IdeVariables.IDE_TOOLS.get(this.context);
6✔
172
      if (regularTools != null) {
2!
173
        for (String regularTool : regularTools) {
10✔
174
          toolCommandlets.add(this.context.getCommandletManager().getRequiredToolCommandlet(regularTool));
8✔
175
        }
1✔
176
      }
177

178
      // custom tools in ide-custom-tools.json
179
      for (CustomToolMetadata customTool : this.context.getCustomToolRepository().getTools()) {
9!
180
        CustomToolCommandlet customToolCommandlet = new CustomToolCommandlet(this.context, customTool);
×
181
        toolCommandlets.add(customToolCommandlet);
×
182
      }
×
183

184
      // update/install the toolCommandlets
185
      for (ToolCommandlet toolCommandlet : toolCommandlets) {
10✔
186
        try {
187
          toolCommandlet.install(false);
4✔
188
        } catch (Exception e) {
1✔
189
          step.error(e, "Installation of {} failed!", toolCommandlet.getName());
11✔
190
        }
1✔
191
      }
1✔
192
      step.success();
2✔
193
    }
194
  }
1✔
195

196
  private void updateRepositories() {
197

198
    if (this.skipRepositories.isTrue()) {
4!
199
      this.context.info("Skipping setup of repositories as specified by the user.");
×
200
      return;
×
201
    }
202
    RepositoryCommandlet repositoryCommandlet = this.context.getCommandletManager().getCommandlet(RepositoryCommandlet.class);
7✔
203
    repositoryCommandlet.reset();
2✔
204
    repositoryCommandlet.run();
2✔
205
  }
1✔
206

207
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc