From 9c7330f387bd7b5b0d210ed1162edc107cb5180c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E4=B8=87=E7=A8=8B?= <1498425439@qq.com> Date: Sat, 18 Nov 2023 21:44:52 +0800 Subject: [PATCH] IDEA plugin --- .idea/encodings.xml | 2 +- .idea/misc.xml | 28 +- .run/Main.run.xml | 18 ++ .run/Run IDE for UI Tests.run.xml | 25 ++ .run/Run Plugin.run.xml | 24 ++ .run/Run Qodana.run.xml | 30 +++ .run/Run Tests.run.xml | 24 ++ .run/Run Verifications.run.xml | 26 ++ .run/buildPlugin.run.xml | 25 ++ CHANGELOG.md | 11 + Jenkins.md | 35 +++ README.md | 100 ++++++- build.gradle.kts | 122 +++++++++ gradle.properties | 38 +++ gradlew | 245 ++++++++++++++++++ gradlew.bat | 92 +++++++ qodana.yml | 12 + settings.gradle.kts | 1 + .../java/io/github/linwancen/sql/DiffSql.java | 8 +- .../java/io/github/linwancen/sql/Main.java | 4 +- .../io/github/linwancen/util/CmdUtils.java | 21 +- .../io/github/linwancen/util/PathUtils.java | 3 - .../github/linwancen/util/git/GitUtils.java | 6 +- .../linwancen/plugin/sql/action/SqlList.kt | 71 +++++ .../github/linwancen/plugin/sql/ui/I18n.kt | 21 ++ src/main/resources/META-INF/plugin.xml | 20 ++ src/main/resources/META-INF/pluginIcon.svg | 11 + src/main/resources/messages/I18n.properties | 2 + .../resources/messages/I18n_zh.properties | 2 + 29 files changed, 988 insertions(+), 39 deletions(-) create mode 100644 .run/Main.run.xml create mode 100644 .run/Run IDE for UI Tests.run.xml create mode 100644 .run/Run Plugin.run.xml create mode 100644 .run/Run Qodana.run.xml create mode 100644 .run/Run Tests.run.xml create mode 100644 .run/Run Verifications.run.xml create mode 100644 .run/buildPlugin.run.xml create mode 100644 CHANGELOG.md create mode 100644 Jenkins.md create mode 100644 build.gradle.kts create mode 100644 gradle.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 qodana.yml create mode 100644 settings.gradle.kts create mode 100644 src/main/kotlin/com/github/linwancen/plugin/sql/action/SqlList.kt create mode 100644 src/main/kotlin/com/github/linwancen/plugin/sql/ui/I18n.kt create mode 100644 src/main/resources/META-INF/plugin.xml create mode 100644 src/main/resources/META-INF/pluginIcon.svg create mode 100644 src/main/resources/messages/I18n.properties create mode 100644 src/main/resources/messages/I18n_zh.properties diff --git a/.idea/encodings.xml b/.idea/encodings.xml index a156f52..fbed62b 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -1,6 +1,6 @@ - + diff --git a/.idea/misc.xml b/.idea/misc.xml index 0c41917..0cc3b9f 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,14 +1,16 @@ - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/.run/Main.run.xml b/.run/Main.run.xml new file mode 100644 index 0000000..369fbe4 --- /dev/null +++ b/.run/Main.run.xml @@ -0,0 +1,18 @@ + + + + \ No newline at end of file diff --git a/.run/Run IDE for UI Tests.run.xml b/.run/Run IDE for UI Tests.run.xml new file mode 100644 index 0000000..ee99b7e --- /dev/null +++ b/.run/Run IDE for UI Tests.run.xml @@ -0,0 +1,25 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/Run Plugin.run.xml b/.run/Run Plugin.run.xml new file mode 100644 index 0000000..d15ff68 --- /dev/null +++ b/.run/Run Plugin.run.xml @@ -0,0 +1,24 @@ + + + + + + + + true + true + false + + + \ No newline at end of file diff --git a/.run/Run Qodana.run.xml b/.run/Run Qodana.run.xml new file mode 100644 index 0000000..c92f33c --- /dev/null +++ b/.run/Run Qodana.run.xml @@ -0,0 +1,30 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/Run Tests.run.xml b/.run/Run Tests.run.xml new file mode 100644 index 0000000..132d9ad --- /dev/null +++ b/.run/Run Tests.run.xml @@ -0,0 +1,24 @@ + + + + + + + + true + true + false + + + diff --git a/.run/Run Verifications.run.xml b/.run/Run Verifications.run.xml new file mode 100644 index 0000000..3a8d688 --- /dev/null +++ b/.run/Run Verifications.run.xml @@ -0,0 +1,26 @@ + + + + + + + + true + true + false + + + + \ No newline at end of file diff --git a/.run/buildPlugin.run.xml b/.run/buildPlugin.run.xml new file mode 100644 index 0000000..4c9546b --- /dev/null +++ b/.run/buildPlugin.run.xml @@ -0,0 +1,25 @@ + + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..35323ec --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,11 @@ + + +# sql-list Changelog + +## [1.0.0] + +- 1.00 init + +# 中文更新日志 + +- 1.00 基本功能 \ No newline at end of file diff --git a/Jenkins.md b/Jenkins.md new file mode 100644 index 0000000..cc7ac19 --- /dev/null +++ b/Jenkins.md @@ -0,0 +1,35 @@ +# Jenkins 使用方式指南 + +- 可以`mvn package`生成或在这里下载 zip:https://github.com/LinWanCen/sql-list/releases +- 然后在服务器上执行以下命令创建目录上传解压 + ```shell script + mkidr /var/lib/jenkins/workspace/sql-list + cd /var/lib/jenkins/workspace/sql-list + rz + unzip sql-list.zip + ``` +- 登陆 Jenkins +- 点击 新建Item +- 创建自由风格(Freestyle project)的项目 +- 描述 + 1. 点击 Build with Parameters + 2. 选择文件后点击"开始构建",等左下角上传进度完成 + 3. 执行完毕后点击"工作区"或"工作空间" + 4. 点击打包下载全部文件 + 5. 解压后用 IDEA 打开 + 6. 选择两个文件夹,右键比较即可 + - [x] Discard old builds + - 保持构建的最大个数 5 + - [x] This project is parameterized + - File Parameter + - file1 + - file2 +- 构建环境 + - [x] Delete workspace before build starts +- 构建 + - Execute shell + ```shell script + mv file1 "1-$file1" + mv file2 "2-$file2" + java -jar /var/lib/jenkins/workspace/sql-list/sql-list.jar "1-$file1" "2-$file2" + ``` \ No newline at end of file diff --git a/README.md b/README.md index c271042..7310fde 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,97 @@ -# SQL 清单 +# SQL 清单 sql-list -解析 Mapper.xml 中的 SQL,涉及的表和条件列,Git 最后修改时间和作者,生成 Excel 表格 +[![Version](https://img.shields.io/jetbrains/plugin/v/23142-sql-list.svg)](https://plugins.jetbrains.com/plugin/23142-sql-list) +[![Downloads](https://img.shields.io/jetbrains/plugin/d/23142-sql-list.svg)](https://plugins.jetbrains.com/plugin/23142-sql-list) -## 入参 +- [Maven package for Jenkins etc](Jenkins.md). +- Gradle build for IDEA plugin. + +- 入参 + - 多个目录 + - 多个文件 + - gitHash..gitHash 多个 Git 根目录 + - gitBranch..gitBranch 多个 Git 根目录 + - diff 旧目录 新目录 + - 无入参时 GUI 弹框选择 + + +## Plugin description 插件介绍 + + + +Export Mapper.xml SQL to Excel. + +解析 Mapper.xml 中的 SQL,涉及的表和条件列,Git 最后修改时间和作者,生成 Excel 表格。 + +## How to Use + +- Select dir and right-clickExport Mapper.xml SQL +- Select two dir and right-clickExport Mapper.xml diff SQL + +## My Plugin +- Show doc comment at the Project view Tree, line End, json etc.: [Show Comment] +- Method call usage graph and maven dependency graph: [Draw Graph] +- Find author/comment of multiple files or lines and export Find: [Find Author] +- Auto sync coverage and capture coverage during debug: [Sync Coverage] +- UnCompress and Delete same, use `javap -c` decompile class: [Compare Jar] +- Export Mapper.xml SQL to Excel: [SQL List] + +--- + +# 中文 + +## 用法 + +- 选择多个目录右键点击导出 Mapper.xml 的 SQL +- 选择两个目录右键点击导出 Mapper.xml 差异的 SQL + +在服务器中用 Jenkins 运行详见 [Jenkins 使用方式指南][Jenkins]。 + +## 我的项目 +- 在文件树、行末、JSON 显示注释:[Show Comment] +- 生成 方法调用图 和 Maven 依赖图:[Draw Graph] +- 查找多个文件或行的作者 与 导出搜索:[Find Author] +- 自动同步覆盖率 和 调试中抓取覆盖率:[Sync Coverage] +- 逐层解压,删除相同文件,反编译 class 对比:[Compare Jar] +- 解析 Mapper.xml 中的 SQL,涉及的表和条件列,Git 最后修改时间和作者,生成 Excel 表格:[SQL List] + +--- + +# 支持 + +如果对你有所帮助,别忘了给 [本项目 GitHub 主页][GitHub] 一个 Star,您的支持是项目前进的动力。 + +[Show Comment]: https://plugins.jetbrains.com/plugin/18553-show-comment +[Draw Graph]: https://plugins.jetbrains.com/plugin/draw-graph +[Find Author]: https://plugins.jetbrains.com/plugin/20557-find-author +[Sync Coverage]: https://plugins.jetbrains.com/plugin/20780-sync-coverage +[Compare Jar]: https://plugins.jetbrains.com/plugin/22356-compare-jar +[SQL List]: https://plugins.jetbrains.com/plugin/23142-sql-list +[GitHub]: https://github.com/LinWanCen/sql-list +[Jenkins]: https://github.com/LinWanCen/sql-list/Jenkins.md + + + +## Installation + +- Using IDE built-in plugin system: + + Settings/Preferences > Plugins > Marketplace > Search for "sql-list" > + Install Plugin + +- Manually: + + Download the [latest release](https://github.com/LinWanCen/sql-list/releases/latest) and install it manually using + Settings/Preferences > Plugins > ⚙️ > Install plugin from disk... + +[Changelog 更新说明](CHANGELOG.md) + +--- +Plugin based on the [IntelliJ Platform Plugin Template][template]. + +[template]: https://github.com/JetBrains/intellij-platform-plugin-template +[docs:plugin-description]: https://plugins.jetbrains.com/docs/intellij/plugin-user-experience.html#plugin-description-and-presentation -- 多个目录 -- 多个文件 -- gitHash..gitHash 多个 Git 根目录 -- gitBranch..gitBranch 多个 Git 根目录 -- diff 旧目录 新目录 -- 无入参时 GUI 弹框选择 ## TODO diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..8061907 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,122 @@ +import org.jetbrains.changelog.markdownToHTML +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter + +fun properties(key: String) = project.findProperty(key).toString() +fun environment(key: String) = providers.environmentVariable(key) + +plugins { + id("java") + id("org.jetbrains.kotlin.jvm") version "1.5.31" + id("org.jetbrains.intellij") version "1.0" + id("org.jetbrains.changelog") version "1.2.1" + id("org.jetbrains.qodana") version "0.1.13" +} + +group = properties("pluginGroup") +val ver = "${properties("pluginVersion")}.${DateTimeFormatter.ofPattern("yyyy.MM.dd_HH.mm").format(LocalDateTime.now())}" +version = ver + +// Configure project's dependencies +repositories { + mavenCentral() +} + +// Dependencies are managed with Gradle version catalog - read more: https://docs.gradle.org/current/userguide/platforms.html#sub:version-catalog +dependencies { +// implementation(libs.annotations) + implementation("org.apache.commons:commons-exec:1.3") + implementation("com.alibaba:druid:1.2.20") + implementation("com.alibaba:easyexcel:3.3.2") + implementation("org.jdom:jdom2:2.0.6") + implementation("org.apache.logging.log4j:log4j-slf4j-impl:2.17.0") + implementation("com.lmax:disruptor:3.4.4") +} + +// Set the JVM language level used to build the project. Use Java 11 for 2020.3+, and Java 17 for 2022.2+. +kotlin { + jvmToolchain { + JavaLanguageVersion.of(11) + } +} + +// Configure Gradle IntelliJ Plugin - read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html +intellij { + pluginName.set(properties("pluginName")) + version.set(properties("platformVersion")) + type.set(properties("platformType")) + + // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file. + plugins.set(properties("platformPlugins").split(',').map(String::trim).filter(String::isNotEmpty)) +} + +// Configure Gradle Changelog Plugin - read more: https://github.com/JetBrains/gradle-changelog-plugin +changelog { + groups.empty() + // repositoryUrl.set(properties("pluginRepositoryUrl")) +} + +// Configure Gradle Qodana Plugin - read more: https://github.com/JetBrains/gradle-qodana-plugin +qodana { + cachePath.set(projectDir.resolve(".qodana").canonicalPath) + reportPath.set(projectDir.resolve("build/reports/inspections").canonicalPath) + saveReport.set(true) + showReport.set(System.getenv("QODANA_SHOW_REPORT")?.toBoolean() ?: false) +} + +tasks { + wrapper { + gradleVersion = properties("gradleVersion") + } + + patchPluginXml { + version.set(ver) + sinceBuild.set(properties("pluginSinceBuild")) + untilBuild.set(properties("pluginUntilBuild")) + + // Extract the section from README.md and provide for the plugin's manifest + pluginDescription.set(providers.fileContents(layout.projectDirectory.file("README.md")).asText.map { + val start = "" + val end = "" + + with (it.lines()) { + if (!containsAll(listOf(start, end))) { + throw GradleException("Plugin description section not found in README.md:\n$start ... $end") + } + subList(indexOf(start) + 1, indexOf(end)).joinToString("\n").let(::markdownToHTML) + } + }) + + val changelog = project.changelog // local variable for configuration cache compatibility + // Get the latest available change notes from the changelog file + changeNotes.set(provider { + changelog.run { + getOrNull(properties("pluginVersion")) ?: getLatest() + }.toHTML() + }) + } + + // Configure UI tests plugin + // Read more: https://github.com/JetBrains/intellij-ui-test-robot + runIdeForUiTests { + systemProperty("robot-server.port", "8082") + systemProperty("ide.mac.message.dialogs.as.sheets", "false") + systemProperty("jb.privacy.policy.text", "") + systemProperty("jb.consents.confirmation.enabled", "false") + } + + signPlugin { + certificateChain.set(System.getenv("CERTIFICATE_CHAIN")) + privateKey.set(System.getenv("PRIVATE_KEY")) + password.set(System.getenv("PRIVATE_KEY_PASSWORD")) + } + + publishPlugin { + dependsOn("patchChangelog") + token.set(System.getenv("PUBLISH_TOKEN")) + // The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3 + // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more: + // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel + channels.set(listOf(properties("pluginVersion").split('-').getOrElse(1) { "default" }.split('.').first())) + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..bc07091 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,38 @@ +# IntelliJ Platform Artifacts Repositories -> https://plugins.jetbrains.com/docs/intellij/intellij-artifacts.html + +pluginGroup = com.github.linwancen.plugin.sql +pluginName = sql-list +pluginRepositoryUrl = https://github.com/LinWanCen/sql-list +# SemVer format -> https://semver.org +pluginVersion = 1.00 + +# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html +pluginSinceBuild = 201 +pluginUntilBuild = + +# IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension +platformType = IC +platformVersion = 2020.1 + +# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html +# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 +platformPlugins = + +# Gradle Releases -> https://github.com/gradle/gradle/releases +gradleVersion = 8.1.1 + +# Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib +kotlin.stdlib.default.dependency = false + +# Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html +# Enabling it will cause the *.java with *.form constructor NPE +org.gradle.configuration-cache = true + +# Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html +org.gradle.caching = true + +# Enable Gradle Kotlin DSL Lazy Property Assignment -> https://docs.gradle.org/current/userguide/kotlin_dsl.html#kotdsl:assignment +systemProp.org.gradle.unsafe.kotlin.assignment = true + +# Temporary workaround for Kotlin Compiler OutOfMemoryError -> https://jb.gg/intellij-platform-kotlin-oom +kotlin.incremental.useClasspathSnapshot = false diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..aeb74cb --- /dev/null +++ b/gradlew @@ -0,0 +1,245 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..93e3f59 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/qodana.yml b/qodana.yml new file mode 100644 index 0000000..f388de9 --- /dev/null +++ b/qodana.yml @@ -0,0 +1,12 @@ +# Qodana configuration: +# https://www.jetbrains.com/help/qodana/qodana-yaml.html + +version: 1.0 +linter: jetbrains/qodana-jvm-community:latest +projectJDK: 17 +profile: + name: qodana.recommended +exclude: + - name: All + paths: + - .qodana diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..0a86dc3 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "sql-list" diff --git a/src/main/java/io/github/linwancen/sql/DiffSql.java b/src/main/java/io/github/linwancen/sql/DiffSql.java index 603ca87..5ac32c8 100644 --- a/src/main/java/io/github/linwancen/sql/DiffSql.java +++ b/src/main/java/io/github/linwancen/sql/DiffSql.java @@ -24,12 +24,12 @@ public static void diff(String[] args, DbType dbType, Consumer> fu int i2 = args[2].lastIndexOf('.'); String dir1 = i1 > 0 ? args[1].substring(0, i1) : args[1]; String dir2 = i2 > 0 ? args[2].substring(0, i2) : args[2]; - diffDir(dbType, fun, dir1, dir2); + diffDir(dbType, new File(dir1), new File(dir2), fun); } - public static void diffDir(DbType dbType, Consumer> fun, String dir1, String dir2) { - List oldList = AllParser.parse(Collections.singletonList(new File(dir1)), dbType, null); - List newList = AllParser.parse(Collections.singletonList(new File(dir2)), dbType, null); + public static void diffDir(DbType dbType, File file1, File file2, Consumer> fun) { + List oldList = AllParser.parse(Collections.singletonList(file1), dbType, null); + List newList = AllParser.parse(Collections.singletonList(file2), dbType, null); Map oldMap = toIdMap(oldList); // delete duplicate Map newMap = toIdMap(newList); diff --git a/src/main/java/io/github/linwancen/sql/Main.java b/src/main/java/io/github/linwancen/sql/Main.java index 0ad614a..c07823c 100644 --- a/src/main/java/io/github/linwancen/sql/Main.java +++ b/src/main/java/io/github/linwancen/sql/Main.java @@ -26,11 +26,11 @@ public static void main(String[] args) { String name = EnvUtils.get("dbType", null, "mysql"); DbType dbType = DbType.of(name); - WriteSheet cmd = EasyExcelFactory.writerSheet("cmd").build(); - WriteSheet sql = ExcelUtils.sheet("sql", SqlInfo.class); ExcelUtils.write("out/sql-list", excelWriter -> { + WriteSheet sql = ExcelUtils.sheet("sql", SqlInfo.class); forArgs(args, dbType, sqlInfo -> excelWriter.write(sqlInfo, sql)); + WriteSheet cmd = EasyExcelFactory.writerSheet("cmd").build(); List line = Collections.singletonList(String.join(" ", args)); List> data = Collections.singletonList(line); excelWriter.write(data, cmd); diff --git a/src/main/java/io/github/linwancen/util/CmdUtils.java b/src/main/java/io/github/linwancen/util/CmdUtils.java index ef2e2c6..635cafd 100644 --- a/src/main/java/io/github/linwancen/util/CmdUtils.java +++ b/src/main/java/io/github/linwancen/util/CmdUtils.java @@ -33,16 +33,25 @@ public static int exec(String cmd, int timeout, return exec(cmd, null, timeout, fun); } + public static int execOut(String cmd, File workingDirectory, int timeout, - Consumer fun) { + Consumer outFun) { + return exec(cmd, workingDirectory, timeout, outFun, errMsg -> { + if (!errMsg.isEmpty()) { + LOG.warn("cmd err:{}\n{}", errMsg, cmd); + } + }); + } + + public static int exec(String cmd, File workingDirectory, int timeout, + Consumer outFun, Consumer errFun) { return exec(cmd, workingDirectory, timeout, (out, err) -> { try { - String errMsg = err.toString("UTF-8"); - if (!errMsg.isEmpty()) { - LOG.warn("cmd err:{}\n{}", err, cmd); + if (errFun != null) { + errFun.accept(err.toString("UTF-8")); } - if (fun != null) { - fun.accept(out.toString("UTF-8")); + if (outFun != null) { + outFun.accept(out.toString("UTF-8")); } } catch (UnsupportedEncodingException e) { LOG.warn("toString(\"UTF-8\") fail:\n{}\n", cmd, e); diff --git a/src/main/java/io/github/linwancen/util/PathUtils.java b/src/main/java/io/github/linwancen/util/PathUtils.java index 75e2cfa..c7559fe 100644 --- a/src/main/java/io/github/linwancen/util/PathUtils.java +++ b/src/main/java/io/github/linwancen/util/PathUtils.java @@ -8,9 +8,6 @@ import java.nio.file.Files; public class PathUtils { - - @SuppressWarnings("ConstantConditions") - public static final String CLASS_PATH = PathUtils.class.getResource("/").getPath(); private static final Logger LOG = LoggerFactory.getLogger(PathUtils.class); private PathUtils() {} diff --git a/src/main/java/io/github/linwancen/util/git/GitUtils.java b/src/main/java/io/github/linwancen/util/git/GitUtils.java index 4080c60..509090b 100644 --- a/src/main/java/io/github/linwancen/util/git/GitUtils.java +++ b/src/main/java/io/github/linwancen/util/git/GitUtils.java @@ -50,7 +50,11 @@ public static void blame(File gitRoot, File file, int start, int endLine, String gitPath = gitRoot.getAbsolutePath(); String subPath = path.substring(gitPath.length() + 1).replace('\\', '/'); String cmd = "git blame -w -L" + start + "," + endLine + " " + subPath; - CmdUtils.execOut(cmd, gitRoot, 60 * 1000, func); + CmdUtils.exec(cmd, gitRoot, 60 * 1000, func, errMsg -> { + if (!errMsg.isEmpty() && !errMsg.contains("no such ref")) { + LOG.warn("cmd err:{}\n{}", errMsg, cmd); + } + }); } public static List diff(String startToEnd, String gitPath, File gitRoot) { diff --git a/src/main/kotlin/com/github/linwancen/plugin/sql/action/SqlList.kt b/src/main/kotlin/com/github/linwancen/plugin/sql/action/SqlList.kt new file mode 100644 index 0000000..33e4d3a --- /dev/null +++ b/src/main/kotlin/com/github/linwancen/plugin/sql/action/SqlList.kt @@ -0,0 +1,71 @@ +package com.github.linwancen.plugin.sql.action + +import com.alibaba.druid.DbType +import com.alibaba.excel.EasyExcelFactory +import com.alibaba.excel.ExcelWriter +import com.github.linwancen.plugin.compare.ui.I18n +import com.intellij.openapi.actionSystem.AnAction +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.actionSystem.CommonDataKeys +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.progress.ProgressIndicator +import com.intellij.openapi.progress.Task +import com.intellij.openapi.vfs.VfsUtil +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.newvfs.RefreshQueue +import io.github.linwancen.sql.DiffSql +import io.github.linwancen.sql.bean.SqlInfo +import io.github.linwancen.sql.parser.AllParser +import io.github.linwancen.util.excel.ExcelUtils +import io.github.linwancen.util.git.GitUtils +import io.github.linwancen.util.java.EnvUtils +import java.io.File + + +object SqlList : AnAction() { + + override fun update(e: AnActionEvent) { + super.update(e) + val files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY) ?: return + if (files.size == 2) { + e.presentation.text = I18n.message("sql.diff") + } else { + e.presentation.text = I18n.message("sql.list") + } + } + + override fun actionPerformed(e: AnActionEvent) { + val project = e.getData(CommonDataKeys.PROJECT) ?: return + val files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY) ?: return + ApplicationManager.getApplication().runWriteAction { + object : Task.Backgroundable(project, "Delete same") { + override fun run(indicator: ProgressIndicator) { + GitUtils.utf8() + val name = EnvUtils.get("dbType", null, "mysql") + val dbType = DbType.of(name) + if (files.isEmpty()) { + return + } + val parent = files[0].parent ?: return + val dir = parent.canonicalPath ?: return + ExcelUtils.write("$dir/sql-list") { excelWriter: ExcelWriter -> + val sql = ExcelUtils.sheet("sql", SqlInfo::class.java) + val fileList = files.map { File(it.path) }.toList() + if (files.size == 2) { + DiffSql.diffDir(dbType, fileList[0], fileList[1]) + { sqlInfo: List? -> excelWriter.write(sqlInfo, sql) } + } else { + val sqlInfos = AllParser.parse(fileList, dbType, null) + excelWriter.write(sqlInfos, sql) + } + + val data = files.map { listOf(it.path) }.toList() + val cmd = EasyExcelFactory.writerSheet("cmd").build() + excelWriter.write(data, cmd) + } + RefreshQueue.getInstance().refresh(true, false, null, parent) + } + }.queue() + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/github/linwancen/plugin/sql/ui/I18n.kt b/src/main/kotlin/com/github/linwancen/plugin/sql/ui/I18n.kt new file mode 100644 index 0000000..a88476c --- /dev/null +++ b/src/main/kotlin/com/github/linwancen/plugin/sql/ui/I18n.kt @@ -0,0 +1,21 @@ +package com.github.linwancen.plugin.compare.ui + +import com.intellij.DynamicBundle +import org.jetbrains.annotations.NonNls +import org.jetbrains.annotations.PropertyKey + +@NonNls +private const val BUNDLE = "messages.I18n" + +object I18n : DynamicBundle(BUNDLE) { + + @Suppress("SpreadOperator") + @JvmStatic + fun message(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any) = + getMessage(key, *params) + + @Suppress("SpreadOperator", "unused") + @JvmStatic + fun messagePointer(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any) = + getLazyMessage(key, *params) +} \ No newline at end of file diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml new file mode 100644 index 0000000..43cc074 --- /dev/null +++ b/src/main/resources/META-INF/plugin.xml @@ -0,0 +1,20 @@ + + + com.github.linwancen.plugin.sql + SQL List + 林万程 + + com.intellij.modules.platform + + messages.I18n + + + + + + + diff --git a/src/main/resources/META-INF/pluginIcon.svg b/src/main/resources/META-INF/pluginIcon.svg new file mode 100644 index 0000000..432b994 --- /dev/null +++ b/src/main/resources/META-INF/pluginIcon.svg @@ -0,0 +1,11 @@ + + + SQL + + + \ No newline at end of file diff --git a/src/main/resources/messages/I18n.properties b/src/main/resources/messages/I18n.properties new file mode 100644 index 0000000..19df318 --- /dev/null +++ b/src/main/resources/messages/I18n.properties @@ -0,0 +1,2 @@ +sql.list=Export Mapper.xml SQL +sql.diff=Export Mapper.xml diff SQL diff --git a/src/main/resources/messages/I18n_zh.properties b/src/main/resources/messages/I18n_zh.properties new file mode 100644 index 0000000..82952bb --- /dev/null +++ b/src/main/resources/messages/I18n_zh.properties @@ -0,0 +1,2 @@ +sql.list=\u5BFC\u51FA Mapper.xml \u7684 SQL +sql.diff=\u5BFC\u51FA Mapper.xml \u5DEE\u5F02\u7684 SQL