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

devonfw / IDEasy / 12749906073

13 Jan 2025 02:58PM UTC coverage: 68.092% (+0.6%) from 67.541%
12749906073

Pull #820

github

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

2690 of 4311 branches covered (62.4%)

Branch coverage included in aggregate %.

6947 of 9842 relevant lines covered (70.59%)

3.1 hits per line

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

81.25
cli/src/main/java/com/devonfw/tools/ide/io/FileAccess.java
1
package com.devonfw.tools.ide.io;
2

3
import java.nio.file.Path;
4
import java.nio.file.attribute.PosixFilePermission;
5
import java.util.List;
6
import java.util.Set;
7
import java.util.function.Consumer;
8
import java.util.function.Function;
9
import java.util.function.Predicate;
10

11
/**
12
 * Interface that gives access to various operations on files.
13
 */
14
public interface FileAccess {
15

16
  /** {@link PosixFilePermission}s for "rwxr-xr-x" or 0755. */
17
  Set<PosixFilePermission> RWX_RX_RX = Set.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE,
10✔
18
      PosixFilePermission.GROUP_READ, PosixFilePermission.GROUP_EXECUTE, PosixFilePermission.OTHERS_READ, PosixFilePermission.OTHERS_EXECUTE);
19

20
  /**
21
   * Downloads a file from an arbitrary location.
22
   *
23
   * @param url the location of the binary file to download. May also be a local or remote path to copy from.
24
   * @param targetFile the {@link Path} to the target file to download to. Should not already exist. Missing parent directories will be created
25
   *     automatically.
26
   */
27
  void download(String url, Path targetFile);
28

29
  /**
30
   * Creates the entire {@link Path} as directories if not already existing.
31
   *
32
   * @param directory the {@link Path} to {@link java.nio.file.Files#createDirectories(Path, java.nio.file.attribute.FileAttribute...) create}.
33
   */
34
  void mkdirs(Path directory);
35

36
  /**
37
   * @param file the {@link Path} to check.
38
   * @return {@code true} if the given {@code file} points to an existing file, {@code false} otherwise (the given {@link Path} does not exist or is a
39
   *     directory).
40
   */
41
  boolean isFile(Path file);
42

43
  /**
44
   * @param folder the {@link Path} to check.
45
   * @return {@code true} if the given {@code folder} points to an existing directory, {@code false} otherwise (a warning is logged in this case).
46
   */
47
  boolean isExpectedFolder(Path folder);
48

49
  /**
50
   * @param file the {@link Path} to compute the checksum of.
51
   * @return the computed checksum (SHA-266).
52
   */
53
  String checksum(Path file);
54

55
  /**
56
   * Moves the given {@link Path} to the backup.
57
   *
58
   * @param fileOrFolder the {@link Path} to move to the backup (soft-deletion).
59
   */
60
  void backup(Path fileOrFolder);
61

62
  /**
63
   * @param source the source {@link Path file or folder} to move.
64
   * @param targetDir the {@link Path} with the directory to move {@code source} into.
65
   */
66
  void move(Path source, Path targetDir);
67

68
  /**
69
   * Creates a symbolic link. If the given {@code targetLink} already exists and is a symbolic link or a Windows junction, it will be replaced. In case of
70
   * missing privileges, Windows Junctions may be used as fallback, which must point to absolute paths. Therefore, the created link will be absolute instead of
71
   * relative.
72
   *
73
   * @param source the source {@link Path} to link to, may be relative or absolute.
74
   * @param targetLink the {@link Path} where the symbolic link shall be created pointing to {@code source}.
75
   * @param relative - {@code true} if the symbolic link shall be relative, {@code false} if it shall be absolute.
76
   */
77
  void symlink(Path source, Path targetLink, boolean relative);
78

79
  /**
80
   * Creates a relative symbolic link. If the given {@code targetLink} already exists and is a symbolic link or a Windows junction, it will be replaced. In case
81
   * of missing privileges, Windows Junctions may be used as fallback, which must point to absolute paths. Therefore, the created link will be absolute instead
82
   * of relative.
83
   *
84
   * @param source the source {@link Path} to link to, may be relative or absolute.
85
   * @param targetLink the {@link Path} where the symbolic link shall be created pointing to {@code source}.
86
   */
87
  default void symlink(Path source, Path targetLink) {
88

89
    symlink(source, targetLink, true);
5✔
90
  }
1✔
91

92
  /**
93
   * @param source the source {@link Path file or folder} to copy.
94
   * @param target the {@link Path} to copy {@code source} to. See {@link #copy(Path, Path, FileCopyMode)} for details. Will always ensure that in the end
95
   *     you will find the same content of {@code source} in {@code target}.
96
   */
97
  default void copy(Path source, Path target) {
98

99
    copy(source, target, FileCopyMode.COPY_TREE_FAIL_IF_EXISTS);
5✔
100
  }
1✔
101

102
  /**
103
   * @param source the source {@link Path file or folder} to copy.
104
   * @param target the {@link Path} to copy {@code source} to. Unlike the Linux {@code cp} command this method will not take the filename of {@code source}
105
   *     and copy that to {@code target} in case that is an existing folder. Instead it will always be simple and stupid and just copy from {@code source} to
106
   *     {@code target}. Therefore the result is always clear and easy to predict and understand. Also you can easily rename a file to copy. While
107
   *     {@code cp my-file target} may lead to a different result than {@code cp my-file target/} this method will always ensure that in the end you will find
108
   *     the same content of {@code source} in {@code target}.
109
   * @param mode the {@link FileCopyMode}.
110
   */
111
  default void copy(Path source, Path target, FileCopyMode mode) {
112

113
    copy(source, target, mode, PathCopyListener.NONE);
6✔
114
  }
1✔
115

116
  /**
117
   * @param source the source {@link Path file or folder} to copy.
118
   * @param target the {@link Path} to copy {@code source} to. Unlike the Linux {@code cp} command this method will not take the filename of {@code source}
119
   *     and copy that to {@code target} in case that is an existing folder. Instead it will always be simple and stupid and just copy from {@code source} to
120
   *     {@code target}. Therefore the result is always clear and easy to predict and understand. Also you can easily rename a file to copy. While
121
   *     {@code cp my-file target} may lead to a different result than {@code cp my-file target/} this method will always ensure that in the end you will find
122
   *     the same content of {@code source} in {@code target}.
123
   * @param mode the {@link FileCopyMode}.
124
   * @param listener the {@link PathCopyListener} that will be called for each copied {@link Path}.
125
   */
126
  void copy(Path source, Path target, FileCopyMode mode, PathCopyListener listener);
127

128
  /**
129
   * @param archiveFile the {@link Path} to the file to extract.
130
   * @param targetDir the {@link Path} to the directory where to extract the {@code archiveFile} to.
131
   */
132
  default void extract(Path archiveFile, Path targetDir) {
133

134
    extract(archiveFile, targetDir, null);
5✔
135
  }
1✔
136

137
  /**
138
   * @param archiveFile the {@link Path} to the archive file to extract.
139
   * @param targetDir the {@link Path} to the directory where to extract the {@code archiveFile}.
140
   * @param postExtractHook the {@link Consumer} to be called after the extraction on the final folder before it is moved to {@code targetDir}.
141
   */
142
  default void extract(Path archiveFile, Path targetDir, Consumer<Path> postExtractHook) {
143

144
    extract(archiveFile, targetDir, postExtractHook, true);
6✔
145
  }
1✔
146

147
  /**
148
   * @param archiveFile the {@link Path} to the archive file to extract.
149
   * @param targetDir the {@link Path} to the directory where to extract the {@code archiveFile}.
150
   * @param postExtractHook the {@link Consumer} to be called after the extraction on the final folder before it is moved to {@code targetDir}.
151
   * @param extract {@code true} if the {@code archiveFile} should be extracted (default), {@code false} otherwise.
152
   */
153
  void extract(Path archiveFile, Path targetDir, Consumer<Path> postExtractHook, boolean extract);
154

155
  /**
156
   * Extracts a ZIP file what is the common archive format on Windows. Initially invented by PKZIP for MS-DOS and also famous from WinZIP software for Windows.
157
   *
158
   * @param file the ZIP file to extract.
159
   * @param targetDir the {@link Path} with the directory to unzip to.
160
   */
161
  void extractZip(Path file, Path targetDir);
162

163
  /**
164
   * @param file the ZIP file to extract.
165
   * @param targetDir the {@link Path} with the directory to unzip to.
166
   * @param compression the {@link TarCompression} to use.
167
   */
168
  void extractTar(Path file, Path targetDir, TarCompression compression);
169

170
  /**
171
   * @param file the JAR file to extract.
172
   * @param targetDir the {@link Path} with the directory to extract to.
173
   */
174
  void extractJar(Path file, Path targetDir);
175

176
  /**
177
   * Extracts an Apple DMG (Disk Image) file that is similar to an ISO image. DMG files are commonly used for software releases on MacOS. Double-clicking such
178
   * files on MacOS mounts them and show the application together with a symbolic link to the central applications folder and some help instructions. The user
179
   * then copies the application to the applications folder via drag and drop in order to perform the installation.
180
   *
181
   * @param file the DMG file to extract.
182
   * @param targetDir the target directory where to extract the contents to.
183
   */
184
  void extractDmg(Path file, Path targetDir);
185

186
  /**
187
   * Extracts an MSI (Microsoft Installer) file. MSI files are commonly used for software releases on Windows that allow an installation wizard and easy later
188
   * uninstallation.
189
   *
190
   * @param file the MSI file to extract.
191
   * @param targetDir the target directory where to extract the contents to.
192
   */
193
  void extractMsi(Path file, Path targetDir);
194

195
  /**
196
   * Extracts an Apple PKG (Package) file. PKG files are used instead of {@link #extractDmg(Path, Path) DMG files} if additional changes have to be performed
197
   * like drivers to be installed. Similar to what {@link #extractMsi(Path, Path) MSI} is on Windows. PKG files are internally a xar based archive with a
198
   * specific structure.
199
   *
200
   * @param file the PKG file to extract.
201
   * @param targetDir the target directory where to extract the contents to.
202
   */
203
  void extractPkg(Path file, Path targetDir);
204

205
  /**
206
   * @param path the {@link Path} to convert.
207
   * @return the absolute and physical {@link Path} (without symbolic links).
208
   */
209
  Path toRealPath(Path path);
210

211
  /**
212
   * Deletes the given {@link Path} idempotent and recursive.
213
   * <p>
214
   * ATTENTION: In most cases we want to use {@link #backup(Path)} instead to prevent the user from data loss.
215
   * </p>
216
   *
217
   * @param path the {@link Path} to delete.
218
   */
219
  void delete(Path path);
220

221
  /**
222
   * Creates a new temporary directory. ATTENTION: The user of this method is responsible to do house-keeping and {@link #delete(Path) delete} it after the work
223
   * is done.
224
   *
225
   * @param name the default name of the temporary directory to create. A prefix or suffix may be added to ensure uniqueness.
226
   * @return the {@link Path} to the newly created and unique temporary directory.
227
   */
228
  Path createTempDir(String name);
229

230
  /**
231
   * @param dir the folder to search.
232
   * @param filter the {@link Predicate} used to find the {@link Predicate#test(Object) match}.
233
   * @param recursive - {@code true} to search recursive in all sub-folders, {@code false} otherwise.
234
   * @return the first child {@link Path} matching the given {@link Predicate} or {@code null} if no match was found.
235
   */
236
  Path findFirst(Path dir, Predicate<Path> filter, boolean recursive);
237

238
  /**
239
   * @param dir the {@link Path} to the directory where to list the children.
240
   * @param filter the {@link Predicate} used to {@link Predicate#test(Object) decide} which children to include (if {@code true} is returned).
241
   * @return all children of the given {@link Path} that match the given {@link Predicate}. Will be the empty list of the given {@link Path} is not an existing
242
   *     directory.
243
   */
244
  default List<Path> listChildren(Path dir, Predicate<Path> filter) {
245

246
    return listChildrenMapped(dir, child -> (filter.test(child)) ? child : null);
13!
247
  }
248

249
  /**
250
   * @param dir the {@link Path} to the directory where to list the children.
251
   * @param filter the filter {@link Function} used to {@link Function#apply(Object) filter and transform} children to include. If the {@link Function}
252
   *     returns  {@code null}, the child will be filtered, otherwise the returned {@link Path} will be included in the resulting {@link List}.
253
   * @return all children of the given {@link Path} returned by the given {@link Function}. Will be the empty list of the given {@link Path} is not an existing
254
   *     directory.
255
   */
256
  List<Path> listChildrenMapped(Path dir, Function<Path, Path> filter);
257

258
  /**
259
   * Finds the existing file with the specified name in the given list of directories.
260
   *
261
   * @param fileName The name of the file to find.
262
   * @param searchDirs The list of directories to search for the file.
263
   * @return The {@code Path} of the existing file, or {@code null} if the file is not found.
264
   */
265
  Path findExistingFile(String fileName, List<Path> searchDirs);
266

267
  /**
268
   * Checks if the given directory is empty.
269
   *
270
   * @param dir The {@link Path} object representing the directory to check.
271
   * @return {@code true} if the directory is empty, {@code false} otherwise.
272
   */
273
  boolean isEmptyDir(Path dir);
274

275
  /**
276
   * Makes a file executable (analog to 'chmod a+x').
277
   *
278
   * @param file {@link Path} to the file.
279
   */
280
  default void makeExecutable(Path file) {
281

282
    makeExecutable(file, false);
×
283
  }
×
284

285
  /**
286
   * Makes a file executable (analog to 'chmod a+x').
287
   *
288
   * @param file {@link Path} to the file.
289
   * @param confirm - {@code true} to get user confirmation before adding missing executable flags, {@code false} otherwise (always set missing flags).
290
   */
291
  void makeExecutable(Path file, boolean confirm);
292

293
  /**
294
   * Like the linux touch command this method will update the modification time of the given {@link Path} to the current
295
   * {@link System#currentTimeMillis() system time}. In case the file does not exist, it will be created as empty file. If already the
296
   * {@link Path#getParent() parent folder} does not exist, the operation will fail.
297
   *
298
   * @param file the {@link Path} to the file or folder.
299
   */
300
  void touch(Path file);
301
}
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