diff --git a/.gitignore b/.gitignore index 552ea58b26bbed58c58f8ed700e9ceabffe0a5f8..7be691a9fdda6f1bd2c0b8d60d66f7f481e44ddf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.jar +!gradle/wrapper/gradle-wrapper.jar .project .classpath .idea/ @@ -12,3 +13,4 @@ src/test/jastadd/*/*.ast src/test/jastadd/*/*.jadd src/test/jastadd/*/*ResolverStubs.jrag !src/test/jastadd/*/MyRefResolver.jadd +/gradle.properties diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9729a314e03c730a3f31025a68ae8233c46d0a62..dfad4ae3915b8a1254351676aaf3cf62a292f138 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,8 +1,18 @@ stages: - - build +- build +- test -test: +build: image: openjdk:8 stage: build script: - - ./gradlew --no-daemon build + - ./gradlew --console=plain assemble jar + artifacts: + paths: + - "/builds/jastadd/relational-rags/build/libs/relast-*.jar" + +test: + image: openjdk:8 + stage: test + script: + - ./gradlew --console=plain --info test diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d6c4f34a06b11c3e604376030cb7215c2841bfa..46997637b262d0b2c2696a43154fc008f4afa3b5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ To propose a new feature, or to report a bug, first [create an issue][create-issue] and add labels accordingly. Working on such issues is done by creating a merge request from the issue page, which 1) creates a new branch to work on, and 2) creates a new WIP merge request for the new branch. -Once done (and new tests are written to ensure, a bug is really fixed, and the feature does the right thing), the merge request will be accepted and merged into `master`. +Once done (and new tests are written to ensure, a bug is really fixed, and the feature does the right thing), the merge request will be accepted and merged into `develop`. # Creating normal test cases @@ -63,7 +63,7 @@ Aside from the [normal tests](#creating-normal-test-cases), there are some speci ## Negative parser tests -To check, errors are found and contain the correct messages, one test [`Errors`](/../blob/master/src/test/java/org/jastadd/relast/tests/Errors.java) is used. +To check, errors are found and contain the correct messages, one test [`Errors`][Errors.java] is used. Here, the RelAST compiler is invoked manually, and the actual error messages are compared to expected ones for each grammar in `src/test/jastadd/errors`. The expected messages can contain the special word `$FILENAME` to refer to the filename of the grammar, if there is only one, or `$FILENAME1`, `$FILENAME2` etc., if there are many. Furthermore, empty lines, lines starting with `//` and the order of the error messages are ignored. @@ -74,12 +74,35 @@ Currently, there is one test to test whether the output of RelAST is a valid inp To achieve this, there are two Gradle tasks. The first produces the usual `.ast` and `.jadd` files, whereas the second task takes the `.ast` as input. The test then ensures, that both output grammars are identical. -# Publishing - -To publish a new version, the following needs to be done: - -1) Create a new annotated tag with an appropriate version number increase (major, minor, patch) described in [semantic versioning](https://semver.org/) -2) If not already present, create a new file `gradle.properties` with two entries `repoUser` and `repoPassword` for our Nexus repository. -3) Run `./gradlew publish -PwithNewVersion` (maybe also adding ` -PasSnapshot` to create a SNAPSHOT release) - +# Releases and Publishing (Maintainer only) + +Important information: + +- Currently, we are publishing to a private Nexus Maven repository only. +- We are using [git-flow][git-flow], so only new merge requests are considered for releases to appear in the `master` branch. +- The version is set in the configuration file [RelASTVersion.properties][RelASTVersion.properties]. + +The workflow: + +1) Finish your work with the current feature(s) and merge those back in `develop`. +1) Choose a new version number `$nextVersion` depending on the introduced changes **following [semantic versioning][semantic-versioning]**. +1) Create a new release branch named `release/$nextVersion` and switch to this branch. +1) Set the version number in the config file calling `./gradlew newVersion -Pvalue=$nextVersion` +1) Commit this change. +1) (Optional) Build a new jar file calling `./gradlew jar` (this is automatically called in the publish step and only used to test the newly set version number) +1) Check, if everything works as planned, e.g., version number is picked up when running the application with `--version`, and all test succeed. +1) Merge the release branch into `master` (using a merge request) and also back into `develop`. +1) Delete the release branch. +1) [Create a new release][create-release]. Choose the following: + - *Tag name*: the chosen version number + - *Create from*: leave the default `master` + - *Message*: "Version " and the chose version number + - *Release notes*: list the (important) changes compared to the last release, prepend a link to the built jar using the line `[:floppy_disk: publish-relast-poc-$nextVersion.jar](/../../../-/jobs/$jobNumber/artifacts/raw/build/libs/publish-relast-poc-$nextVersion.jar?inline=false)` replacing `$jobNumber` with the `jar` job of the pipeline run after the merge request, and `$nextVersion` +1) Publish the built jar to the maven repository calling `./gradlew publish` + +[git-flow]: https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow +[Errors.java]: /../blob/master/src/test/java/org/jastadd/relast/tests/Errors.java +[RelASTVersion.properties]: /../-/blob/master/src/main/resources/RelASTVersion.properties +[semantic-versioning]: https://semver.org/ +[create-release]: /../-/tags/new [create-issue]: https://git-st.inf.tu-dresden.de/jastadd/relational-rags/issues/new diff --git a/README.md b/README.md index da4ab0d84628e3cf7f193d23e55f6e0a5350ace5..b49c377f9290f661896b992cc1d363d9334d0053 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -[](/../pipelines) - -# RelAST Preprocessor Version 0.2.4 +# RelAST Preprocessor  +See [releases page](/../../releases) for the latest version. + The RelAST preprocessor takes a `.relast` file as input comprising AST rules and relations. It produces files that afterwards are processed by JastAdd to generated Java code. To use it in your project, build the JAR file running diff --git a/build.gradle b/build.gradle index c4a81cb274c3cb4ab83004aeaa29648e6f1e466c..58840b2af00e93024da6e17fd940b68c202997ad 100644 --- a/build.gradle +++ b/build.gradle @@ -14,6 +14,9 @@ repositories { jcenter() } +group = 'org.jastadd' +apply plugin: 'maven-publish' + buildscript { repositories.jcenter() dependencies { @@ -44,6 +47,25 @@ sourceSets { } } +def versionFile = 'src/main/resources/RelASTVersion.properties' +def oldProps = new Properties() + +try { + file(versionFile).withInputStream { stream -> oldProps.load(stream) } + version = oldProps['version'] +} catch (e) { + // this happens, if either the properties file is not present, or cannot be read from + throw new GradleException("File ${versionFile} not found or unreadable. Aborting.") +} + +task newVersion() { + doFirst { + def props = new Properties() + props['version'] = value + props.store(file(versionFile).newWriter(), null) + } +} + jar { manifest { attributes "Main-Class": 'org.jastadd.relast.compiler.Compiler' @@ -52,6 +74,8 @@ jar { from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } + + archiveBaseName = 'relast' } jastadd { @@ -111,46 +135,27 @@ jastadd { jastaddOptions = ["--lineColumnNumbers", "--safeLazy", "--visitCheck=true", "--rewrite=cnta", "--cache=all"] } -def versionFile = 'src/main/resources/RelASTVersion.properties' -task updateVersion { - /* version string handling adapted from https://bitbucket.org/extendj/extendj/src/master/build.gradle - written by Jesper Öqvist <jesper.oqvist@cs.lth.se> */ - group 'build' - description 'Updates the version file for RelAST' - - doLast { - def oldProps = new Properties() - String oldFullVersion, fullVersion - - try { - file(versionFile).withInputStream { stream -> oldProps.load(stream) } - oldFullVersion = oldProps['version'] - } catch (ignored) { - oldFullVersion = "???" +publishing { + publications { + maven(MavenPublication) { + artifact("build/libs/relast-${version}.jar") { + extension 'jar' + } } - try { - def proc = 'git describe'.execute(null, rootDir) - if (proc.waitFor() == 0) { - fullVersion = proc.text.trim() - if (hasProperty('withNewVersion')) { - // Trim to get latest tag: - version = (fullVersion =~ /-\d+\-g.+$/).replaceAll('') - } - if (oldFullVersion != fullVersion) { - def props = new Properties() - props['version'] = fullVersion - props.store(file(versionFile).newWriter(), null) - } - } else { - logger.warn('No git tags found.') + } + repositories { + maven { + name 'nexus' + url "http://172.22.1.152:8081/repository/" + (project.hasProperty('asSnapshot') ? "maven-snapshots" : "maven-releases/") + credentials { + username project.ext.properties.repoUser + password project.ext.properties.repoPassword } - } catch (IOException e) { - logger.warn("Failded to run git describe (${e.getMessage()}).") } } } -processResources.dependsOn updateVersion +publish.dependsOn jar task firstRelationsRun(type: RelastTest) { relastFiles 'src/test/jastadd/relations/Relations.relast' @@ -251,6 +256,7 @@ task compileListNamesTest(type: RelastTest) { grammarName = 'src/test/jastadd/listnames/ListNames' useJastAddNames = true jastAddList = 'ListyMcListface' + listClass = 'java.util.LinkedList' packageName = 'listnames.ast' moreInputFiles 'src/test/jastadd/Utils.jadd' } diff --git a/src/main/java/org/jastadd/relast/compiler/Compiler.java b/src/main/java/org/jastadd/relast/compiler/Compiler.java index 2f6ef2572c7e6ad4fda1f7e6abaf78eb577e3669..dfa3d1a812d0e98a5652a4fe3b324fc17624297a 100644 --- a/src/main/java/org/jastadd/relast/compiler/Compiler.java +++ b/src/main/java/org/jastadd/relast/compiler/Compiler.java @@ -23,6 +23,7 @@ public class Compiler { private FlagOption optionResolverHelper; private FlagOption optionUseJastaddNames; private FlagOption optionQuiet; + private FlagOption optionVersion; private CommandLine commandLine; public Compiler(String[] args) throws CommandLineException { @@ -32,6 +33,11 @@ public class Compiler { commandLine = new CommandLine(options); commandLine.parse(args); + if (optionVersion.isSet()) { + System.out.println(readVersion()); + return; + } + printMessage("Running RelAST " + readVersion()); if (commandLine.getArguments().size() < 1) { @@ -136,7 +142,7 @@ public class Compiler { */ private String readVersion() { try { - ResourceBundle resources = ResourceBundle.getBundle("Version"); + ResourceBundle resources = ResourceBundle.getBundle("RelASTVersion"); return resources.getString("version"); } catch (MissingResourceException e) { return "version ?"; @@ -179,6 +185,7 @@ public class Compiler { optionUseJastaddNames = addOption(new FlagOption("useJastAddNames", "generate names in the form of addX, removeX and setX. If omitted, the default, original naming scheme resulting in addToX, removeFromX and setX will be used.")); optionSerializer = addOption(new EnumOption("serializer", "generate a (de-)serializer", Arrays.asList("jackson", "jackson-json-pointer", "jackson-manual-references"), "jackson")); optionQuiet = addOption(new FlagOption("quiet", "do not output anything on stdout")); + optionVersion = addOption(new FlagOption("version", "print version and exit")); } private <OptionType extends Option<?>> OptionType addOption(OptionType option) { diff --git a/src/main/resources/.gitignore b/src/main/resources/.gitignore deleted file mode 100644 index e4a21f4a3975000dd59369f1430ec3e931b4e3e3..0000000000000000000000000000000000000000 --- a/src/main/resources/.gitignore +++ /dev/null @@ -1 +0,0 @@ -RelASTVersion.properties diff --git a/src/main/resources/RelASTVersion.properties b/src/main/resources/RelASTVersion.properties new file mode 100644 index 0000000000000000000000000000000000000000..909fca73c343468a25475a043d5e03ca356550cf --- /dev/null +++ b/src/main/resources/RelASTVersion.properties @@ -0,0 +1,2 @@ +#Thu Apr 16 11:22:48 CEST 2020 +version=0.3.0 diff --git a/src/test/jastadd/relations/Relations.jrag b/src/test/jastadd/relations/Relations.jrag index f8571163de1be37f6812e90dca22fb1a73e37966..69766fef8f5b5374fce094db182a99ef871c95e5 100644 --- a/src/test/jastadd/relations/Relations.jrag +++ b/src/test/jastadd/relations/Relations.jrag @@ -1 +1,38 @@ import java.util.ArrayList; + +aspect NTA { + + // E ::= ... /<NT1>/ ... ; + syn String E.getNT1() = ""; + + // E ::= ... /<NT2:String>/ ... ; + syn String E.getNT2() = ""; + + // E ::= ... /<NT3:boolean>/ ... ; + syn boolean E.getNT3() = false; + + // E ::= ... /<NT4:int>/ ... ; + syn int E.getNT4() = 1; + + // E ::= ... /<NT5:float>/ ... ; + syn float E.getNT5() = 1.0f; + + // E ::= ... /<NT6:double>/ ... ; + syn double E.getNT6() = 1.0d; + + // E ::= ... /<NT7:long>/ ... ; + syn long E.getNT7() = 1l; + + // E ::= ... /[NT8:A]/ ... ; + syn Opt<A> E.getNT8Opt() = new Opt<A>(); + + // E ::= ... /[A]/ ... ; + syn Opt<A> E.getAOpt() = new Opt<A>(); + + // E ::= ... /NT10:A*/ ... ; + syn List<A> E.getNT10List() = new List<A>(); + + // E ::= ... /B*/ ... ; + syn List<B> E.getBList() = new List<B>(); + +} diff --git a/src/test/jastadd/relations/Relations.relast b/src/test/jastadd/relations/Relations.relast index 6df99c3d62d07071dd97599555de011de752a4a4..cccea4744ba0eb7904e04e1803cfb64c064797d2 100644 --- a/src/test/jastadd/relations/Relations.relast +++ b/src/test/jastadd/relations/Relations.relast @@ -51,9 +51,10 @@ D ::= SingleA:A ListOfA:A* [OptionalA:A] /NTAA:A/ ; // production with tokens, nonterminal-tokens, multi-line E ::= <T1> <T2:String> <T3:boolean> <T4:int> <T5:float> <T6:double> <T7:long> <T8:java.lang.Object> <T9:ArrayList<String>> <T10:java.util.ArrayList<java.lang.String>> - /<NT2:String>/ /<NT3:boolean>/ /<NT4:int>/ /<NT5:float>/ /<NT6:double>/ /<NT7:long>/ ; + /<NT1>/ /<NT2:String>/ /<NT3:boolean>/ /<NT4:int>/ /<NT5:float>/ /<NT6:double>/ /<NT7:long>/ + /[NT8:A]/ /[A]/ /NT10:A*/ /B*/; -rel E.NT1 -> A ; +rel E.R1 -> A ; // inheritance and empty F : A ;