Skip to content

Commit d0b7ca0

Browse files
authored
Merge pull request #144 from marytts/custom-basenames-lst
Custom basenames.lst
2 parents 51453ba + 503b1ac commit d0b7ca0

File tree

7 files changed

+193
-40
lines changed

7 files changed

+193
-40
lines changed

.github/workflows/main.yml

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ jobs:
1818
- 8
1919
- 11
2020
- 13
21+
exclude:
22+
- os: macos-latest
23+
java_version: 8
24+
- os: macos-latest
25+
java_version: 13
2126
runs-on: ${{ matrix.os }}
2227

2328
steps:

CHANGELOG.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,23 @@ Gradle MaryTTS voicebuilding plugin
66

77
### Added
88

9-
- Plugin usage in readme
9+
- Plugin usage documented in readme
1010
- Testing on OpenJDK 11 and 13
1111

1212
### Changed
1313

1414
- Migrate testing from Travis CI to GitHub Actions
15-
- Refactor to depends to gradle-marytts-component-plugin v0.2.2
16-
- Refactor to replace the dependency on the defunct marytts-builder by a dependecy on marytts-runtime
15+
- Refactor to depend on gradle-marytts-component-plugin v0.2.2
16+
- Refactor to replace the dependency on the defunct marytts-builder with a dependecy on marytts-runtime
1717
- Build with Gradle v6.3
1818
- Upgrade test dependencies
1919
- Drop testing on Oracle JDK
2020
- [all changes since v5.4]
2121

22+
### Fixed
23+
24+
- Utterance order in `basenames.lst` is now deterministic, either sorted (the default) or specified via a provided `srcFile` (optional)
25+
2226
[v5.4] - 2018-12-12
2327
-------------------
2428

src/main/groovy/de/dfki/mary/voicebuilding/tasks/GenerateBasenamesList.groovy

+20-10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import org.gradle.api.tasks.*
88

99
class GenerateBasenamesList extends DefaultTask {
1010

11+
@Optional
12+
@InputFile
13+
final RegularFileProperty srcFile = project.objects.fileProperty()
14+
1115
@InputDirectory
1216
final DirectoryProperty wavDir = project.objects.directoryProperty()
1317

@@ -39,20 +43,26 @@ class GenerateBasenamesList extends DefaultTask {
3943
@TaskAction
4044
void generate() {
4145
destFile.get().asFile.withWriter('UTF-8') { writer ->
42-
project.fileTree(wavDir).matching {
43-
include this.includes.getOrElse('*').collect { it + '.wav' }
44-
exclude this.excludes.getOrElse([]).collect { it + '.wav' }
45-
}.toSorted().each { wavFile ->
46-
def basename = wavFile.name - '.wav'
46+
def basenames
47+
if (srcFile.getOrNull()) {
48+
basenames = srcFile.get().asFile.readLines().findAll { !it.trim().startsWith('#') }
49+
} else {
50+
basenames = project.fileTree(wavDir).matching {
51+
include this.includes.getOrElse('*').collect { it + '.wav' }
52+
exclude this.excludes.getOrElse([]).collect { it + '.wav' }
53+
}.collect { it.name - '.wav' }.toSorted()
54+
}
55+
basenames.each { basename ->
56+
def wavFile = wavDir.file("${basename}.wav").get().asFile
57+
if (!wavFile.canRead())
58+
project.logger.warn "WARNING: Could not read from $wavFile"
4759
def textFile = textDir.file("${basename}.txt").get().asFile
48-
if (!textFile.canRead()) {
60+
if (!textFile.canRead())
4961
project.logger.warn "WARNING: Could not read from $textFile"
50-
}
5162
def labFile = labDir.file("${basename}.lab").get().asFile
52-
if (!labFile.canRead()) {
63+
if (!labFile.canRead())
5364
project.logger.warn "WARNING: Could not read from $labFile"
54-
}
55-
if (textFile.canRead() && labFile.canRead()) {
65+
if (wavFile.canRead() && textFile.canRead() && labFile.canRead()) {
5666
writer.println basename
5767
}
5868
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
package de.dfki.mary.voicebuilding.tasks
2+
3+
import org.gradle.testkit.runner.BuildResult
4+
import org.gradle.testkit.runner.GradleRunner
5+
import org.testng.annotations.Test
6+
7+
class GenerateBasenamesListFunctionalTest {
8+
9+
@Test
10+
void 'Given data directories, When basenames list is generated, Then basenames are in sort order'() {
11+
def projectDir = File.createTempDir()
12+
13+
def basenames = generateBasenames(5)
14+
createDataDirectories(projectDir, basenames)
15+
16+
generateBuildScript(projectDir)
17+
runGradle(projectDir)
18+
19+
def expected = basenames
20+
def actual = new File(projectDir, 'basenames.lst').readLines()
21+
assert expected == actual
22+
}
23+
24+
@Test
25+
void 'Given data directories with some missing files, When basenames list is generated, Then basenames exclude them'() {
26+
def projectDir = File.createTempDir()
27+
28+
def basenames = generateBasenames(6)
29+
createDataDirectories(projectDir, basenames)
30+
31+
new File(projectDir.path + File.separator + 'wav', 'test_0002.wav').delete()
32+
new File(projectDir.path + File.separator + 'txt', 'test_0004.txt').delete()
33+
new File(projectDir.path + File.separator + 'lab', 'test_0006.lab').delete()
34+
35+
generateBuildScript(projectDir)
36+
runGradle(projectDir)
37+
38+
def expected = basenames - ['test_0002', 'test_0004', 'test_0006']
39+
def actual = new File(projectDir, 'basenames.lst').readLines()
40+
assert expected == actual
41+
}
42+
43+
@Test
44+
void 'Given data directories, When custom list is provided, Then basenames are in custom order'() {
45+
def projectDir = File.createTempDir()
46+
47+
def basenames = generateBasenames(5)
48+
createDataDirectories(projectDir, basenames)
49+
50+
Collections.shuffle(basenames)
51+
new File(projectDir, 'custom.lst').withWriter { customList ->
52+
basenames.each { basename ->
53+
customList.writeLine(basename)
54+
}
55+
}
56+
57+
def buildScript = generateBuildScript(projectDir)
58+
buildScript << "basenames.srcFile = file('custom.lst')"
59+
runGradle(projectDir)
60+
61+
def expected = basenames
62+
def actual = new File(projectDir, 'basenames.lst').readLines()
63+
assert expected == actual
64+
}
65+
66+
@Test
67+
void 'Given data directories, When custom list with comments is provided, Then basenames are in custom order'() {
68+
def projectDir = File.createTempDir()
69+
70+
def basenames = generateBasenames(5)
71+
createDataDirectories(projectDir, basenames)
72+
73+
Collections.shuffle(basenames)
74+
new File(projectDir, 'custom.lst').withWriter { customList ->
75+
customList.writeLine('# This is the custom order:')
76+
basenames.eachWithIndex { basename, b ->
77+
customList.writeLine(basename)
78+
if (b == 3)
79+
customList.writeLine(' # Another comment!')
80+
}
81+
}
82+
83+
def buildScript = generateBuildScript(projectDir)
84+
buildScript << "basenames.srcFile = file('custom.lst')"
85+
runGradle(projectDir)
86+
87+
def expected = basenames
88+
def actual = new File(projectDir, 'basenames.lst').readLines()
89+
assert expected == actual
90+
}
91+
92+
@Test
93+
void 'Given data directories with some missing files, When custom list is provided, Then basenames exclude them and are in custom order'() {
94+
def projectDir = File.createTempDir()
95+
96+
def basenames = generateBasenames(6)
97+
createDataDirectories(projectDir, basenames)
98+
99+
Collections.shuffle(basenames)
100+
new File(projectDir, 'custom.lst').withWriter { customList ->
101+
basenames.each { basename ->
102+
customList.writeLine(basename)
103+
}
104+
}
105+
106+
new File(projectDir.path + File.separator + 'wav', 'test_0002.wav').delete()
107+
new File(projectDir.path + File.separator + 'txt', 'test_0004.txt').delete()
108+
new File(projectDir.path + File.separator + 'lab', 'test_0006.lab').delete()
109+
110+
def buildScript = generateBuildScript(projectDir)
111+
buildScript << "basenames.srcFile = file('custom.lst')"
112+
runGradle(projectDir)
113+
114+
def expected = basenames - ['test_0002', 'test_0004', 'test_0006']
115+
def actual = new File(projectDir, 'basenames.lst').readLines()
116+
assert expected == actual
117+
}
118+
119+
private static List<String> generateBasenames(int n) {
120+
(1..n).collect { i ->
121+
String.format('test_%04d', i)
122+
}
123+
}
124+
125+
private static List<String> createDataDirectories(projectDir, basenames) {
126+
['wav', 'txt', 'lab'].each { dirName ->
127+
def dir = new File(projectDir, dirName)
128+
dir.mkdir()
129+
basenames.each { basename ->
130+
new File(dir, "${basename}.${dirName}").createNewFile()
131+
}
132+
}
133+
}
134+
135+
private static File generateBuildScript(File projectDir) {
136+
def buildScript = new File(projectDir, 'build.gradle')
137+
buildScript.text = '''
138+
plugins {
139+
id 'de.dfki.mary.voicebuilding-data'
140+
}
141+
142+
basenames {
143+
wavDir = file('wav')
144+
textDir = file('txt')
145+
labDir = file('lab')
146+
destFile = file('basenames.lst')
147+
}
148+
'''.stripMargin()
149+
buildScript
150+
}
151+
152+
private static BuildResult runGradle(File projectDir) {
153+
def defaultArgs = ['--warning-mode', 'all', '--stacktrace', '--info']
154+
GradleRunner.create()
155+
.withProjectDir(projectDir)
156+
.withPluginClasspath()
157+
.forwardOutput()
158+
.withArguments(defaultArgs + 'basenames')
159+
.build()
160+
}
161+
}

src/test/resources/de/dfki/mary/voicebuilding/dataPluginFunctionalTestBuildScript.gradle

-9
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,6 @@ marytts {
99
}
1010

1111
repositories {
12-
ivy {
13-
url 'https://dl.bintray.com/marytts/marytts'
14-
patternLayout {
15-
artifact '[organisation]/[module]/[artifact].[ext]'
16-
}
17-
metadataSources {
18-
artifact()
19-
}
20-
}
2112
ivy {
2213
url 'http://festvox.org/examples'
2314
allowInsecureProtocol = true

src/test/resources/de/dfki/mary/voicebuilding/festvoxPluginFunctionalTestBuildScript.gradle

-9
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,6 @@ plugins {
33
}
44

55
repositories {
6-
ivy {
7-
url 'https://dl.bintray.com/marytts/marytts'
8-
patternLayout {
9-
artifact '[organisation]/[module]/[artifact].[ext]'
10-
}
11-
metadataSources {
12-
artifact()
13-
}
14-
}
156
ivy {
167
url 'http://festvox.org/examples'
178
allowInsecureProtocol = true

src/test/resources/de/dfki/mary/voicebuilding/legacyPluginFunctionalTestBuildScript.gradle

-9
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,6 @@ def voiceLocale = new Locale.Builder()
2929
.build()
3030

3131
repositories {
32-
ivy {
33-
url 'https://dl.bintray.com/marytts/marytts'
34-
patternLayout {
35-
artifact '[organisation]/[module]/[artifact].[ext]'
36-
}
37-
metadataSources {
38-
artifact()
39-
}
40-
}
4132
ivy {
4233
url 'http://festvox.org/examples'
4334
allowInsecureProtocol = true

0 commit comments

Comments
 (0)