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

devonfw / IDEasy / 15855321673

24 Jun 2025 03:51PM UTC coverage: 68.191% (+0.4%) from 67.783%
15855321673

Pull #1375

github

web-flow
Merge 26e6591cb into 584febaaf
Pull Request #1375: #742: Show warning when git repo name does not meet name convention.

3198 of 5094 branches covered (62.78%)

Branch coverage included in aggregate %.

8213 of 11640 relevant lines covered (70.56%)

3.09 hits per line

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

84.95
cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java
1
package com.devonfw.tools.ide.commandlet;
2

3
import java.nio.file.Files;
4
import java.nio.file.Path;
5

6
import com.devonfw.tools.ide.context.IdeContext;
7
import com.devonfw.tools.ide.git.GitContext;
8
import com.devonfw.tools.ide.git.GitUrl;
9
import com.devonfw.tools.ide.io.FileAccess;
10
import com.devonfw.tools.ide.property.FlagProperty;
11
import com.devonfw.tools.ide.property.StringProperty;
12
import com.devonfw.tools.ide.step.Step;
13
import com.devonfw.tools.ide.version.IdeVersion;
14

15
/**
16
 * {@link Commandlet} to create a new IDEasy instance
17
 */
18
public class CreateCommandlet extends AbstractUpdateCommandlet {
19

20
  /** {@link StringProperty} for the name of the new project */
21
  public final StringProperty newProject;
22

23
  /** {@link FlagProperty} for creating a project with settings inside a code repository */
24
  public final FlagProperty codeRepositoryFlag;
25

26
  /**
27
   * The constructor.
28
   *
29
   * @param context the {@link IdeContext}.
30
   */
31
  public CreateCommandlet(IdeContext context) {
32

33
    super(context);
3✔
34
    this.newProject = add(new StringProperty("", true, "project"));
11✔
35
    this.codeRepositoryFlag = add(new FlagProperty("--code"));
9✔
36
    add(this.settingsRepo);
5✔
37
  }
1✔
38

39
  @Override
40
  public String getName() {
41

42
    return "create";
2✔
43
  }
44

45
  @Override
46
  public boolean isIdeHomeRequired() {
47

48
    return false;
2✔
49
  }
50

51
  @Override
52
  public void run() {
53

54
    String newProjectName = this.newProject.getValue();
5✔
55
    Path newProjectPath = this.context.getIdeRoot().resolve(newProjectName);
6✔
56

57
    this.context.info("Creating new IDEasy project in {}", newProjectPath);
10✔
58
    if (!this.context.getFileAccess().isEmptyDir(newProjectPath)) {
6!
59
      this.context.askToContinue("Directory " + newProjectPath + " already exists. Do you want to continue?");
×
60
    } else {
61
      this.context.getFileAccess().mkdirs(newProjectPath);
5✔
62
    }
63

64
    initializeProject(newProjectPath);
3✔
65
    this.context.setIdeHome(newProjectPath);
4✔
66
    this.context.verifyIdeMinVersion(true);
4✔
67
    super.run();
2✔
68
    this.context.verifyIdeMinVersion(true);
4✔
69
    this.context.getFileAccess().writeFileContent(IdeVersion.getVersionString(), newProjectPath.resolve(IdeContext.FILE_SOFTWARE_VERSION));
8✔
70
    this.context.success("Successfully created new project '{}'.", newProjectName);
10✔
71
  }
1✔
72

73
  private void initializeProject(Path newInstancePath) {
74

75
    FileAccess fileAccess = this.context.getFileAccess();
4✔
76
    fileAccess.mkdirs(newInstancePath.resolve(IdeContext.FOLDER_SOFTWARE));
5✔
77
    fileAccess.mkdirs(newInstancePath.resolve(IdeContext.FOLDER_PLUGINS));
5✔
78
    fileAccess.mkdirs(newInstancePath.resolve(IdeContext.FOLDER_WORKSPACES).resolve(IdeContext.WORKSPACE_MAIN));
7✔
79
  }
1✔
80

81
  /**
82
   * Handles cases for settings and code repository during creation.
83
   */
84
  @Override
85
  protected void processRepository() {
86
    RepositoryStrategy repositoryStrategy = new SettingsRepositoryStrategy();
4✔
87
    if (isCodeRepository()) {
3✔
88
      repositoryStrategy = new CodeRepositoryStrategy();
4✔
89
    }
90

91
    processRepositoryUsingStrategy(repositoryStrategy);
3✔
92
  }
1✔
93

94
  private void processRepositoryUsingStrategy(RepositoryStrategy strategy) {
95
    Step step = strategy.createNewStep(this.context);
5✔
96
    String repository = this.settingsRepo.getValue();
5✔
97
    if (repository == null || repository.isBlank()) {
5!
98
      repository = strategy.handleBlankRepository(this.context);
×
99
    }
100
    if ("-".equals(repository)) {
4✔
101
      repository = IdeContext.DEFAULT_SETTINGS_REPO_URL;
2✔
102
    }
103
    GitUrl gitUrl = GitUrl.of(repository);
3✔
104
    strategy.checkProjectNameConvention(this.context, gitUrl.getProjectName());
6✔
105
    strategy.initializeRepository(this.context, gitUrl);
5✔
106
    strategy.resolveStep(step);
3✔
107
  }
1✔
108

109
  /**
110
   * Strategy for handling repository.
111
   */
112
  interface RepositoryStrategy {
113

114
    /**
115
     * Handler for blank repository, displays warning and asks for input of repository URL.
116
     *
117
     * @param context ide context
118
     * @return repository url from user input
119
     */
120
    String handleBlankRepository(IdeContext context);
121

122
    /**
123
     * Check the given project name, displays warning when name does not meet convention.
124
     *
125
     * @param context ide context
126
     * @param projectName the project name of repository
127
     */
128
    void checkProjectNameConvention(IdeContext context, String projectName);
129

130
    /**
131
     * Initialize the given Git repository.
132
     *
133
     * @param context ide context
134
     * @param gitUrl URL of the git repository
135
     */
136
    void initializeRepository(IdeContext context, GitUrl gitUrl);
137

138
    /**
139
     * Create a new commandlet step.
140
     *
141
     * @param context ide context
142
     * @return the created new commandlet Step
143
     */
144
    Step createNewStep(IdeContext context);
145

146
    /**
147
     * Resolve the given commandlet step.
148
     *
149
     * @param step to resolve
150
     */
151
    void resolveStep(Step step);
152
  }
153

154
  /**
155
   * Strategy implementation for code repository.
156
   */
157
  static class CodeRepositoryStrategy implements RepositoryStrategy {
3✔
158

159
    @Override
160
    public String handleBlankRepository(IdeContext context) {
161
      String message = """
×
162
          No code repository was given after '--code'.
163
          Please give the code repository below that includes your settings folder.
164
          Further details can be found here: https://github.com/devonfw/IDEasy/blob/main/documentation/settings.adoc
165
          Code repository URL:
166
          """;
167
      return context.askForInput(message);
×
168
    }
169

170
    @Override
171
    public void checkProjectNameConvention(IdeContext context, String projectName) {
172
      if (projectName.contains(IdeContext.SETTINGS_REPOSITORY_KEYWORD)) {
4!
173
        String warningTemplate = """
2✔
174
            Your git URL is pointing to the project name {} that contains the keyword '{}'.
175
            Therefore we assume that you did a mistake by adding the '--code' option to the ide project creation.
176
            Do you really want to create the project?
177
            """;
178
        context.askToContinue(warningTemplate, projectName, IdeContext.SETTINGS_REPOSITORY_KEYWORD);
13✔
179
      }
180
    }
1✔
181

182
    @Override
183
    public void initializeRepository(IdeContext context, GitUrl gitUrl) {
184
      // clone the given repository into IDE_HOME/workspaces/main
185
      Path codeRepoPath = context.getWorkspacePath().resolve(gitUrl.getProjectName());
6✔
186
      context.getGitContext().pullOrClone(gitUrl, codeRepoPath);
5✔
187

188
      // check for settings folder and create symlink to IDE_HOME/settings
189
      Path settingsFolder = codeRepoPath.resolve(IdeContext.FOLDER_SETTINGS);
4✔
190
      if (Files.exists(settingsFolder)) {
5!
191
        context.getFileAccess().symlink(settingsFolder, context.getSettingsPath());
×
192
        // create a file in IDE_HOME with the current local commit id
193
        context.getGitContext().saveCurrentCommitId(codeRepoPath, context.getSettingsCommitIdPath());
×
194
      } else {
195
        context.warning("No settings folder was found inside the code repository.");
3✔
196
      }
197
    }
1✔
198

199
    @Override
200
    public Step createNewStep(IdeContext context) {
201
      return context.newStep("Clone code repository");
4✔
202
    }
203

204
    @Override
205
    public void resolveStep(Step step) {
206
      step.success("Successfully updated code repository.");
3✔
207
    }
1✔
208
  }
209

210
  /**
211
   * Strategy implementation for settings repository.
212
   */
213
  static class SettingsRepositoryStrategy implements RepositoryStrategy {
3✔
214

215
    @Override
216
    public String handleBlankRepository(IdeContext context) {
217
      Path settingsPath = context.getSettingsPath();
×
218
      String message = "Missing your settings at " + settingsPath + " and no SETTINGS_URL is defined.\n"
×
219
          + "Further details can be found here: https://github.com/devonfw/IDEasy/blob/main/documentation/settings.adoc\n"
220
          + "Please contact the technical lead of your project to get the SETTINGS_URL for your project.\n"
221
          + "In case you just want to test IDEasy you may simply hit return to install the default settings.\n" + "Settings URL ["
222
          + IdeContext.DEFAULT_SETTINGS_REPO_URL + "]:";
223
      return context.askForInput(message, IdeContext.DEFAULT_SETTINGS_REPO_URL);
×
224
    }
225

226
    @Override
227
    public void checkProjectNameConvention(IdeContext context, String projectName) {
228
      if (!projectName.contains(IdeContext.SETTINGS_REPOSITORY_KEYWORD)) {
4✔
229
        String warningTemplate = """
2✔
230
            Your git URL is pointing to the project name {} that does not contain the keyword ''{}''.
231
            Therefore we assume that you forgot to add the '--code' option to the ide project creation.
232
            Do you really want to create the project?
233
            """;
234
        context.askToContinue(warningTemplate, projectName, IdeContext.SETTINGS_REPOSITORY_KEYWORD);
13✔
235
      }
236
    }
1✔
237

238
    @Override
239
    public void initializeRepository(IdeContext context, GitUrl gitUrl) {
240
      Path settingsPath = context.getSettingsPath();
3✔
241
      GitContext gitContext = context.getGitContext();
3✔
242
      gitContext.pullOrClone(gitUrl, settingsPath);
4✔
243
      context.getGitContext().saveCurrentCommitId(settingsPath, context.getSettingsCommitIdPath());
6✔
244
    }
1✔
245

246
    @Override
247
    public Step createNewStep(IdeContext context) {
248
      return context.newStep("Clone settings repository");
4✔
249
    }
250

251
    @Override
252
    public void resolveStep(Step step) {
253
      step.success("Successfully updated settings repository.");
3✔
254
    }
1✔
255
  }
256

257
  @Override
258
  protected boolean isCodeRepository() {
259
    return this.codeRepositoryFlag.isTrue();
4✔
260
  }
261
}
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

© 2025 Coveralls, Inc