diff --git a/ktlint/src/main/kotlin/com/pinterest/ktlint/Main.kt b/ktlint/src/main/kotlin/com/pinterest/ktlint/Main.kt index 2711707ccb..b295202f24 100644 --- a/ktlint/src/main/kotlin/com/pinterest/ktlint/Main.kt +++ b/ktlint/src/main/kotlin/com/pinterest/ktlint/Main.kt @@ -9,9 +9,9 @@ import com.pinterest.ktlint.core.ReporterProvider import com.pinterest.ktlint.core.RuleExecutionException import com.pinterest.ktlint.core.RuleSetProvider import com.pinterest.ktlint.internal.ApplyToIDEAGloballySubCommand +import com.pinterest.ktlint.internal.ApplyToIDEAProjectSubCommand import com.pinterest.ktlint.internal.GitPreCommitHookSubCommand import com.pinterest.ktlint.internal.GitPrePushHookSubCommand -import com.pinterest.ktlint.internal.IntellijIDEAIntegration import com.pinterest.ktlint.internal.KtlintVersionProvider import com.pinterest.ktlint.internal.PrintASTSubCommand import com.pinterest.ktlint.internal.expandTilde @@ -26,11 +26,8 @@ import java.io.IOException import java.io.PrintStream import java.net.URLClassLoader import java.net.URLDecoder -import java.nio.file.Paths import java.util.ArrayList import java.util.LinkedHashMap -import java.util.NoSuchElementException -import java.util.Scanner import java.util.ServiceLoader import java.util.concurrent.ArrayBlockingQueue import java.util.concurrent.Callable @@ -53,6 +50,7 @@ fun main(args: Array) { .addSubcommand(GitPrePushHookSubCommand.COMMAND_NAME, GitPrePushHookSubCommand()) .addSubcommand(PrintASTSubCommand.COMMAND_NAME, PrintASTSubCommand()) .addSubcommand(ApplyToIDEAGloballySubCommand.COMMAND_NAME, ApplyToIDEAGloballySubCommand()) + .addSubcommand(ApplyToIDEAProjectSubCommand.COMMAND_NAME, ApplyToIDEAProjectSubCommand()) val parseResult = commandLine.parseArgs(*args) commandLine.printHelpOrVersionUsage() @@ -73,6 +71,7 @@ fun handleSubCommand( is GitPrePushHookSubCommand -> subCommand.run() is PrintASTSubCommand -> subCommand.run() is ApplyToIDEAGloballySubCommand -> subCommand.run() + is ApplyToIDEAProjectSubCommand -> subCommand.run() else -> commandLine.usage(System.out, CommandLine.Help.Ansi.OFF) } } @@ -121,13 +120,6 @@ class KtlintCommandLine { ) var android: Boolean = false - // todo: make it a command in 1.0.0 (it's too late now as we might interfere with valid "lint" patterns) - @Option( - names = ["--apply-to-idea-project"], - description = ["Update Intellij IDEA project settings"] - ) - private var applyToProject: Boolean = false - @Option( names = ["--color"], description = ["Make output colorful"] @@ -202,12 +194,6 @@ class KtlintCommandLine { ) private var verbose: Boolean = false - @Option( - names = ["-y"], - hidden = true - ) - private var forceApply: Boolean = false - @Option( names = ["--editorconfig"], description = ["Path to .editorconfig"] @@ -224,10 +210,6 @@ class KtlintCommandLine { private var patterns = ArrayList() fun run() { - if (applyToProject) { - applyToIDEA() - exitProcess(0) - } val start = System.currentTimeMillis() // Detect custom rulesets that have not been moved to the new package @@ -423,42 +405,6 @@ class KtlintCommandLine { } } - private fun applyToIDEA() { - try { - val workDir = Paths.get(".") - if (!forceApply) { - val fileList = IntellijIDEAIntegration.apply(workDir, true, android, applyToProject) - System.err.println( - "The following files are going to be updated:\n\n\t" + - fileList.joinToString("\n\t") + - "\n\nDo you wish to proceed? [y/n]\n" + - "(in future, use -y flag if you wish to skip confirmation)" - ) - val scanner = Scanner(System.`in`) - val res = - generateSequence { - try { scanner.next() } catch (e: NoSuchElementException) { null } - } - .filter { line -> !line.trim().isEmpty() } - .first() - if (!"y".equals(res, ignoreCase = true)) { - System.err.println("(update canceled)") - exitProcess(1) - } - } - IntellijIDEAIntegration.apply(workDir, false, android, applyToProject) - } catch (e: IntellijIDEAIntegration.ProjectNotFoundException) { - System.err.println( - ".idea directory not found. " + - "Are you sure you are inside project root directory?" - ) - exitProcess(1) - } - System.err.println("(updated)") - System.err.println("\nPlease restart your IDE") - System.err.println("(if you experience any issues please report them at https://github.com/pinterest/ktlint)") - } - private fun List.head(limit: Int) = if (limit == size) this else this.subList(0, limit) private fun parseQuery(query: String) = diff --git a/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/ApplyToIDEACommandHelper.kt b/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/ApplyToIDEACommandHelper.kt new file mode 100644 index 0000000000..554f873e0f --- /dev/null +++ b/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/ApplyToIDEACommandHelper.kt @@ -0,0 +1,64 @@ +package com.pinterest.ktlint.internal + +import java.nio.file.Path +import java.nio.file.Paths +import kotlin.system.exitProcess + +class ApplyToIDEACommandHelper( + private val applyToProject: Boolean, + private val forceApply: Boolean, + private val isAndroidCodeStyle: Boolean +) { + fun apply() { + try { + val workDir = Paths.get(".") + + if (!forceApply && !getUserAcceptanceToUpdateFiles(workDir)) { + println("Update canceled.") + exitProcess(1) + } + + IntellijIDEAIntegration.apply( + workDir, + false, + isAndroidCodeStyle, + applyToProject + ) + } catch (e: IntellijIDEAIntegration.ProjectNotFoundException) { + println(".idea directory not found. Are you sure you are inside project root directory?") + exitProcess(1) + } + + println( + """ + |Updated. + |Please restart your IDE. + |If you experience any issues please report them at https://github.com/pinterest/ktlint/issues. + """.trimMargin() + ) + } + + private fun getUserAcceptanceToUpdateFiles(workDir: Path): Boolean { + val fileList = IntellijIDEAIntegration.apply( + workDir, + true, + isAndroidCodeStyle, + applyToProject + ) + println( + """ + |The following files are going to be updated: + |${fileList.joinToString(prefix = "\t", separator = "\n\t")} + | + |Do you wish to proceed? [y/n] + |(in future, use -y flag if you wish to skip confirmation) + """.trimMargin() + ) + + val userInput = generateSequence { readLine() } + .filter { it.trim().isNotBlank() } + .first() + + return "y".equals(userInput, ignoreCase = true) + } +} diff --git a/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/ApplyToIDEAGloballySubCommand.kt b/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/ApplyToIDEAGloballySubCommand.kt index 24fd280ebe..e7722d877e 100644 --- a/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/ApplyToIDEAGloballySubCommand.kt +++ b/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/ApplyToIDEAGloballySubCommand.kt @@ -1,9 +1,6 @@ package com.pinterest.ktlint.internal import com.pinterest.ktlint.KtlintCommandLine -import java.nio.file.Path -import java.nio.file.Paths -import kotlin.system.exitProcess import picocli.CommandLine @CommandLine.Command( @@ -30,46 +27,11 @@ class ApplyToIDEAGloballySubCommand : Runnable { override fun run() { commandSpec.commandLine().printHelpOrVersionUsage() - try { - val workDir = Paths.get(".") - - if (!forceApply && !getUserAcceptanceToUpdateFiles(workDir)) { - println("Update canceled.") - exitProcess(1) - } - - IntellijIDEAIntegration.apply(workDir, false, ktlintCommand.android, false) - } catch (e: IntellijIDEAIntegration.ProjectNotFoundException) { - println(".idea directory not found. Are you sure you are inside project root directory?") - exitProcess(1) - } - - println( - """ - |Updated. - |Please restart your IDE. - |If you experience any issues please report them at https://github.com/pinterest/ktlint/issues. - """.trimMargin() - ) - } - - private fun getUserAcceptanceToUpdateFiles(workDir: Path): Boolean { - val fileList = IntellijIDEAIntegration.apply(workDir, true, ktlintCommand.android, false) - println( - """ - |The following files are going to be updated: - |${fileList.joinToString(prefix = "\t", separator = "\n\t")} - | - |Do you wish to proceed? [y/n] - |(in future, use -y flag if you wish to skip confirmation) - """.trimMargin() - ) - - val userInput = generateSequence { readLine() } - .filter { it.trim().isNotBlank() } - .first() - - return "y".equals(userInput, ignoreCase = true) + ApplyToIDEACommandHelper( + false, + forceApply, + ktlintCommand.android + ).apply() } companion object { diff --git a/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/ApplyToIDEAProjectSubCommand.kt b/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/ApplyToIDEAProjectSubCommand.kt new file mode 100644 index 0000000000..ef3c6033f8 --- /dev/null +++ b/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/ApplyToIDEAProjectSubCommand.kt @@ -0,0 +1,40 @@ +package com.pinterest.ktlint.internal + +import com.pinterest.ktlint.KtlintCommandLine +import picocli.CommandLine + +@CommandLine.Command( + description = [ + "Update Intellij IDEA project settings" + ], + aliases = ["--apply-to-idea-project"], + mixinStandardHelpOptions = true, + versionProvider = KtlintVersionProvider::class +) +class ApplyToIDEAProjectSubCommand : Runnable { + @CommandLine.ParentCommand + private lateinit var ktlintCommand: KtlintCommandLine + + @CommandLine.Spec + private lateinit var commandSpec: CommandLine.Model.CommandSpec + + @CommandLine.Option( + names = ["-y"], + description = ["Overwrite existing Kotlin codestyle settings without asking"] + ) + private var forceApply: Boolean = false + + override fun run() { + commandSpec.commandLine().printHelpOrVersionUsage() + + ApplyToIDEACommandHelper( + true, + forceApply, + ktlintCommand.android + ).apply() + } + + companion object { + const val COMMAND_NAME = "applyToIDEAProject" + } +}