1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
// SPDX-License-Identifier: BSD-3-Clause
package org.islandoftex.arara.filehandling
import java.io.File
import java.io.FileFilter
import java.nio.file.FileSystems
import org.islandoftex.arara.Arara
import org.islandoftex.arara.configuration.AraraSpec
import org.islandoftex.arara.localization.LanguageController
import org.islandoftex.arara.localization.Messages
import org.islandoftex.arara.model.AraraException
import org.islandoftex.arara.utils.CommonUtils
/**
* Implements file searching utilitary methods.
*
* @author Island of TeX
* @version 5.0
* @since 4.0
*/
object FileSearchingUtils {
/**
* List all files from the provided directory according to the list of
* extensions. The leading dot must be omitted, unless it is part of the
* extension.
* @param directory The provided directory.
* @param extensions The list of extensions.
* @param recursive A flag indicating whether the search is recursive.
* @return A list of files.
*/
fun listFilesByExtensions(
directory: File,
extensions: List<String>,
recursive: Boolean
):
List<File> = try {
// return the result of the
// provided search
if (recursive)
directory.walkTopDown().asSequence()
.filter { !it.isDirectory }
.filter { extensions.contains(it.extension) }
.toList()
else
directory.listFiles(
FileFilter { extensions.contains(it.extension) })!!
.toList()
} catch (_: Exception) {
// if something bad happens,
// gracefully fallback to
// an empty file list
listOf()
}
/**
* List all files from the provided directory matching the list of file
* name patterns. Such list can contain wildcards.
* @param directory The provided directory.
* @param patterns The list of file name patterns.
* @param recursive A flag indicating whether the search is recursive.
* @return A list of files.
*/
fun listFilesByPatterns(
directory: File,
patterns: List<String>,
recursive: Boolean
):
List<File> = try {
// return the result of the provided
// search, with the wildcard filter
// and a potential recursive search
val pathMatcher = patterns.map {
FileSystems.getDefault().getPathMatcher("glob:$it")
}
if (recursive)
directory.walkTopDown().asSequence()
.filter { !it.isDirectory }
.filter { file ->
pathMatcher.any { it.matches(file.toPath().fileName) }
}.toList()
else
directory.listFiles { file: File ->
pathMatcher.any { it.matches(file.toPath().fileName) }
}!!.toList()
} catch (_: Exception) {
// if something bad happens,
// gracefully fallback to
// an empty file list
listOf()
}
/**
* Discovers the file through string reference lookup and sets the
* configuration accordingly.
*
* @param reference The string reference.
* @throws AraraException Something wrong happened, to be caught in the
* higher levels.
*/
@Throws(AraraException::class)
fun discoverFile(reference: String) {
lookupFile(reference)
?: throw AraraException(
LanguageController.getMessage(
Messages.ERROR_DISCOVERFILE_FILE_NOT_FOUND,
reference,
CommonUtils.fileTypesList
)
)
}
/**
* Performs a file lookup based on a string reference.
*
* @param reference The file reference as a string.
* @return The file as result of the lookup operation.
* @throws AraraException Something wrong happened, to be caught in the
* higher levels.
*/
@Throws(AraraException::class)
private fun lookupFile(reference: String): File? {
val types = Arara.config[AraraSpec.Execution.fileTypes]
val file = Arara.config[AraraSpec.Execution.workingDirectory]
.resolve(reference).toFile()
val name = file.name
val parent = FileHandlingUtils.getParentCanonicalFile(file)
// direct search, so we are considering
// the reference as a complete name
val testFile = parent.resolve(name)
if (testFile.exists() && testFile.isFile) {
types.firstOrNull {
testFile.toString().endsWith("." + it.extension)
}?.let {
Arara.config[AraraSpec.Execution.filePattern] =
it.pattern
Arara.config[AraraSpec.Execution.reference] = testFile
return testFile
}
}
// indirect search; in this case, we are considering
// that the file reference has an implicit extension,
// so we need to add it and look again
// TODO: disable this step in safe mode
return types.map { parent.resolve("$name.${it.extension}") to it }
.union(types.map {
parent.resolve("${name.removeSuffix(".").trim()}.${it.extension}") to it
})
.firstOrNull { it.first.exists() && it.first.isFile }
?.let {
Arara.config[AraraSpec.Execution.filePattern] =
it.second.pattern
Arara.config[AraraSpec.Execution.reference] = it.first
file
}
}
}
|