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

devonfw / IDEasy / 11783304870

11 Nov 2024 05:26PM UTC coverage: 67.136% (+0.2%) from 66.902%
11783304870

push

github

web-flow
#632: added .editorconfig  to settings-workspaces (#731)

2430 of 3960 branches covered (61.36%)

Branch coverage included in aggregate %.

6336 of 9097 relevant lines covered (69.65%)

3.07 hits per line

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

63.44
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

12
import org.jline.utils.Log;
13

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

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

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

31
  private final FallbackMerger fallbackMerger;
32

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

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

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

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

77
  private FileMerger getMerger(Path file) {
78

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

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

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

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

123
  private Set<String> addChildren(Path folder, Set<String> children) {
124

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

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