Skip to content

Latest commit

 

History

History
243 lines (167 loc) · 9.83 KB

CONTRIBUTING.md

File metadata and controls

243 lines (167 loc) · 9.83 KB

Table of Contents

Contributions to the project are very welcome! Please submit pull requests with any changes (preferably with tests).

Documentation

The documentation for the project can be found here. In order to edit the website checkout the gh-pages branch. It is possible to use Jekyll (https://help.github.com/articles/using-jekyll-with-pages) to preview the changes. Jekyll can be run with jekyll serve --watch -V. This README's table of contents are generated by tocdown using the following command line:

ruby .../tocdown/toc.rb -b -r -t -d 3 -s -m <markdown-file>

IDE Config and Code Style

This project has a strictly enforced code style. Code formatting is done by the Eclipse code formatter, using the config files found in the ide-config directory. By default, when you run ./gradlew build the code will be formatted automatically.

Eclipse Setup

Open the Preferences window, and then navigate to Java -> Code Style -> Formatter. Click Import and then select the eclipse-format.xml file in the ide-config directory.

Next navigate to Java -> Code Style -> Organize Imports. Click Import and select the eclipse.importorder file.

IDEA Setup

Open the Preferences window, navigate to Plugins and install the Eclipse Code Formatter Plugin.

Restart you IDE, open the Preferences window again and navigate to Other Settings -> Eclipse Code Formatter.

Select Use the Eclipse Code Formatter, then change the Eclipse Java Formatter Config File to point to the eclipse-format.xml file in the ide-config directory. Make sure the Optimize Imports box is ticked, and select the eclipse.importorder file as the import order config file.

Code Recommendations

Logging

The tooling overrides the logging to support integration into ProjectNCL. Therefore, to retrieve a standard Gradle logger instance, do:

     org.gradle.api.logging.Logger logger = org.jboss.gm.common.logging.GMLogger.getLogger(getClass());

The Gradle logger interface extends org.slf4j.Logger. It is recommended to use info and debug categories as appropriate.

During tests, it may be useful to retrieve logging output. The following rule will capture output for examination: @Rule public final SystemOutRule systemOutRule = new SystemOutRule().enableLog().muteForSuccessfulTests(); Due to how the Gradle logging system initialises outside of the TestKit, the unit tests may not output logging as the Gradle logging defaults to LIFECYCLE level by default. Therefore, a new Logging rule has been provided which can configure the logging level on a per test basis.

    @Rule
    public final LoggingRule loggingRule = new LoggingRule(LogLevel.INFO);

Exceptions

  • Internal code may use checked exceptions such as ManipulationException.
  • All external invocation points cannot throw a checked exception, so they must use an unchecked exception (e.g., ManipulationUncheckedException).
  • The org.gradle.api.InvalidUserDataException can be used for configuration errors.
  • Avoid throwing RuntimeException ; rather, use a more explicit exception.

Gradle Test Runner

The test runner may be used for functional testing. Note that it is recommended that withDebug(true) is not used in the manipulator sub-module by default but just enabled as required. This is because debug runs in-process which can lead to some strange side effects.

To pass specific property / environment variables through the following pattern should be followed (which will also work when using single-test debugging):

    @Rule
    public final TestRule restoreSystemProperties = new RestoreSystemProperties();

......
        System.setProperty("AProxDeployUrl", "file://" + publishDirectory.toString());

        final BuildResult buildResult = TestUtils.createGradleRunner ()
                .withProjectDir(simpleProjectRoot)
                .withArguments("--info", "publish")
                .build();
     ....

Note that instead of calling GradleRunner.create the TestUtils class is used instead which passes on the extra system properties.

Building

To build GME and run all tests, use

gradle clean build

If you also wish to publish the artifacts to you local maven repository, replace build with publishToMavenLocal

gradle clean publishToMavenLocal

Running Tests

Normally, Gradle will only run tests if the code has changed. However, you may wish to force all tests to run using

gradle cleanTest test

Similarly, you can force all functional tests to run using

gradle cleanFunctionalTest functionalTest

Skipping Tests

If you wish to build excluding all tests and functional tests, use

gradle clean publishToMavenLocal -x test -x functionalTest

You may run only certain tests (e.g., the tests in a class named TestClass) using

gradle test --tests TestClass

Releasing

The project has been configured to release both plugins to the Gradle Portal and to release to Maven Central.

- Before running the release notify the team to lock down the repository until the release is finished. -

It uses the gradle-release plugin to simulate a similar process to the Maven release plugin - it can increment the version, add tags, push the changes, etc. It supplies a hook task (afterReleaseBuild) that can be used to ensure that tasks after the release version has been changed - we have configured it as follows:

tasks.afterReleaseBuild {
    dependsOn(":analyzer:publish", ":manipulation:publish",
              ":analyzer:publishPlugins", ":manipulation:publishPlugins") }

The publish pushes to Sonatype staging while the publishPlugins pushes to the Gradle Plugin Portal. The build script will also modify README.md to ensure it points to the correct version.

Prerequisites

  • Run the release using Gradle 5.6.4 (currently later 6.x produce much larger jars)
  • Sign up for a Gradle account (see details here)
  • Make sure you can push changes to Maven Central
  • Create or update the required $HOME/.gradle/gradle.properties locally with data from the API key (which can be found in your gradle account)

It should look something like this:

gradle.publish.key=key
gradle.publish.secret=secret
  • Update $HOME/.gradle/gradle.properties to contain the necessary configuration for publishing to Maven Central. Something like:
signing.gnupg.keyName=someKey
signing.passphrase=pass

Note: By default the signing is configured to use GPG. It will automatically look for the gpg2 executable. On Fedora systems this is normally a symbolic link, e.g.,

    /usr/bin/gpg*
    /usr/bin/gpg2 -> gpg*

If this does not exist on your system then you may need to add a line like signing.gnupg.executable=gpg to the properties file.


The configuration will also read your $HOME/.m2/settings.xml for a username/password associated with sonatype-nexus-staging.

See this for more details

Release command

The plugins can be released using the following command (from the main branch of the repository):

# Optional command: ./gradlew clean

./gradlew --info release -Drelease=true

The command will both publish the plugin to the Gradle Plugin Portal and to Maven Central.

Note: It is very important to execute this exact command when releasing. Adding other tasks (e.g., clean) can cause the release to fail, or even worse leave the release in an inconsistent state. If clean is needed, run it separately before the main command. If a release needs to be rolled back the following must be checked and cleaned up:

Note: It may be necessary to add the following to your $HOME/.gradle/gradle.properties to prevent timeouts:

systemProp.org.gradle.internal.http.connectionTimeout=600000
systemProp.org.gradle.internal.http.socketTimeout=600000
systemProp.http.socketTimeout=600000
systemProp.http.connectionTimeout=600000

Publishing artifacts locally

Both plugins can be published to maven local to make it easier to consume them in projects. The command to do so is:

./gradlew publishToMavenLocal

To change the version that will be deployed just add -Pversion=whatever.

Releasing SNAPSHOT version

The artifacts can be pushed to the Sonatype snapshot repository (e.g., https://oss.sonatype.org/content/repositories/snapshots/org/jboss/gm/analyzer/analyzer/) with the following command:

gradle publishAllPublicationsToSonatype-nexus-snapshotsRepository

Note that your username/password in $HOME/.m2/settings.xml for Sonatype must be setup.