Skip to content

Commit 271a154

Browse files
committed
feat: poc of cli (step 1)
1 parent 5a5db69 commit 271a154

16 files changed

+441
-1
lines changed

cli/CHANGES.md

Whitespace-only changes.

cli/build.gradle

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
plugins {
2+
id 'org.graalvm.buildtools.native'
3+
}
4+
apply from: rootProject.file('gradle/changelog.gradle')
5+
ext.artifactId = project.artifactIdGradle
6+
version = spotlessChangelog.versionNext
7+
apply plugin: 'java-library'
8+
apply plugin: 'application'
9+
apply from: rootProject.file('gradle/java-setup.gradle')
10+
apply from: rootProject.file('gradle/spotless-freshmark.gradle')
11+
12+
dependencies {
13+
// todo, unify with plugin-gradle/build.gradle -- BEGIN
14+
if (version.endsWith('-SNAPSHOT') || (rootProject.spotlessChangelog.versionNext == rootProject.spotlessChangelog.versionLast)) {
15+
api projects.lib
16+
api projects.libExtra
17+
} else {
18+
api "com.diffplug.spotless:spotless-lib:${rootProject.spotlessChangelog.versionLast}"
19+
api "com.diffplug.spotless:spotless-lib-extra:${rootProject.spotlessChangelog.versionLast}"
20+
}
21+
implementation "com.diffplug.durian:durian-core:${VER_DURIAN}"
22+
implementation "com.diffplug.durian:durian-io:${VER_DURIAN}"
23+
implementation "com.diffplug.durian:durian-collect:${VER_DURIAN}"
24+
implementation "org.eclipse.jgit:org.eclipse.jgit:${VER_JGIT}"
25+
26+
testImplementation projects.testlib
27+
testImplementation "org.junit.jupiter:junit-jupiter:${VER_JUNIT}"
28+
testImplementation "org.assertj:assertj-core:${VER_ASSERTJ}"
29+
testImplementation "com.diffplug.durian:durian-testlib:${VER_DURIAN}"
30+
testImplementation 'org.owasp.encoder:encoder:1.3.1'
31+
testRuntimeOnly "org.junit.platform:junit-platform-launcher"
32+
// todo, unify with plugin-gradle/build.gradle -- END
33+
34+
implementation "info.picocli:picocli:${VER_PICOCLI}"
35+
annotationProcessor "info.picocli:picocli-codegen:${VER_PICOCLI}"
36+
}
37+
38+
compileJava {
39+
options.compilerArgs += [
40+
"-Aproject=${project.group}/${project.name}"
41+
]
42+
}
43+
44+
tasks.withType(org.graalvm.buildtools.gradle.tasks.GenerateResourcesConfigFile).configureEach {
45+
notCompatibleWithConfigurationCache('https://github.com/britter/maven-plugin-development/issues/8')
46+
}
47+
tasks.withType(org.graalvm.buildtools.gradle.tasks.BuildNativeImageTask).configureEach {
48+
notCompatibleWithConfigurationCache('https://github.com/britter/maven-plugin-development/issues/8')
49+
}
50+
51+
// use tasks 'nativeCompile' and 'nativeRun' to compile and run the native image
52+
graalvmNative {
53+
binaries {
54+
main {
55+
imageName = 'spotless'
56+
mainClass = 'com.diffplug.spotless.cli.SpotlessCLI'
57+
sharedLibrary = false
58+
59+
runtimeArgs.add('--user=ABC')
60+
}
61+
}
62+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2024 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.cli;
17+
18+
import com.diffplug.spotless.cli.execution.SpotlessExecutionStrategy;
19+
import com.diffplug.spotless.cli.subcommands.SpotlessApply;
20+
import com.diffplug.spotless.cli.subcommands.SpotlessCheck;
21+
22+
import picocli.CommandLine;
23+
import picocli.CommandLine.Command;
24+
25+
@Command(name = "spotless cli", mixinStandardHelpOptions = true, version = "spotless ${version}", // https://picocli.info/#_dynamic_version_information
26+
description = "Runs spotless", subcommands = {SpotlessCheck.class, SpotlessApply.class})
27+
public class SpotlessCLI implements SpotlessCommand {
28+
29+
@CommandLine.Option(names = {"-V", "--version"}, versionHelp = true, description = "Print version information and exit")
30+
boolean versionRequested;
31+
32+
@CommandLine.Option(names = {"-h", "--help"}, usageHelp = true, description = "display this help message")
33+
boolean usageHelpRequested;
34+
35+
public static void main(String... args) {
36+
// args = new String[]{"--version"};
37+
args = new String[]{"apply", "license-header", "--header-file", "abc.txt", "license-header", "--header", "abc"};
38+
int exitCode = new CommandLine(new SpotlessCLI())
39+
.setExecutionStrategy(new SpotlessExecutionStrategy())
40+
.execute(args);
41+
System.exit(exitCode);
42+
}
43+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright 2024 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.cli;
17+
18+
public interface SpotlessCommand {}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2024 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.cli.execution;
17+
18+
import static picocli.CommandLine.executeHelpRequest;
19+
20+
import java.util.function.Function;
21+
22+
import com.diffplug.spotless.cli.SpotlessCommand;
23+
import com.diffplug.spotless.cli.subcommands.SpotlessActionCommand;
24+
import com.diffplug.spotless.cli.subcommands.steps.SpotlessCLIStep;
25+
26+
import picocli.CommandLine;
27+
28+
public class SpotlessExecutionStrategy implements CommandLine.IExecutionStrategy {
29+
30+
public int execute(CommandLine.ParseResult parseResult) throws CommandLine.ExecutionException {
31+
Integer helpResult = executeHelpRequest(parseResult);
32+
if (helpResult != null) {
33+
return helpResult;
34+
}
35+
return runSpotlessActions(parseResult);
36+
}
37+
38+
private Integer runSpotlessActions(CommandLine.ParseResult parseResult) {
39+
// 1. run setup (for combining steps handled as subcommands)
40+
41+
// TODO: maybe collect a list of steps and pass them to the spotless action in step 2?
42+
Integer prepareResult = runSpotlessRecursive(parseResult, this::prepareStep);
43+
if (prepareResult != null) {
44+
return prepareResult;
45+
}
46+
// 2. run spotless steps
47+
return runSpotlessRecursive(parseResult, this::executeSpotlessAction);
48+
}
49+
50+
private Integer runSpotlessRecursive(CommandLine.ParseResult parseResult, Function<SpotlessCommand, Integer> action) {
51+
SpotlessCommand spotlessCommand = parseResult.commandSpec().commandLine().getCommand();
52+
Integer result = action.apply(spotlessCommand);
53+
if (result != null) {
54+
return result;
55+
}
56+
for (CommandLine.ParseResult subCommand : parseResult.subcommands()) {
57+
Integer subResult = runSpotlessRecursive(subCommand, action);
58+
if (subResult != null) {
59+
return subResult;
60+
}
61+
}
62+
return null;
63+
}
64+
65+
private Integer prepareStep(SpotlessCommand spotlessCommand) {
66+
if (spotlessCommand instanceof SpotlessCLIStep) {
67+
((SpotlessCLIStep) spotlessCommand).prepare();
68+
}
69+
return null;
70+
}
71+
72+
private Integer executeSpotlessAction(SpotlessCommand spotlessCommand) {
73+
if (spotlessCommand instanceof SpotlessActionCommand) {
74+
return ((SpotlessActionCommand) spotlessCommand).executeSpotlessAction();
75+
}
76+
return null;
77+
}
78+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright 2024 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.cli.subcommands;
17+
18+
import com.diffplug.spotless.cli.SpotlessCommand;
19+
20+
public interface SpotlessActionCommand extends SpotlessCommand {
21+
Integer executeSpotlessAction();
22+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2024 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.cli.subcommands;
17+
18+
import com.diffplug.spotless.cli.subcommands.steps.generic.LicenseHeader;
19+
import com.diffplug.spotless.cli.subcommands.steps.generic.RemoveMeLaterSubCommand;
20+
21+
import picocli.CommandLine;
22+
23+
// repeatable subcommands: https://picocli.info/#_repeatable_subcommands_specification
24+
25+
// access command spec: https://picocli.info/#spec-annotation
26+
27+
@CommandLine.Command(mixinStandardHelpOptions = true, subcommandsRepeatable = true, subcommands = {
28+
LicenseHeader.class,
29+
RemoveMeLaterSubCommand.class
30+
})
31+
public abstract class SpotlessActionSubCommand implements SpotlessActionCommand {
32+
33+
@Override
34+
public Integer executeSpotlessAction() {
35+
System.out.println("Hello " + getClass().getSimpleName() + ", abc!");
36+
return 0;
37+
}
38+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2024 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.cli.subcommands;
17+
18+
import picocli.CommandLine;
19+
20+
@CommandLine.Command(name = "apply", description = "Runs spotless apply")
21+
public class SpotlessApply extends SpotlessActionSubCommand {
22+
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2024 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.cli.subcommands;
17+
18+
import picocli.CommandLine;
19+
20+
@CommandLine.Command(name = "check", description = "Runs spotless check")
21+
public class SpotlessCheck extends SpotlessActionSubCommand {
22+
23+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright 2024 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.cli.subcommands.steps;
17+
18+
import com.diffplug.spotless.cli.SpotlessCommand;
19+
20+
public interface SpotlessCLIStep extends SpotlessCommand {
21+
void prepare();
22+
}

0 commit comments

Comments
 (0)