Skip to content

Commit 278f21b

Browse files
authored
Emulate and deprecate generatedFilesBaseDir (#636)
Fixes #33 for users not changing generatedFilesBaseDir. Stop documenting generatedFilesBaseDir since it produces poor results, but keep it functional with its existing Copy semantics. Fixes #332 This deprecates the setter, but I don't know how to make this trigger a warning, for either Groovy and Kotlin. Both seem to ignore it. Turn off UnnecessaryObjectReferences because it isn't providing value.
1 parent 2fbe179 commit 278f21b

File tree

7 files changed

+74
-62
lines changed

7 files changed

+74
-62
lines changed

README.md

+7-41
Original file line numberDiff line numberDiff line change
@@ -315,12 +315,10 @@ task.plugins {
315315

316316
```gradle
317317
protobuf {
318-
generatedFilesBaseDir = "$projectDir/generated"
319-
320318
generateProtoTasks {
321319
all().each { task ->
322320
task.builtins {
323-
// Generates Python code in the output folder:
321+
// Generates Python code
324322
python { }
325323
326324
// If you wish to avoid generating Java files:
@@ -410,7 +408,7 @@ protobuf {
410408
```gradle
411409
{ task ->
412410
// If true, will generate a descriptor_set.desc file under
413-
// $generatedFilesBaseDir/$sourceSet. Default is false.
411+
// task.outputBaseDir. Default is false.
414412
// See --descriptor_set_out in protoc documentation about what it is.
415413
task.generateDescriptorSet = true
416414
@@ -430,19 +428,11 @@ protobuf {
430428

431429
#### Change where files are generated
432430

433-
By default generated Java files are under
434-
``$generatedFilesBaseDir/$sourceSet/$builtinPluginName``, where
435-
``$generatedFilesBaseDir`` is ``$buildDir/generated/source/proto`` by default,
436-
and is configurable. E.g.,
437-
438-
```gradle
439-
protobuf {
440-
...
441-
 generatedFilesBaseDir = "$projectDir/src/generated"
442-
}
443-
```
431+
Generated files are under `task.outputBaseDir` with a subdirectory per
432+
builtin and plugin. This produces a folder structure of
433+
``$buildDir/generated/source/proto/$sourceSet/$builtinPluginName``.
444434

445-
The subdirectory name, which is by default ``$builtinPluginName``, can also be
435+
The subdirectory name, which is by default ``$builtinPluginName``, can be
446436
changed by setting the ``outputSubDir`` property in the ``builtins`` or
447437
``plugins`` block of a task configuration within ``generateProtoTasks`` block
448438
(see previous section). E.g.,
@@ -451,8 +441,7 @@ changed by setting the ``outputSubDir`` property in the ``builtins`` or
451441
{ task ->
452442
task.plugins {
453443
grpc {
454-
// Write the generated files under
455-
// "$generatedFilesBaseDir/$sourceSet/grpcjava"
444+
// Use subdirectory 'grpcjava' instead of the default 'grpc'
456445
outputSubDir = 'grpcjava'
457446
}
458447
}
@@ -521,29 +510,6 @@ This plugin integrates with the ``idea`` plugin and automatically
521510
registers the proto files and generated Java code as sources.
522511

523512

524-
```gradle
525-
apply plugin: 'idea'
526-
527-
protobuf {
528-
...
529-
generatedFilesBaseDir = "$projectDir/gen"
530-
}
531-
532-
clean {
533-
delete protobuf.generatedFilesBaseDir
534-
}
535-
536-
idea {
537-
module {
538-
// proto files and generated Java files are automatically added as
539-
// source dirs.
540-
// If you have additional sources, add them here:
541-
sourceDirs += file("/path/to/other/sources");
542-
}
543-
}
544-
```
545-
546-
547513
## Testing the plugin
548514

549515
``testProject*`` are testing projects that uses this plugin to compile

config/codenarc/codenarc.xml

+4
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8282
<ruleset-ref path='rulesets/unnecessary.xml'>
8383
<exclude name="UnnecessaryCollectCall"/>
8484
<exclude name="UnnecessaryGetter"/>
85+
8586
<exclude name="UnnecessaryGString"/>
8687
<exclude name="UnnecessarySetter"/>
8788
<exclude name="UnnecessaryPublicModifier"/>
8889
<exclude name="UnnecessaryReturnKeyword"/>
90+
91+
<!-- Poor suggestion when using static typing -->
92+
<exclude name="UnnecessaryObjectReferences"/>
8993
</ruleset-ref>
9094
</ruleset>

src/main/groovy/com/google/protobuf/gradle/CopyActionFacade.java

+25
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@
3333
import org.gradle.api.Action;
3434
import org.gradle.api.Project;
3535
import org.gradle.api.file.CopySpec;
36+
import org.gradle.api.file.DeleteSpec;
3637
import org.gradle.api.file.FileSystemOperations;
38+
import org.gradle.api.model.ObjectFactory;
3739
import org.gradle.api.tasks.WorkResult;
40+
import org.gradle.util.GradleVersion;
3841

3942
import javax.inject.Inject;
4043

@@ -46,6 +49,18 @@
4649
@CompileStatic
4750
interface CopyActionFacade {
4851
WorkResult copy(Action<? super CopySpec> var1);
52+
WorkResult delete(Action<? super DeleteSpec> action);
53+
54+
@CompileStatic
55+
final class Loader {
56+
public static CopyActionFacade create(Project project, ObjectFactory objectFactory) {
57+
if (GradleVersion.current().compareTo(GradleVersion.version("6.0")) >= 0) {
58+
// Use object factory to instantiate as that will inject the necessary service.
59+
return objectFactory.newInstance(CopyActionFacade.FileSystemOperationsBased.class);
60+
}
61+
return new CopyActionFacade.ProjectBased(project);
62+
}
63+
}
4964

5065
@CompileStatic
5166
class ProjectBased implements CopyActionFacade {
@@ -59,6 +74,11 @@ public ProjectBased(Project project) {
5974
public WorkResult copy(Action<? super CopySpec> action) {
6075
return project.copy(action);
6176
}
77+
78+
@Override
79+
public WorkResult delete(Action<? super DeleteSpec> action) {
80+
return project.delete(action);
81+
}
6282
}
6383

6484
@CompileStatic
@@ -70,5 +90,10 @@ abstract class FileSystemOperationsBased implements CopyActionFacade {
7090
public WorkResult copy(Action<? super CopySpec> action) {
7191
return getFileSystemOperations().copy(action);
7292
}
93+
94+
@Override
95+
public WorkResult delete(Action<? super DeleteSpec> action) {
96+
return getFileSystemOperations().delete(action);
97+
}
7398
}
7499
}

src/main/groovy/com/google/protobuf/gradle/GenerateProtoTask.groovy

+4
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ public abstract class GenerateProtoTask extends DefaultTask {
8181
static final int CMD_ARGUMENT_EXTRA_LENGTH = 3
8282
private static final String JAR_SUFFIX = ".jar"
8383

84+
private final CopyActionFacade copyActionFacade = CopyActionFacade.Loader.create(project, objectFactory)
8485
// include dirs are passed to the '-I' option of protoc. They contain protos
8586
// that may be "imported" from the source protos, but will not be compiled.
8687
private final ConfigurableFileCollection includeDirs = objectFactory.fileCollection()
@@ -587,6 +588,9 @@ public abstract class GenerateProtoTask extends DefaultTask {
587588
void compile() {
588589
Preconditions.checkState(state == State.FINALIZED, 'doneConfig() has not been called')
589590

591+
copyActionFacade.delete { spec ->
592+
spec.delete(outputBaseDir)
593+
}
590594
// Sort to ensure generated descriptors have a canonical representation
591595
// to avoid triggering unnecessary rebuilds downstream
592596
List<File> protoFiles = sourceDirs.asFileTree.files.sort()

src/main/groovy/com/google/protobuf/gradle/ProtobufExtension.groovy

+15-8
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import groovy.transform.TypeCheckingMode
3737
import org.gradle.api.Action
3838
import org.gradle.api.NamedDomainObjectContainer
3939
import org.gradle.api.Project
40+
import org.gradle.api.provider.Property
4041
import org.gradle.api.tasks.TaskCollection
4142

4243
/**
@@ -52,18 +53,16 @@ abstract class ProtobufExtension {
5253
private final ArrayList<Action<GenerateProtoTaskCollection>> taskConfigActions
5354
private final NamedDomainObjectContainer<ProtoSourceSet> sourceSets
5455

55-
/**
56-
* The base directory of generated files. The default is
57-
* "${project.buildDir}/generated/source/proto".
58-
*/
59-
private String generatedFilesBaseDir
56+
@PackageScope
57+
final String defaultGeneratedFilesBaseDir
6058

6159
public ProtobufExtension(final Project project) {
6260
this.project = project
6361
this.tasks = new GenerateProtoTaskCollection(project)
6462
this.tools = new ToolsLocator(project)
6563
this.taskConfigActions = []
66-
this.generatedFilesBaseDir = "${project.buildDir}/generated/source/proto"
64+
this.defaultGeneratedFilesBaseDir = "${project.buildDir}/generated/source/proto"
65+
this.generatedFilesBaseDirProperty.convention(defaultGeneratedFilesBaseDir)
6766
this.sourceSets = project.objects.domainObjectContainer(ProtoSourceSet) { String name ->
6867
new DefaultProtoSourceSet(name, project.objects)
6968
}
@@ -80,13 +79,21 @@ abstract class ProtobufExtension {
8079
}
8180

8281
String getGeneratedFilesBaseDir() {
83-
return generatedFilesBaseDir
82+
return generatedFilesBaseDirProperty.get()
8483
}
8584

85+
@Deprecated
8686
void setGeneratedFilesBaseDir(String generatedFilesBaseDir) {
87-
this.generatedFilesBaseDir = generatedFilesBaseDir
87+
generatedFilesBaseDirProperty.set(generatedFilesBaseDir)
8888
}
8989

90+
/**
91+
* The base directory of generated files. The default is
92+
* "${project.buildDir}/generated/source/proto".
93+
*/
94+
@PackageScope
95+
abstract Property<String> getGeneratedFilesBaseDirProperty()
96+
9097
@PackageScope
9198
void configureTasks() {
9299
this.taskConfigActions.each { action ->

src/main/groovy/com/google/protobuf/gradle/ProtobufExtract.groovy

+1-9
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ import javax.inject.Inject
5757
@CompileStatic
5858
abstract class ProtobufExtract extends DefaultTask {
5959

60-
private final CopyActionFacade copyActionFacade = instantiateCopyActionFacade()
60+
private final CopyActionFacade copyActionFacade = CopyActionFacade.Loader.create(project, objectFactory)
6161
private final ArchiveActionFacade archiveActionFacade = instantiateArchiveActionFacade()
6262
private final FileCollection filteredProtos = instantiateFilteredProtos()
6363

@@ -98,14 +98,6 @@ abstract class ProtobufExtract extends DefaultTask {
9898
@Inject
9999
protected abstract ProviderFactory getProviderFactory()
100100

101-
private CopyActionFacade instantiateCopyActionFacade() {
102-
if (GradleVersion.current() >= GradleVersion.version("6.0")) {
103-
// Use object factory to instantiate as that will inject the necessary service.
104-
return objectFactory.newInstance(CopyActionFacade.FileSystemOperationsBased)
105-
}
106-
return new CopyActionFacade.ProjectBased(project)
107-
}
108-
109101
private ArchiveActionFacade instantiateArchiveActionFacade() {
110102
if (GradleVersion.current() >= GradleVersion.version("6.0")) {
111103
// Use object factory to instantiate as that will inject the necessary service.

src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy

+18-4
Original file line numberDiff line numberDiff line change
@@ -374,15 +374,29 @@ class ProtobufPlugin implements Plugin<Project> {
374374
) {
375375
String sourceSetName = protoSourceSet.name
376376
String taskName = 'generate' + Utils.getSourceSetSubstringForTaskNames(sourceSetName) + 'Proto'
377-
Provider<String> outDir = project.providers.provider {
378-
"${this.protobufExtension.generatedFilesBaseDir}/${sourceSetName}".toString()
379-
}
377+
String defaultGeneratedFilesBaseDir = protobufExtension.defaultGeneratedFilesBaseDir
378+
Provider<String> generatedFilesBaseDirProvider = protobufExtension.generatedFilesBaseDirProperty
380379
Provider<GenerateProtoTask> task = project.tasks.register(taskName, GenerateProtoTask) {
380+
CopyActionFacade copyActionFacade = CopyActionFacade.Loader.create(it.project, it.objectFactory)
381381
it.description = "Compiles Proto source for '${sourceSetName}'".toString()
382-
it.outputBaseDir = outDir
382+
it.outputBaseDir = project.providers.provider {
383+
"${defaultGeneratedFilesBaseDir}/${sourceSetName}".toString()
384+
}
383385
it.addSourceDirs(protoSourceSet.proto)
384386
it.addIncludeDir(protoSourceSet.proto.sourceDirectories)
385387
it.addIncludeDir(protoSourceSet.includeProtoDirs)
388+
it.doLast { task ->
389+
String generatedFilesBaseDir = generatedFilesBaseDirProvider.get()
390+
if (generatedFilesBaseDir == defaultGeneratedFilesBaseDir) {
391+
return
392+
}
393+
// Purposefully don't wire this up to outputs, as it can be mixed with other files.
394+
copyActionFacade.copy { CopySpec spec ->
395+
spec.includeEmptyDirs = false
396+
spec.from(it.outputBaseDir)
397+
spec.into("${generatedFilesBaseDir}/${sourceSetName}")
398+
}
399+
}
386400
configureAction.execute(it)
387401
}
388402
protoSourceSet.output.from(task.map { GenerateProtoTask it -> it.outputSourceDirectories })

0 commit comments

Comments
 (0)