or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ant-builder.mdfile-utilities.mdgroovy-compilation.mdgroovy-documentation.mdgroovy-execution.mdindex.md

file-utilities.mddocs/

0

# File Pattern Matching

1

2

File pattern matching utilities provide Ant-style include/exclude pattern support for file discovery, scanning, and filtering operations in build automation and file processing tasks.

3

4

## Capabilities

5

6

### FileNameFinder

7

8

Groovy utility class for finding files using Ant-style patterns with include/exclude support.

9

10

```java { .api }

11

/**

12

* Find files according to a base directory and includes/excludes patterns.

13

* Patterns conform to Ant's fileset pattern conventions.

14

*/

15

public class FileNameFinder implements IFileNameFinder {

16

/** Find files using base directory and include pattern */

17

public List<String> getFileNames(String basedir, String pattern);

18

19

/** Find files using base directory, include pattern, and exclude pattern */

20

public List<String> getFileNames(String basedir, String pattern, String excludesPattern);

21

22

/** Find files using configuration map with named parameters */

23

public List<String> getFileNames(Map args);

24

}

25

26

/**

27

* Interface for file name finding functionality.

28

*/

29

public interface IFileNameFinder {

30

/** Core file finding method with base directory and pattern */

31

List<String> getFileNames(String basedir, String pattern);

32

33

/** Extended file finding with exclude patterns */

34

List<String> getFileNames(String basedir, String pattern, String excludesPattern);

35

36

/** Flexible file finding with named parameters */

37

List<String> getFileNames(Map args);

38

}

39

```

40

41

### FileScanner

42

43

Low-level file scanning utility integrated with Ant's DirectoryScanner functionality.

44

45

```java { .api }

46

/**

47

* Ant-integrated file scanner for pattern-based file discovery.

48

* Provides iterator-style access to matched files.

49

*/

50

public class FileScanner {

51

/** Set the base directory for scanning */

52

public void setDir(File dir);

53

54

/** Get the base directory */

55

public File getDir();

56

57

/** Set include patterns (comma or space separated) */

58

public void setIncludes(String includes);

59

60

/** Get include patterns */

61

public String getIncludes();

62

63

/** Set exclude patterns (comma or space separated) */

64

public void setExcludes(String excludes);

65

66

/** Get exclude patterns */

67

public String getExcludes();

68

69

/** Set whether to follow symbolic links */

70

public void setFollowSymlinks(boolean followSymlinks);

71

72

/** Check if following symbolic links */

73

public boolean isFollowSymlinks();

74

75

/** Set whether to use default excludes (like .svn, .git) */

76

public void setDefaultexcludes(boolean useDefaultExcludes);

77

78

/** Check if using default excludes */

79

public boolean getDefaultexcludes();

80

81

/** Add include pattern */

82

public void addInclude(String pattern);

83

84

/** Add exclude pattern */

85

public void addExclude(String pattern);

86

87

/** Get array of included files */

88

public String[] getIncludedFiles();

89

90

/** Get array of included directories */

91

public String[] getIncludedDirectories();

92

93

/** Scan directory and populate results */

94

public void scan();

95

}

96

```

97

98

### FileIterator

99

100

Iterator interface for traversing files matched by patterns.

101

102

```java { .api }

103

/**

104

* Iterator for traversing files matched by scanning patterns.

105

* Integrates with Java's Iterator pattern for easy file processing.

106

*/

107

public class FileIterator implements java.util.Iterator<File> {

108

/** Check if more files are available */

109

public boolean hasNext();

110

111

/** Get the next file in the iteration */

112

public File next();

113

114

/** Remove current file (operation not supported) */

115

public void remove() throws UnsupportedOperationException;

116

}

117

```

118

119

## Pattern Syntax

120

121

Ant-style patterns support the following wildcards:

122

123

```java { .api }

124

/**

125

* Pattern matching syntax for file selection.

126

*/

127

public interface PatternSyntax {

128

/** Single character wildcard - matches any single character except path separators */

129

String SINGLE_CHAR = "?";

130

131

/** Multi-character wildcard - matches zero or more characters except path separators */

132

String MULTI_CHAR = "*";

133

134

/** Directory wildcard - matches zero or more directories */

135

String DIR_WILDCARD = "**/";

136

137

/** Path separator - platform independent */

138

String PATH_SEP = "/";

139

}

140

```

141

142

### Pattern Examples

143

144

- `*.java` - All Java files in base directory

145

- `**/*.groovy` - All Groovy files in any subdirectory

146

- `src/**/*.java` - All Java files under src directory tree

147

- `**/test/**/*.class` - All class files in any test directory

148

- `**/*Test.java` - All Java files ending with "Test"

149

- `com/example/**` - All files under com/example package structure

150

151

## Usage Examples

152

153

### Basic File Finding

154

```groovy

155

import groovy.util.FileNameFinder

156

157

def finder = new FileNameFinder()

158

159

// Find all Groovy files

160

def groovyFiles = finder.getFileNames("src", "**/*.groovy")

161

groovyFiles.each { file ->

162

println "Found: $file"

163

}

164

165

// Find Java files, excluding test files

166

def javaFiles = finder.getFileNames("src", "**/*.java", "**/*Test.java")

167

println "Found ${javaFiles.size()} non-test Java files"

168

```

169

170

### Map-Based Configuration

171

```groovy

172

def finder = new FileNameFinder()

173

174

// Using named parameters

175

def configFiles = finder.getFileNames(

176

dir: "config",

177

includes: "**/*.properties,**/*.xml",

178

excludes: "**/test/**"

179

)

180

181

// Process configuration files

182

configFiles.each { configFile ->

183

println "Processing config: $configFile"

184

// Load and validate configuration

185

}

186

```

187

188

### Integration with AntBuilder

189

```groovy

190

import groovy.util.AntBuilder

191

import groovy.util.FileNameFinder

192

193

def ant = new AntBuilder()

194

def finder = new FileNameFinder()

195

196

// Find source files to compile

197

def sourceFiles = finder.getFileNames(

198

dir: "src/main/groovy",

199

includes: "**/*.groovy",

200

excludes: "**/internal/**"

201

)

202

203

if (sourceFiles) {

204

println "Compiling ${sourceFiles.size()} source files"

205

206

ant.groovyc(destdir: "build/classes") {

207

sourceFiles.each { sourceFile ->

208

src(file: sourceFile)

209

}

210

}

211

}

212

```

213

214

### File Processing Pipeline

215

```groovy

216

def finder = new FileNameFinder()

217

218

// Find and process different file types

219

def processFiles = { pattern, processor ->

220

def files = finder.getFileNames(".", pattern)

221

files.each { file ->

222

processor(new File(file))

223

}

224

}

225

226

// Process properties files

227

processFiles("**/*.properties") { file ->

228

def props = new Properties()

229

file.withInputStream { props.load(it) }

230

println "$file.name has ${props.size()} properties"

231

}

232

233

// Process XML files

234

processFiles("**/*.xml") { file ->

235

def xml = new XmlSlurper().parse(file)

236

println "$file.name root element: ${xml.name()}"

237

}

238

```

239

240

### Directory Scanner Usage

241

```groovy

242

import org.codehaus.groovy.ant.FileScanner

243

import groovy.util.AntBuilder

244

245

def ant = new AntBuilder()

246

247

// Create scanner through AntBuilder

248

def scanner = ant.fileScanner {

249

fileset(dir: "src") {

250

include(name: "**/*.groovy")

251

include(name: "**/*.java")

252

exclude(name: "**/test/**")

253

exclude(name: "**/*Test.*")

254

}

255

}

256

257

// Iterate through matched files

258

scanner.each { file ->

259

println "Processing: ${file.absolutePath}"

260

261

// Analyze file properties

262

def lines = file.readLines()

263

def size = file.length()

264

println " Lines: ${lines.size()}, Size: ${size} bytes"

265

}

266

```

267

268

### Conditional File Operations

269

```groovy

270

def finder = new FileNameFinder()

271

272

// Find outdated files that need recompilation

273

def sourceFiles = finder.getFileNames("src", "**/*.groovy")

274

def classFiles = finder.getFileNames("build/classes", "**/*.class")

275

276

def outdatedSources = sourceFiles.findAll { srcPath ->

277

def srcFile = new File(srcPath)

278

def classPath = srcPath.replace("src/", "build/classes/")

279

.replace(".groovy", ".class")

280

def classFile = new File(classPath)

281

282

!classFile.exists() || srcFile.lastModified() > classFile.lastModified()

283

}

284

285

if (outdatedSources) {

286

println "Recompiling ${outdatedSources.size()} outdated files"

287

// Trigger compilation

288

} else {

289

println "All files are up to date"

290

}

291

```

292

293

### Archive Content Analysis

294

```groovy

295

import java.util.zip.ZipFile

296

297

def finder = new FileNameFinder()

298

299

// Find all JAR files in dependencies

300

def jarFiles = finder.getFileNames("lib", "**/*.jar")

301

302

jarFiles.each { jarPath ->

303

def jarFile = new ZipFile(jarPath)

304

def entries = jarFile.entries().toList()

305

306

println "Analyzing $jarPath:"

307

println " Total entries: ${entries.size()}"

308

309

// Count different file types

310

def classCount = entries.count { it.name.endsWith('.class') }

311

def resourceCount = entries.count { !it.name.endsWith('.class') && !it.directory }

312

313

println " Classes: $classCount"

314

println " Resources: $resourceCount"

315

316

jarFile.close()

317

}

318

```

319

320

### Build Artifact Management

321

```groovy

322

def finder = new FileNameFinder()

323

324

// Clean up old build artifacts

325

def cleanupOldArtifacts = {

326

def artifactPatterns = [

327

"build/**/*.class",

328

"build/**/*.jar",

329

"dist/**/*.zip",

330

"**/*.tmp"

331

]

332

333

artifactPatterns.each { pattern ->

334

def files = finder.getFileNames(".", pattern)

335

files.each { filePath ->

336

def file = new File(filePath)

337

if (file.exists()) {

338

println "Removing: $filePath"

339

file.delete()

340

}

341

}

342

}

343

}

344

345

// Find test reports for archiving

346

def archiveTestReports = {

347

def reports = finder.getFileNames(

348

dir: "build",

349

includes: "**/TEST-*.xml,**/test-results/**/*.html",

350

excludes: "**/tmp/**"

351

)

352

353

if (reports) {

354

println "Archiving ${reports.size()} test reports"

355

// Create archive with reports

356

}

357

}

358

359

cleanupOldArtifacts()

360

archiveTestReports()

361

```

362

363

### Multi-Project File Discovery

364

```groovy

365

def finder = new FileNameFinder()

366

367

// Find all build files across subprojects

368

def findProjectFiles = { rootDir ->

369

def buildFiles = [:]

370

371

// Find Gradle build files

372

buildFiles.gradle = finder.getFileNames(rootDir, "**/build.gradle")

373

374

// Find Maven POM files

375

buildFiles.maven = finder.getFileNames(rootDir, "**/pom.xml")

376

377

// Find Ant build files

378

buildFiles.ant = finder.getFileNames(rootDir, "**/build.xml")

379

380

return buildFiles

381

}

382

383

def projectFiles = findProjectFiles(".")

384

385

projectFiles.each { buildSystem, files ->

386

if (files) {

387

println "$buildSystem projects found:"

388

files.each { file ->

389

println " $file"

390

}

391

}

392

}

393

```

394

395

## Advanced Pattern Matching

396

397

### Complex Include/Exclude Combinations

398

```groovy

399

def finder = new FileNameFinder()

400

401

// Complex pattern matching for code analysis

402

def analyzeCodebase = {

403

def codeFiles = finder.getFileNames(

404

dir: "src",

405

includes: "**/*.java,**/*.groovy,**/*.scala",

406

excludes: [

407

"**/test/**", // No test files

408

"**/generated/**", // No generated code

409

"**/*\$*.java", // No inner class files

410

"**/package-info.java" // No package info files

411

].join(",")

412

)

413

414

// Categorize by language

415

def byLanguage = codeFiles.groupBy { file ->

416

def ext = file.substring(file.lastIndexOf('.') + 1)

417

return ext

418

}

419

420

byLanguage.each { lang, files ->

421

println "$lang files: ${files.size()}"

422

}

423

424

return codeFiles

425

}

426

427

def codeFiles = analyzeCodebase()

428

```