Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to add a new rule #986

Open
Rapter1990 opened this issue Sep 18, 2023 · 69 comments
Open

How to add a new rule #986

Rapter1990 opened this issue Sep 18, 2023 · 69 comments

Comments

@Rapter1990
Copy link

I tried to use your plugin in my Intellij IDEA 2023.2.1 Ultimate Edition and it feels very comfortable to analyze the code and suggest some major and minor ideas which help you revise the code.

What I just want to ask is to learn how to add a new rule in the plugin.

Which documentation do I follow that?
Can you guide me?

I hope you can help me.

I'm waiting for response as early as possible.

@godfather1103
Copy link

  1. Add a class, extends AbstractAliRule
  2. add rule to idea-plugin/p3c-common/src/main/resources/rulesets/java/ali-pmd.xml
  3. repackage plugin

@Rapter1990
Copy link
Author

@godfather1103 Do you have any documentation or tutorial to add a rule?

If you have, can you share it with me?

@Rapter1990
Copy link
Author

@godfather1103 Thank you for your sharing the resource with me.

@Rapter1990
Copy link
Author

@godfather1103 I want to add a sample rule but I have no idea to add it. I looked through the documentation but I couldn't find detail information about it. Do you have any video record or sample tutorial for it like build the rule from scratch. I hope you can help me. I'm waiting for your response as soon as possible.

@godfather1103
Copy link

I don't have any experience writing rules independently, I just modified bugs in existing rules

@godfather1103
Copy link

P3C pmd is based on pmd, so you may need to search for a tutorial on writing pmd rules

@Rapter1990
Copy link
Author

@godfather1103 What I just want to ask is to learn if I can add a rule (after I've learnt) to the plugin. Is it possible to do that. Let me know.

@godfather1103
Copy link

  1. git clone https://github.com/godfather1103/p3c.git
  2. import idea-plugin project,this is a gradle project
  3. create class extends AbstractAliRule in idea-plugin/p3c-common module,write rule
  4. add rule to idea-plugin/p3c-common/src/main/resources/rulesets/java/ali-pmd.xml
  5. repackage plugin

@godfather1103
Copy link

this is way to add custom rule for plugin

@Rapter1990
Copy link
Author

@godfather1103

2 ) Do I define the rule this location Link . Is it right?

3 ) Create class class extends AbstractAliRule in Link

4 ) How can I ad the rule as there are some xml files Link

5 ) Do I run this command mvn clean package spring-boot:repackage.

Who can I connect with someone whose experience is enough to define a new ?

I hope you can help me.

@godfather1103
Copy link

2-4 is right
5 is gradle clean :p3c-idea:buildPlugin or ./gradlew clean :p3c-idea:buildPlugin

@Rapter1990
Copy link
Author

@godfather1103 What about 3 and my last question?

@Rapter1990
Copy link
Author

@godfather1103 I hope you can provide a video tutorial for adding a new rule to this plugin like building from scratch.

@godfather1103
Copy link

I don't have any relevant tutorials, I hope others can provide them in the future.

@godfather1103
Copy link

Are you a beginner? Do you have any experience in Java development?

@godfather1103
Copy link

My English is not good and I need to rely on translation software, so I don't quite understand your needs.
Do you want to know how to write PMD rules?
Do you want to know how to add pmd rules to this IDEA plugin?

@Rapter1990
Copy link
Author

@godfather1103 I already had an experience in Java Development. You can look through my github profile. As I couldn't find any relevant tutorials like building to add a rule from scratch, I asked you about it. I hope other contributors can help me provide them. Is it possible to connect with them about it.
Except for that, yeah, you're right. I want to know how to write PMD rules and add pmd rules to this IDEA plugin.

@godfather1103
Copy link

If I have time on the weekend, I can try writing a document titled 'How to Add a Simple Custom Rule', hoping it will be helpful to you.

@Rapter1990
Copy link
Author

@godfather1103 I hope you can do it. Is it possible to record a video like build from scratch? That's why I can easily get how to add a custom rule like detecting deprecated methods, greater or equal to or vice versa. I'm waiting for your feedback as soon as possible.

@Rapter1990
Copy link
Author

@godfather1103 Hi, you forgot to share a video like "building a custom rule in the plugin and then using it from scratch". I hope you can prepare it as soon as possible.

@godfather1103
Copy link

@Rapter1990 Sorry, due to the approaching holiday, I am working overtime to process work and currently do not have time to record videos.

@godfather1103
Copy link

@Rapter1990 I recorded a video explaining how to add custom rules. After the video website review, I will attach the corresponding link.

@godfather1103
Copy link

The language in the video is Chinese, and you can check the demo branch for the specific code

@godfather1103
Copy link

this is video https://www.bilibili.com/video/BV1uN411E7TE/

@godfather1103
Copy link

example code
godfather1103/p3c@f7efc02

@godfather1103
Copy link

@Rapter1990
Copy link
Author

@godfather1103 Thank you for your sharing video and documentation but the video cannot be enough clear to see even if I revised its settings. Can you reupload it with high resolution if you don't mind?

@godfather1103
Copy link

@godfather1103 Thank you for your sharing video and documentation but the video cannot be enough clear to see even if I revised its settings. Can you reupload it with high resolution if you don't mind?

I'm on vacation recently. I'll give it a try tomorrow evening

@Rapter1990
Copy link
Author

@godfather1103 I also want to add a sample custom rule like methods written in camelCase and add it into plugin. Next, I can use it. Can you add me as a contributor in this repo? Can you help me how to define it? Can you direct me?

@godfather1103
Copy link

@Rapter1990 https://github.com/alibaba/p3c?
Sorry,I am not the owner of this repo.
I don't have the relevant permissions.

@Rapter1990
Copy link
Author

Rapter1990 commented Oct 5, 2023

@godfather1103 Hi. I tried to download the repo as a zip file and added a sample custom rule. I have a problem when I run gradle clean :p3c-idea:buildPlugin under idea-plugin.

p3c-master\idea-plugin> gradle clean :p3c-idea:buildPlugin

Here is the error.

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring root project 'idea-plugin'.
> Could not resolve all dependencies for configuration ':classpath'.
   > Using insecure protocols with repositories, without explicit opt-in, is unsupported.

> For more information, please refer to https://docs.gradle.org/8.3/dsl/org.gradle.api.artifacts.repositories.UrlArtifactRepository.html#org.gradle.api.artifacts.repositories.U
rlArtifactRepository:allowInsecureProtocol in the Gradle documentation.
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

BUILD FAILED in 1s

@Rapter1990
Copy link
Author

@godfather1103 I defined allowInsecureProtocol = true to build.gradle of idea plugin shown below

buildscript {
    repositories {
        maven {
            url "https://oss.sonatype.org/content/repositories/snapshots/"
        }
        maven {
            url 'http://dl.bintray.com/jetbrains/intellij-plugin-service'
            allowInsecureProtocol = true
        }
        mavenCentral()

    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

Then I run this command gradle clean :p3c-idea:buildPlugin --warning-mode all , I got this issue shown below

PS C:\Users\User\IdeaProjects\p3c-master\idea-plugin> gradle clean :p3c-idea:buildPlugin --warning-mode all
Starting a Gradle Daemon, 1 incompatible and 1 stopped Daemons could not be reused, use --status for details

> Configure project :
The org.gradle.util.WrapUtil type has been deprecated. This is scheduled to be removed in Gradle 9.0. Consult the upgrading guide for further information: https://docs.gradle.o
rg/8.3/userguide/upgrading_version_7.html#org_gradle_util_reports_deprecations
        at build_acg3fz6m14q00jaf2rs52fa9w$_run_closure1.doCall(C:\Users\User\IdeaProjects\p3c-master\idea-plugin\build.gradle:21)
        (Run with --stacktrace to get the full stack trace of this deprecation warning.)
The Project.getConvention() method has been deprecated. This is scheduled to be removed in Gradle 9.0. Consult the upgrading guide for further information: https://docs.gradle.
org/8.3/userguide/upgrading_version_8.html#deprecated_access_to_conventions
        at build_acg3fz6m14q00jaf2rs52fa9w$_run_closure1.doCall(C:\Users\User\IdeaProjects\p3c-master\idea-plugin\build.gradle:21)
        (Run with --stacktrace to get the full stack trace of this deprecation warning.)
The org.gradle.api.plugins.Convention type has been deprecated. This is scheduled to be removed in Gradle 9.0. Consult the upgrading guide for further information: https://docs
.gradle.org/8.3/userguide/upgrading_version_8.html#deprecated_access_to_conventions
        at build_acg3fz6m14q00jaf2rs52fa9w$_run_closure1.doCall(C:\Users\User\IdeaProjects\p3c-master\idea-plugin\build.gradle:21)
        (Run with --stacktrace to get the full stack trace of this deprecation warning.)
The org.gradle.api.plugins.JavaPluginConvention type has been deprecated. This is scheduled to be removed in Gradle 9.0. Consult the upgrading guide for further information: ht
tps://docs.gradle.org/8.3/userguide/upgrading_version_8.html#java_convention_deprecation
        at build_acg3fz6m14q00jaf2rs52fa9w$_run_closure1.doCall(C:\Users\User\IdeaProjects\p3c-master\idea-plugin\build.gradle:21)
        (Run with --stacktrace to get the full stack trace of this deprecation warning.)

FAILURE: Build completed with 2 failures.

1: Task failed with an exception.
-----------
* Where:
Build file 'C:\Users\User\IdeaProjects\p3c-master\idea-plugin\build.gradle' line: 21

* What went wrong:
A problem occurred evaluating root project 'idea-plugin'.
> 'void org.gradle.api.artifacts.dsl.DependencyHandler.registerTransform(org.gradle.api.Action)'

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
==============================================================================

2: Task failed with an exception.
-----------
* What went wrong:
A problem occurred configuring root project 'idea-plugin'.
> Could not create task ':compileKotlin'.
   > Cannot use @TaskAction annotation on method AbstractKotlinCompile.execute() because interface org.gradle.api.tasks.incremental.IncrementalTaskInputs is not a valid paramet
er to an action method.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
==============================================================================

BUILD FAILED in 11s

How can I fix it? I use gradle 8.3

@godfather1103
Copy link

godfather1103 commented Oct 6, 2023 via email

@Rapter1990
Copy link
Author

Rapter1990 commented Oct 6, 2023

@godfather1103 I downloaded your repository and tested it. I got the same issue which I mentioned before. How can I fix it? As I mentioned before, I use gradle 8.3

@Rapter1990
Copy link
Author

Rapter1990 commented Oct 6, 2023

@godfather1103 I fixed it but there is another question to you. I saw idea_version=2018.3 in gradle.properties of idea-plugin. How can I use this plugin in 2023.2.2?

Here is the error shown below

* What went wrong:
A problem occurred configuring project ':p3c-idea'.
> Cannot find builtin plugin git4idea for IDE: C:\Users\User\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2023.2.2\9501eca11251de344f61d01388781a8
fabcd81df\ideaIC-2023.2.2

@godfather1103
Copy link

  1. my project base on gradle 7.5.1
    Try gradle7.5.1, or use godfather1103/p3c idea-plugin/gradlew

  2. my project idea_version=2023.2, support 2023.2-2023.2.*
    idea-plugin/p3c-idea/build.gradle.kts

tasks {
    patchPluginXml {
        sinceBuild.set("${yearVersion}${noVersion}.0")
        untilBuild.set("${yearVersion}${noVersion}.*")
}

@godfather1103
Copy link

branch before-2022.3,supports versions up to and including 2022.3

@godfather1103
Copy link

idea-plugin/build.gradle.kts

val ideaVersion = property("idea_version") as String

val yearVersion = ideaVersion
    .split(".")
    .first()
    .substring(2)
    .toInt()

val noVersion = ideaVersion
    .substring(ideaVersion.indexOf(".") + 1)
    .toInt()

val myPlugins = when (yearVersion) {
    in 23..Int.MAX_VALUE -> setOf("vcs-git", "java")
    22 -> if (noVersion == 3) setOf("vcs-git", "java") else setOf("git4idea", "java")
    in 19..21 -> setOf("git4idea", "java")
    else -> setOf("git4idea")
}

ext["ideaVersion"] = ideaVersion
ext["yearVersion"] = yearVersion
ext["noVersion"] = noVersion
ext["myPlugins"] = myPlugins

@Rapter1990
Copy link
Author

Rapter1990 commented Oct 6, 2023

@godfather1103 After adding a sample rule to check the method is camelcase of not, I tried to build the repo with gradle clean :p3c-idea:buildPlugin in idea_version=2018.3 but my rule cannot be detected. How can I fix it?

Here are the code snippets shown below

p3c-pmd/src/main/resources/messages.xml

<!-- CAMEL CASE RULE  -->
    <entry key="demo.CamelCaseMethodNameRule.violation.msg">
        <![CDATA[方法名称应采用驼峰命名法。]]>
    </entry>

p3c-pmd/src/main/resources/messages-en.xml

<!-- CAMEL CASE RULE -->
    <entry key="demo.CamelCaseMethodNameRule.violation.msg">
        <![CDATA[Method names should be in camelCase.]]>
    </entry>

p3c-pmd/src/test/java/demo/CamelCaseMethodNameRuleTest

public class CamelCaseMethodNameRuleTest extends SimpleAggregatorTst {
    @Override
    protected void setUp() {
        addRule("rulesets/java/demo.xml", "CamelCaseMethodNameRule");
    }
}

p3c-pmd/src/test/resources/rulesets/java/demo.xml

<?xml version="1.0"?>

<ruleset name="AlibabaJavaOthers" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>Demo</description>
    <rule name="CamelCaseMethodNameRule"
          language="java"
          message="demo.CamelCaseMethodNameRule.violation.msg"
          class="demo.CamelCaseMethodNameRule">
        <priority>5</priority>
    </rule>
</ruleset>

p3c-pmd/src/test/resources/demo/xml/CamelCaseMethodNameRule.xml

<?xml version="1.0" encoding="UTF-8"?>
<test-data xmlns="http://pmd.sourceforge.net/rule-tests"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.sourceforge.io/rule-tests_1_0_0.xsd">
    <code-fragment id="camelCaseMethodName">
        <![CDATA[
        public class Example {

            public int NonCamelCaseMethod() {
                return 0;
            }

            public int camelCaseMethod() {
                return 1;
            }
        }
        ]]>
    </code-fragment>
    <test-code>
        <description>Method names are in camelCase</description>
        <expected-problems>1</expected-problems>
        <code-ref id="camelCaseMethodName"/>
    </test-code>

    <code-fragment id="notCamelCaseMethodName">
        <![CDATA[
        public class Example {

            public int nONCamelCASEMethod() {
                return 0;
            }

            public int camelCaseMethod() {
                return 1;
            }

        }
        ]]>
    </code-fragment>
    <test-code>
        <description>Method names not are in camelCase</description>
        <expected-problems>0</expected-problems>
        <code-ref id="notCamelCaseMethodName"/>
    </test-code>

</test-data>

idea-plugin/p3c-common/src/main/resources/rulesets/java/ali-pmd.xml

<!-- ADD CUSTOM RULE FOR CAMEL CASE METHOD NAME RULE -->
    <rule name="CamelCaseMethodNameRule"
          language="java"
          since="1.6"
          message="demo.CamelCaseMethodNameRule.violation.msg" class="demo.CamelCaseMethodNameRule">
        <priority>5</priority>
    </rule>

p3c-pmd/src/main/java/demo/CamelCaseMethodNameRule.java

public class CamelCaseMethodNameRule extends AbstractJavaRule {

    @Override
    public Object visit(ASTMethodDeclaration node, Object data) {
        String methodName = node.getName();

        // Check if the method name is not in camel case
        if (!isCamelCase(methodName)) {
            addViolationWithMessage(data, node, "demo.CamelCaseMethodNameRule.violation.msg");
        }

        return super.visit(node, data);
    }

    // Method to check if a string is in camel case
    private boolean isCamelCase(String s) {

        System.out.println(s);

        // [a-z]+ -> Matches one or more lowercase letters
        // [A-Z]+ -> Matches one or more uppercase letters
        // \\w+ -> Matches one or more word characters (letters, digits, or underscores)
        // + -> This part of the expression matches one or more occurrences of the previous group, which allows for multiple words in camel case format
        return s.matches("([a-z]+[A-Z]+\\w+)+");
    }
}

@godfather1103
Copy link

Can you debug to see if relevant content has been injected

@Rapter1990
Copy link
Author

@godfather1103 I can run CamelCaseMethodNameRuleTest without any error. After I get zip file from repo as plugin, I test it in Intellij Idea 2018 but it couldn't detect the rule and rule can appeared when I click "Analyze code through Ali Baba Java Guideness Plugin".
How can I fix it?

@Rapter1990
Copy link
Author

Rapter1990 commented Oct 9, 2023

@godfather1103 I downloaded your repo but I got this issue when I run this command gradle clean :p3c-idea:buildPlugin --warning-mode all

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring root project 'idea-plugin'.
> Could not resolve all files for configuration ':classpath'.
   > Could not resolve org.jetbrains.intellij.plugins:gradle-intellij-plugin:1.13.3.
     Required by:
         project :
      > No matching variant of org.jetbrains.intellij.plugins:gradle-intellij-plugin:1.13.3 was found. The consumer was configured to find a runtime of a library compatible with Ja
va 8, packaged as a jar, and its dependencies declared externally, as well as attribute 'org.gradle.plugin.api-version' with value '7.5.1' but:
          - Variant 'apiElements' capability org.jetbrains.intellij.plugins:gradle-intellij-plugin:1.13.3 declares a library, packaged as a jar, and its dependencies declared exter
nally:
              - Incompatible because this component declares an API of a component compatible with Java 11 and the consumer needed a runtime of a component compatible with Java 8  
              - Other compatible attribute:
                  - Doesn't say anything about org.gradle.plugin.api-version (required '7.5.1')
          - Variant 'javadocElements' capability org.jetbrains.intellij.plugins:gradle-intellij-plugin:1.13.3 declares a runtime of a component, and its dependencies declared exter
nally:
          - Variant 'runtimeElements' capability org.jetbrains.intellij.plugins:gradle-intellij-plugin:1.13.3 declares a runtime of a library, packaged as a jar, and its dependenci
es declared externally:
              - Incompatible because this component declares a component compatible with Java 11 and the consumer needed a component compatible with Java 8
              - Other compatible attribute:
                  - Doesn't say anything about org.gradle.plugin.api-version (required '7.5.1')
          - Variant 'sourcesElements' capability org.jetbrains.intellij.plugins:gradle-intellij-plugin:1.13.3 declares a runtime of a component, and its dependencies declared exter
nally:
              - Incompatible because this component declares documentation and the consumer needed a library
              - Other compatible attributes:
                  - Doesn't say anything about its target Java version (required compatibility with Java 8)
                  - Doesn't say anything about its elements (required them packaged as a jar)
                  - Doesn't say anything about org.gradle.plugin.api-version (required '7.5.1')
          - Variant 'testFixturesApiElements' capability org.jetbrains.intellij.plugins:gradle-intellij-plugin-test-fixtures:1.13.3 declares a library, packaged as a jar, and its d
ependencies declared externally:
              - Incompatible because this component declares an API of a component compatible with Java 11 and the consumer needed a runtime of a component compatible with Java 8  
              - Other compatible attribute:
                  - Doesn't say anything about org.gradle.plugin.api-version (required '7.5.1')
          - Variant 'testFixturesRuntimeElements' capability org.jetbrains.intellij.plugins:gradle-intellij-plugin-test-fixtures:1.13.3 declares a runtime of a library, packaged as
 a jar, and its dependencies declared externally:
              - Incompatible because this component declares a component compatible with Java 11 and the consumer needed a component compatible with Java 8
              - Other compatible attribute:
                  - Doesn't say anything about org.gradle.plugin.api-version (required '7.5.1')

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

How can I fix it?

@godfather1103
Copy link

use jdk 17

@Rapter1990
Copy link
Author

Rapter1990 commented Oct 9, 2023

@godfather1103 I define jdk 17 for project structure, idea-plugin and p3c-pmd under gradle but nothing changed. I still got the same issue. How can I fix it as I'm stuck there. As you can see, Could not resolve org.jetbrains.intellij.plugins:gradle-intellij-plugin:1.13.3.

@godfather1103
Copy link

@Rapter1990 What about the code for this class "demo.CamelCaseMethodNameRule"

@Rapter1990
Copy link
Author

Rapter1990 commented Oct 9, 2023

@godfather1103 I forgot to add it. You can see the post above to show all information about custom rule. I have also another problem which I mentioned before. I hope you can help me.

@godfather1103
Copy link

@godfather1103
Copy link

Could not resolve org.jetbrains.intellij.plugins:gradle-intellij-plugin:1.13.3.
@Rapter1990

  1. check jdk Version
    Have you change jdk between these two places?
    Settings -> Build -> Gradle -> Gradle Jvm
    Project Structure -> Project -> SDK

2.Modify buildscript.repositories Order

1

@Rapter1990
Copy link
Author

Rapter1990 commented Oct 10, 2023

@godfather1103 Here is what I've done after your response.

1. Settings -> Build -> Gradle -> Gradle Jvm -> Oracle Open JDK version 11.0.20
Project Structure -> Project -> SDK -> Oracle Open JDK version 11.0.20

In the file named gradle-wrapper.properties , here is the gradle version shown below

`distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip`

2. Move gradlePluginPortal() to mavenLocal() above.

It works now. Thank you for your guideness. I can reach out you again if I have any problem.

@Rapter1990
Copy link
Author

@godfather1103 How can I find rule example like xpath example such as FinallyStatement, ReturnStatement, ContinueStatement? Can you share its link if you have? Let me know.

@godfather1103
Copy link

godfather1103 commented Oct 16, 2023 via email

@Rapter1990
Copy link
Author

@godfather1103 I found this link ( https://josephallen.github.io/PMD-New-Site/writing_pmd_rules.html ) I try to find their usage like FinallyStatement//ContinueStatement .

Do you have any idea about it?

@godfather1103
Copy link

godfather1103 commented Oct 16, 2023 via email

@Rapter1990
Copy link
Author

@godfather1103 Which contributor has any idea about it?

@Rapter1990
Copy link
Author

@godfather1103 I try to find more examples of writing custom rule. Where do I find more them?

@Rapter1990
Copy link
Author

@godfather1103 Hi, I want to ask some questions to you?

  1. How can I run the app locally?
    I try this approach
    - idea-plugin:p3c-idea
    - Edit Configuration
    - runIde in Run section
    - idea-plugin:p3c-idea
    - Edit Configuration
    - clean buildPlugin in Run section

    Is it right?

  2. I added the rule but it cannot detect.

Can you help me?

@godfather1103
Copy link

Run in debug mode to confirm if the rules have been injected

@godfather1103
Copy link

Follow the steps in the video I sent and check in sequence

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants