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

devonfw / IDEasy / 12987966179

27 Jan 2025 11:27AM UTC coverage: 68.326% (-0.1%) from 68.444%
12987966179

Pull #990

github

web-flow
Merge ca9b2b7a7 into c44479b1a
Pull Request #990: #954: improve repository support

2836 of 4561 branches covered (62.18%)

Branch coverage included in aggregate %.

7337 of 10328 relevant lines covered (71.04%)

3.09 hits per line

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

83.33
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
    updateSettings();
2✔
54
    updateConf();
2✔
55
    reloadContext();
2✔
56

57
    updateSoftware();
2✔
58
    updateRepositories();
2✔
59
  }
1✔
60

61
  private void reloadContext() {
62

63
    ((AbstractIdeContext) this.context).reload();
4✔
64
  }
1✔
65

66
  private void updateConf() {
67

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

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

85
  private void setupConf(Path template, Path conf) {
86

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

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

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

111
  /**
112
   * 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
113
   * latest current commit ID in the file ".commit.id".
114
   */
115
  protected void updateSettings() {
116

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

150
  private void updateSoftware() {
151

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

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

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

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

194
  private void updateRepositories() {
195

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

205
}
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