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

devonfw / IDEasy / 12750410851

13 Jan 2025 03:23PM UTC coverage: 68.077% (+0.5%) from 67.541%
12750410851

Pull #820

github

web-flow
Merge b7b0d1004 into 8e971e1a8
Pull Request #820: #759: upgrade settings commandlet

2689 of 4311 branches covered (62.38%)

Branch coverage included in aggregate %.

6946 of 9842 relevant lines covered (70.58%)

3.1 hits per line

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

65.49
cli/src/main/java/com/devonfw/tools/ide/merge/DirectoryMerger.java
1
package com.devonfw.tools.ide.merge;
2

3
import java.io.IOException;
4
import java.nio.file.Files;
5
import java.nio.file.Path;
6
import java.util.HashMap;
7
import java.util.HashSet;
8
import java.util.Iterator;
9
import java.util.Map;
10
import java.util.Set;
11
import java.util.stream.Stream;
12

13
import org.jline.utils.Log;
14

15
import com.devonfw.tools.ide.context.IdeContext;
16
import com.devonfw.tools.ide.environment.EnvironmentVariables;
17
import com.devonfw.tools.ide.merge.xmlmerger.XmlMerger;
18
import com.devonfw.tools.ide.util.FilenameUtil;
19

20
/**
21
 * Implementation of {@link WorkspaceMerger} that does the whole thing:
22
 * <ul>
23
 * <li>It will recursively traverse directories.</li>
24
 * <li>For each setup or update file if will delegate to the according {@link FileMerger} based on the file
25
 * extension.</li>
26
 * </ul>
27
 */
28
public class DirectoryMerger extends AbstractWorkspaceMerger {
29

30
  private final Map<String, FileMerger> extension2mergerMap;
31

32
  private final FallbackMerger fallbackMerger;
33

34
  /**
35
   * The constructor.
36
   *
37
   * @param context the {@link #context}.
38
   */
39
  public DirectoryMerger(IdeContext context) {
40

41
    super(context);
3✔
42
    this.extension2mergerMap = new HashMap<>();
5✔
43
    PropertiesMerger propertiesMerger = new PropertiesMerger(context);
5✔
44
    this.extension2mergerMap.put("properties", propertiesMerger);
6✔
45
    this.extension2mergerMap.put("prefs", propertiesMerger); // Eclipse specific
6✔
46
    XmlMerger xmlMerger = new XmlMerger(context);
5✔
47
    this.extension2mergerMap.put("xml", xmlMerger);
6✔
48
    this.extension2mergerMap.put("xmi", xmlMerger);
6✔
49
    this.extension2mergerMap.put("launch", xmlMerger); // Eclipse specific
6✔
50
    JsonMerger jsonMerger = new JsonMerger(context);
5✔
51
    this.extension2mergerMap.put("json", jsonMerger);
6✔
52
    TextMerger textMerger = new TextMerger(context);
5✔
53
    this.extension2mergerMap.put("name", textMerger); // intellij specific
6✔
54
    this.extension2mergerMap.put("editorconfig", textMerger);
6✔
55
    this.extension2mergerMap.put("txt", textMerger);
6✔
56
    this.fallbackMerger = new FallbackMerger(context);
6✔
57
  }
1✔
58

59
  @Override
60
  public int merge(Path setup, Path update, EnvironmentVariables variables, Path workspace) {
61

62
    int errors = 0;
2✔
63
    Set<String> children = null;
2✔
64
    children = addChildren(setup, children);
5✔
65
    children = addChildren(update, children);
5✔
66
    if (children == null) {
2✔
67
      // file merge
68
      FileMerger merger = getMerger(workspace);
4✔
69
      errors += merger.merge(setup, update, variables, workspace);
9✔
70
    } else {
1✔
71
      // directory scan
72
      for (String filename : children) {
10✔
73
        errors += merge(setup.resolve(filename), update.resolve(filename), variables, workspace.resolve(filename));
15✔
74
      }
1✔
75
    }
76
    return errors;
2✔
77
  }
78

79
  private FileMerger getMerger(Path file) {
80

81
    String filename = file.getFileName().toString();
4✔
82
    String extension = FilenameUtil.getExtension(filename);
3✔
83
    if (extension == null) {
2!
84
      this.context.debug("No extension for {}", file);
×
85
    } else {
86
      this.context.trace("Extension is {}", extension);
10✔
87
      FileMerger merger = this.extension2mergerMap.get(extension);
6✔
88
      if (merger != null) {
2✔
89
        return merger;
2✔
90
      }
91
    }
92
    return this.fallbackMerger;
3✔
93
  }
94

95
  @Override
96
  public void inverseMerge(Path workspace, EnvironmentVariables variables, boolean addNewProperties, Path update) {
97

98
    if (Files.isDirectory(update)) {
×
99
      if (!Files.isDirectory(workspace)) {
×
100
        Log.warn("Workspace is missing directory: {}", workspace);
×
101
        return;
×
102
      }
103
      Log.trace("Traversing directory: {}", update);
×
104
      try (Stream<Path> childStream = Files.list(update)) {
×
105
        Iterator<Path> iterator = childStream.iterator();
×
106
        while (iterator.hasNext()) {
×
107
          Path updateChild = iterator.next();
×
108
          Path fileName = updateChild.getFileName();
×
109
          inverseMerge(workspace.resolve(fileName), variables, addNewProperties, update.resolve(fileName));
×
110
        }
×
111
      } catch (IOException e) {
×
112
        throw new IllegalStateException("Failed to list children of folder " + update, e);
×
113
      }
×
114

115
    } else if (Files.exists(workspace)) {
×
116
      Log.debug("Start merging of changes from workspace back to file: {}", update);
×
117
      FileMerger merger = getMerger(workspace);
×
118
      Log.trace("Using merger {}", merger.getClass().getSimpleName());
×
119
      merger.inverseMerge(workspace, variables, addNewProperties, update);
×
120
    } else {
×
121
      Log.warn("No such file or directory: {}", update);
×
122
    }
123
  }
×
124

125
  private Set<String> addChildren(Path folder, Set<String> children) {
126

127
    if (!Files.isDirectory(folder)) {
5✔
128
      return children;
2✔
129
    }
130
    try (Stream<Path> childStream = Files.list(folder)) {
3✔
131
      Iterator<Path> iterator = childStream.iterator();
3✔
132
      while (iterator.hasNext()) {
3✔
133
        Path child = iterator.next();
4✔
134
        if (children == null) {
2✔
135
          children = new HashSet<>();
4✔
136
        }
137
        children.add(child.getFileName().toString());
6✔
138
      }
1✔
139
      return children;
4✔
140
    } catch (IOException e) {
×
141
      throw new IllegalStateException("Failed to list children of folder " + folder, e);
×
142
    }
143
  }
144

145
  @Override
146
  public void upgrade(Path folder) {
147

148
    try (Stream<Path> childStream = Files.list(folder)) {
3✔
149
      Iterator<Path> iterator = childStream.iterator();
3✔
150
      while (iterator.hasNext()) {
3✔
151
        Path child = iterator.next();
4✔
152
        if (Files.isDirectory(child)) {
5!
153
          upgrade(child);
×
154
        } else {
155
          FileMerger merger = getMerger(child);
4✔
156
          merger.upgrade(child);
3✔
157
        }
158
      }
1✔
159
    } catch (IOException e) {
×
160
      throw new IllegalStateException("Failed to list children of folder " + folder, e);
×
161
    }
1✔
162
  }
1✔
163

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