diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000000000000000000000000000000000..07926923085123e3d7ff394a8777e16563073379 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore index 8a4c59aef9c4142c7675b653db6b710a5d6503c3..795da40d5d07c33b3026ab24cf05fb514f446701 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,9 @@ env/ # Apple .DS_Store +# VSCode +.vscode/ + # NetBeans **/nbproject/private/ **/nbproject/Makefile-*.mk diff --git a/.versionrc b/.versionrc new file mode 100644 index 0000000000000000000000000000000000000000..7428f00ed3d40104ab4e21ab38a3b5c767e2ad0b --- /dev/null +++ b/.versionrc @@ -0,0 +1,3 @@ +{ + "tagPrefix": "" +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..dcc23ec3be1745199c0f80c59cb8b377adc3f1ea --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,2 @@ +Information on how to contribute to this project, is written in the docs. +See here: [docs/unified-ticketing/contributing.md](docs/unified-ticketing/contributing.md) diff --git a/LICENSE.md b/LICENSE.md index 1110e89874643ece9fc3efe3ba58f2b946535cb4..4564b291ddcb7eda26bf6d4fad7ca9edec7764a0 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -2,7 +2,7 @@ GNU General Public License ========================== _Version 3, 29 June 2007_ -_Copyright © 2007 Free Software Foundation, Inc. <>_ +_Copyright © 2007 [Free Software Foundation, Inc.](https://fsf.org)_ Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. diff --git a/README.md b/README.md index a2df26aee3f42e0d2338d31175129ab68b0afcdd..bd0a2dfe520c13984dea60349813e83f3a837a41 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,8 @@ This is the repository of the unified-ticketing library. Documentation for this is done with GitLab Pages using MkDocs and is available here: https://transfer.hft-stuttgart.de/pages/unified-ticketing/ + +If you don't want to open the Webpage or it is not available for whatever reason, +the documentation root is in [docs/index.md][docs-root] + +[docs-root]: docs/index.md diff --git a/docs/api/core/logging.md b/docs/api/core/logging.md new file mode 100644 index 0000000000000000000000000000000000000000..c11b3c49540f87815ef1629eb66e69923b7063ad --- /dev/null +++ b/docs/api/core/logging.md @@ -0,0 +1,41 @@ +# Logging + +The library uses the built-in logger from `java.util.logging`. +It configures to not use the parent logger and places a new ConsoleHandler +on static initialization. This outputs the log in formatted lines like: +```text +[2020-11-27T14:40:26+0100] [WARNING] [de.hftstuttgart.unifiedticketing.core.Logging.test] calling from app +``` + +This will _not_ change visual presentation based on any localization. + +## change log-level + +Default is to use _INFO_-level. +You can change the used level: +```java +Logging.setLevel(Level); +``` + +The parameter passed is of type `java.util.logging.Level`. + +## test logging output + +To test if the logging as such works, +you can pass a test string: +```java +Logging.test("test message"); +``` + +This message will be logged by the `Logging`-class own Logger, +once per level. + +## set custom formatter + +If you need another format, +you can replace the default formatter of this lib by calling: +```java +Logging.setFormatter(Formatter); +``` + +This formatter has to be of type `java.util.logging.Formatter` diff --git a/docs/api/core/ticket-system.md b/docs/api/core/ticket-system.md new file mode 100644 index 0000000000000000000000000000000000000000..17d4790e1925fda15c8957e9e3ce60adc151ce58 --- /dev/null +++ b/docs/api/core/ticket-system.md @@ -0,0 +1,159 @@ +# Ticketsystem + +A `TicketSystem` object represents a connection definition to a space in an external ticket system. +Part of this is a base URL, and some system specific identifier for e.g. a project on that system. +If the access needs some kind of authentication, +this has to be configured in this object on creation. + +## create new instance + +The constructor of `TicketSystem` is not publicly callable. +Acquiring an instance has to be done either by passing an URI or using the builder mechanism. + +### by URI + +This library has a global definition, for how an URI has to start. +The end of it is defined by each system specific implementation. + +!!! info "global URI definition" + `unifiedticketing::` + _For system specific details look into the systems part of this docs_ + +To instantiate a `TicketSystem` from an URI, call the static method `fromUri(String)`: + +```java +TicketSystem ts = TicketSystem.fromUri(); +``` + +!!! warning + If the given String does not match the criteria for a valid URI, + or the system identifier is unknown, it throws an `AssertionException` + +### by builder + +The library has a builder mechanism defined to instantiate a new `TicketSystem` object, using fluent-api. +To start it, call the static method `fromBuilder()`. +The returning object gives you all supported systems as choice, +which then brings you to the system specific builder mechanism. + +At the end, you'll have to finish the building process with a call to `build()`. + +!!! warning + If not all mandatory information where given before calling `build()`, + it will throw an `AssertionException` + +## configuration options + +You can set configurations of two kinds: + +- simple boolean switches to enable/disable a behaviour/feature +- string values + +To set a configuration, call the instance method `config`. It provides two signatures: + +- `config(TicketSystem.ConfigurationOption, boolean)` +- `config(TicketSystem.ConfigurationOption, String)` + +??? abstract "currently available configuration options" + | ConfigurationOption | type | default | description | + | :------------------- | :------ | :------ | :------------------------------------------------------------------------------------------------ | + | RETURN_NULL_ON_ERROR | boolean | `false` | If true, don't throw exception on error, but return null or the calling object, if in fluent-api. | + +!!! warning + option `RETURN_NULL_ON_ERROR` is not fully implemented and tested yet. + Expect it still throws Exceptions sometimes, but returns null/self also sometimes. +## list tickets + +Tickets are requested by using the filter mechanism. +To get _all_ Tickets just don't define any filters before calling `get()`. +They are returned as `List`. + +??? warning "default pagination" + many systems have an implicit default pagination enabled, + which could block you from simply getting _all_ tickets. + + you can ask the `TicketSystem` object, to tell you if it uses a default pagination: + + ```java + ts.hasDefaultPagination(); + ``` + +!!! info "assignees" + Tickets have a field of type `Assignee`. + These have final String fields, + where the system implementation puts values if supported. + +!!! example "requesting tickets" + ```java + ts.find() + .setPage(1) + .setPageSize(10) + .get(); + ``` + +You can add various filter options, before finally calling `get()`. +Each supported systems implementation is free to define special filter options. +These are only callable, if your variable has the dedicated child-type. + +The globally available ones are listed below. +They are marked `single` or `multi` types. +A `single` typed filter will override previous values, +whereas `multi` typed ones will be added to the previous values. + +| filter option method definition | type | description | +| :------------------------------- | :------- | :--------------------------------------------------------------------------------------------------------------- | +| `isClosed()` | `single` | returns only tickets closed, or _considered_ closed by the system specific implementation | +| `isOpen()` | `single` | returns only tickets open, or _considered_ open by the system specific implementation | +| `setPage(int)` | `single` | page number of pagination to request | +| `setPageSize(int)` | `single` | page size of request to paginate with | +| `withAssigneeId(String)` | `multi` | tickets with given assigneeId as assignee.
On multiple calls ticket must have _ALL_ given ids as assignees | +| `withAssigneeName(String)` | `multi` | same as assigneeId above | +| `withDescriptionContain(String)` | `single` | substring the description has to contain | +| `withDescriptionMatch(String)` | `single` | fully qualified regular expression, the whole description has to match | +| `withId(String)` | `multi` | id a ticket must have.
multiple calls keeps tickets matching _any_ of the set ids | +| `withLabel(String)` | `multi` | label a ticket must have.
Multiple calls a ticket must have _all_ given labels | +| `withTitleContain(String)` | `single` | substring the title has to contain | +| `withTitleMatch(String)` | `single` | fully qualified regular expression, the whole title has to match | + +## get single ticket + +To request a single ticket the method `getTicketById` is provided, +available with two signatures: +- `getTicketById(String)` +- `getTicketById(int)` + +The integer variant is just for convenience, if you have the id as number. +It calls the String one with your number transformed. + +!!! example + ```java + Ticket t = ts.getTicketById("5"); + ``` + +## create new ticket + +The creation of a new Ticket is started by calling `createTicket()`. +This starts another fluid-api chain, +in which you can set everything your new ticket should contain. +The chain finishes calling `create()` at the end. + +!!! warning + if a mandatory information for ticket creation is not given, + prior calling `create()`, + an `AssertionException` is thrown. + +!!! example + ```java + Ticket t = ts.createTicket() + .title("some title") + .create(); + ``` + +Global available setters for ticket creation are: + +| method | additional information | +| :--------------------------------------------- | :---------------------------------------------------------------------- | +| `assignees(String[])` | array of assignee identifiers, check system specific part, what to pass | +| `description(String)` | | +| `labels(Set)`
`labels(String[])` | | +| `title(String)` | | diff --git a/docs/api/core/ticket.md b/docs/api/core/ticket.md new file mode 100644 index 0000000000000000000000000000000000000000..38c58aa7a47536b4cce2f7dac469f22d8d737866 --- /dev/null +++ b/docs/api/core/ticket.md @@ -0,0 +1,57 @@ +# Ticket + +A ticket instance represents one ticket of the connected space. + +## get/create ticket + +The class is not publicly constructable, +as it always belongs to a `TicketSystem` object. + +Getting an instance for a existing ticket, +or creating a new one, +is done from a `TicketSystem` instance. +[->For details see here <-](./ticket-system.md) +## reading data + +There are various getters available. +Below the globally defined ones are listed, +each system specific implementation is free to provide additional ones. + +!!! warning + systems are not guaranteed to support all data, + a global getter is defined for. + Therefore it can happen, you get an null value back + or exception thrown in this case. + +| method | return | +| :----------------- | :-------------------- | +| `getAssignees()` | `Set` | +| `getDescription()` | `String` | +| `getId()` | `String` | +| `getLabels()` | `Set` | +| `getParent()` | `TicketSystem` | +| `getTitle()` | `String` | +| `isOpen()` | `boolean` | + +## changing data + +You can change data of supported fields through dedicated setters. +Every changed field is flagged as changed. +To persist the changes to the connected space, +you need to call `save()`. +This forms an update request for all flagged fields +and returns a new instance of `Ticket`, +formed off the answer from the connected system. + +Below the globally defined setters are listed, +each system implementation is free to offer more. + +| method | description | +| :-------------------------------------------------- | :-------------------------------------------------------------- | +| `addAssignee(String)`
`removeAssignee(String)` | adds/removes assignee, check system specific part, what to pass | +| `addLabel(String)` | add label | +| `clearAssignees()` | remove all assignees | +| `open()`
`close()` | opens/closes the ticket | +| `setDescription(String)` | | +| `setLabels(Set)`
`setLabels(String[])` | replace all labels with the passed ones | +| `setTitle(String)` | | diff --git a/docs/api/exceptions.md b/docs/api/exceptions.md new file mode 100644 index 0000000000000000000000000000000000000000..4b4cc724ae1e4ad5ebbb016769d6ff14a65aa33d --- /dev/null +++ b/docs/api/exceptions.md @@ -0,0 +1,23 @@ +# Exceptions + +The library defines its own set of exceptions. +Throughout the whole library, these are used. +They are located in the package `de.hftstuttgart.unifiedticketing.exceptions`. + +Base for all others is `UnifiedticketingException`, +which extends `RuntimeException`. +Every other custom exception extends this exception. + +This provides you with the ability, +to catch a specific or all library related problems. +Both without catching exceptions of your own code, +that happen to be in the same try block. + +## Possible Exceptions + +- `AssertionException` +- `DeserializationException` +- `HttpRequestException` +- `HttpResponseException` +- `SerializationException` +- `UnsupportedFunctionException` diff --git a/docs/api/index.md b/docs/api/index.md new file mode 100644 index 0000000000000000000000000000000000000000..463afc33070d442393d3bad702ead024810076a6 --- /dev/null +++ b/docs/api/index.md @@ -0,0 +1,66 @@ +# Java-API + +This is the API-Documentation, +holding detailed information for each publicly available action you can do with each class. +Below the structure of the library is explained and some generic examples are shown. +## library structure + +The library is structured into three packages: + +1. `de.hftstuttgart.unifiedticketing.core` +1. `de.hftstuttgart.unifiedticketing.exceptions` +1. `de.hftstuttgart.unifiedticketing.systems` + +The core package contains the classes defining the generic API, +to be implemented by each supported system. +The systems package contains a sub-package per supported system, +which then holds the implementations of the core classes. +The exceptions package has some own exception types, +used throughout the lib. + +For each package, this documentation provides a chapter in the navigation on the left. + +## examples + +!!! info + These examples are not specific to a certain system. + Therefore they can contain placeholders for system specific parts. + To get these parts, you'll have to go to the dedicated API-docs part. + +??? example "create TicketSystem instance" + __from builder:__ + ```java + TicketSystem ts = TicketSystem.fromBuilder() + . + .build(); + ``` + + __from uri:__ + ```java + TicketSystem ts = TicketSystem.fromUri(); + ``` + +??? example "searching tickets" + __without filters:__ + ```java + ts.find().get(); + ``` + + __only open tickets and explicit pagination:__ + ```java + ts.find() + .isOpen() + .setPage(1) + .setPageSize(10) + .get(); + ``` + +??? warning "default pagination" + many systems have an implicit default pagination enabled, + which could block you from simply getting _all_ tickets. + + !!! tip + you can ask the `TicketSystem` object, to tell you if it uses a default pagination: + ```java + ts.hasDefaultPagination(); + ``` diff --git a/docs/api/systems/gitlab/ticket-system.md b/docs/api/systems/gitlab/ticket-system.md new file mode 100644 index 0000000000000000000000000000000000000000..8ab3d36bb8d47929d4345a7e10c91827cac09614 --- /dev/null +++ b/docs/api/systems/gitlab/ticket-system.md @@ -0,0 +1,138 @@ +# GitLab-Ticketsystem + +This documents GitLab specific things for the integration to this library. +For the global parts, see in the [core sections Ticketsystem site][core-ts]. + +## create new instance + +A `GitlabTicketSystem` object is always referencing a specific GitLab project. +Mandatory information to instantiate it, are the GitLab instances base url and the projects id. + +For public accessible actions, it can be used anonymously. +Other operations have to be authenticated using an api-key. + +For all calls the GitLab api V4 is used (at the time of writing this, the only available one). +If not configured otherwise, connections will use https. + +### by URI + +```java +// recommended option +GitlabTicketSystem ts = (GitlabTicketSystem) TicketSystem.fromUri(""); + +// second possible declaration +TicketSystem< + GitlabTicket, + GitlabTicketSystem, + GitlabTicketBuilder, + GitlabFilter + > gl = TicketSystem.fromUri(""); +``` + +The first declaration option uses the child-class from the GitLab implementation directly. +The second option uses the parent-class instead, +defining the different implementations with Generics. + +Use the first option, if you're sure you want to use GitLab no matter what. +This way you can see GitLab specific methods, +whereas the second option keeps you limited on the global defined ones. +If you may switch ticket systems in the future, +the second option forces you to not use system specific stuff, making a transition easier. + +The URI to pass has to match this format: +``` +unifiedticketing:gitlab:[http://|https://]:[:api key] +``` + +- protocol for http/https is optional. If not given, https is used +- base url can contain also non-standard port hosted gitlab instances +- api key if authentication needed, otherwise anonymous access is used + +??? example "URI examples" + - non-https anonymous, project 234, public gitlab + `unifiedticketing:gitlab:http://wwww.gitlab.com:234` + - implicit https authenticated, project 234, public gitlab + `unifiedticketing:gitlab:gitlab.com:234:1234896102765abcddbda324bb3a3` + - explicit https authenticated, project 42, fictional gitlab, non-standard port + `unifiedticketing:gitlab:https://gitlab.example.org:8080:42:1234896102765abcddbda324bb3a3` + +### by builder + +For instantiation from the builder, +mostly the same like building by URI applies. + +!!! warning + Passing the base url ensure the protocol (http or https) is removed + +??? example "builder examples" + - non-https anonymous, project 234, public gitlab + ```java + GitlabTicketSystem ts = TicketSystem.fromBuilder() + .gitlab() + .withBaseUrl("www.gitlab.com") + .withHttp() + .withProjectId(234) // String and int variant available + .build(); + ``` + - implicit https authenticated, project 234, public gitlab + ```java + GitlabTicketSystem ts = TicketSystem.fromBuilder() + .gitlab() + .withBaseUrl("gitlab.com") + .withProjectId("234") + .withApiKey("1234896102765abcddbda324bb3a3") + .build(); + ``` + - explicit https authenticated, project 42, fictional gitlab, non-standard port + ```java + GitlabTicketSystem ts = TicketSystem.fromBuilder() + .gitlab() + .withBaseUrl("gitlab.example.org:8080") + .withHttps() + .withProjectId(42) + .withApiKey("1234896102765abcddbda324bb3a3") + .build(); + ``` + +## list tickets + +!!! warning "default pagination" + GitLab has a default pagination on _20_ elements per page. + Highest possible value is _100_ elements. [[Link]][gl-api-docs-pagination] + +!!! warning "mutual exclusive filters" + if you filter for assignees, you can only use either assignee-ids or their usernames. [[Link]][gl-api-docs-issues-list] + +!!! info "assignees" + GitLab implementation supports the fields `id`, `username` and `full name`. + If ticket has no assignee, assignee field stays `null`. + +From the filters shown on the global `TicketSystem` docs, +the ones for regex-matching are not natively supported by the GitLab API. +If such a filter is used, +this get's done locally after receiving the response from GitLab, +before handing it to the user. + +## get single ticket + +!!! info + This uses the list mechanism internally, + with the given issue-id as filter and just unwraps it from the received list. + +## create new ticket + +For a new GitLab ticket a title is mandatory. +Everything else is optional. + +!!! example "minimal example" + ```java + GitlabTicket = ts.createTicket() + .title("my new ticket") + .create(); + ``` + +Setting an assignee, has to be by user-id. Setting by user name is not supported. + +[core-ts]: ../../core/ticket-system.md +[gl-api-docs-issues-list]: https://docs.gitlab.com/ee/api/issues.html#list-issues +[gl-api-docs-pagination]: https://docs.gitlab.com/ee/api/#pagination diff --git a/docs/api/systems/gitlab/ticket.md b/docs/api/systems/gitlab/ticket.md new file mode 100644 index 0000000000000000000000000000000000000000..c8a2b00405bed9110b28ab5784a6e436f70a2d51 --- /dev/null +++ b/docs/api/systems/gitlab/ticket.md @@ -0,0 +1,4 @@ +# Gitlab-Ticket + +!!! todo + write usage api docs diff --git a/docs/developers-guide/machine-setup.md b/docs/developers-guide/machine-setup.md new file mode 100644 index 0000000000000000000000000000000000000000..5d1bb2a1cdce9edf09af3df8ab9448878eb4c7fa --- /dev/null +++ b/docs/developers-guide/machine-setup.md @@ -0,0 +1,255 @@ +# Machine Setup + +## General + +### Git + +The whole project is a Git repository, +to do anything you'll need to have Git setup on your machine. + +!!! tip + We highly recommend you use Git directly typing commands to your terminal, + instead of relying on any GUI tools, IDE integration's whatsoever. + They make life easy, sure. + But do you know, what exact calls they do under the hood? + +#### Installation + +=== "*nix" + Should be part of all major systems default software distribution path. + +=== "Windows" + !!! warning "disclaimer" + This is for people having not much experience. + If you e.g. use Cygwin, you could just install Git from there and ignore this^^ + + - Download Git: [Git-SCM][gitscm-win] + - Installation recommendations: + - opt-out from `Enable Git Credential Manager` + _We had bad experiences with it, storing wrong passwords an no one knew where to remove them as none of the pros used this thing^^_ + +#### Configuration + +After installing Git, you'll have to set a few information, +in order to be able to work with it. +Mandatory is your username and email. + +Globally set your most used username and email address you'll be using. + +```bash +git config --global user.name "" +git config --global user.email "" +``` + +!!! attention + If your global email is different from the one for this projects GitLab, + make sure to either add your main email address as committer email in your profile, + or change the git config for this project individually after cloning it. + +#### Clone project + +As of writing, the project can be accessed with HTTPS and SSH. +If this is not working, +check the repository from the link in the upper right corner of the page. +(Maybe the path changed and someone forgot to update this part of the docs) + +=== "SSH" + ```bash + git clone git@transfer.hft-stuttgart.de:9Lukas5/unified-ticketing.git + ``` + +=== "HTTPS" + ```bash + git clone https://transfer.hft-stuttgart.de/gitlab/9Lukas5/unified-ticketing.git + ``` + +## Java Development + +The Java library is development with OpenJDK 8 and Maven 3.6 + +### Requirements + +- Git setup +- OpenJDK 1.8.0+ +- Maven 3.6.0+ + +### Installation + +#### OpenJDK + +=== "*nix" + Check your specific systems package names. + + __Ubuntu 20.04__: + ```bash + sudo apt install openjdk-11-jdk + ``` + +=== "Windows" + + - download OpenJDK: [jdk.java.net][java-net] + - extract archive to permanent place + - create/update system environment variable `JAVA_HOME`, + to the path you extracted OpenJDK to. + - update `PATH` variable including the `bin` folder of your newly placed OpenJDK + - check with a terminal that `java --version` works + +#### Maven + +=== "*nix" + Same as before, check your specific systems package names. + + __Ubuntu:__ + ```bash + sudo apt install maven + ``` + +=== "Windows" + + - download Maven binary: [maven.apache.org][maven-dl] + - extract archive to permanent place + - create/update system environment variable `MAVEN_HOME`, + to the path you extracted Maven to. + - update `PATH` including `bin` folder of maven home + - check that `mvn --version` works + +### Import project to IDE + +Following is described, how to import the maven project to your IDE. +I really hope, you're familiar enough to know how to use your IDE, +so this is a just-in-case service. + +Also, this does not claim to be up-to-date/correct/cover all available IDE's. +You are invited to contribute to this list below +if you're IDE of choice is not listed yet or has some faults. + +=== "IntelliJ IDEA" + - Select `Open or Import` + - Choose the folder you cloned the project into + +## MkDocs (Documentation) + +This project is documented using MkDocs Material. +It means we write Markdown files, organize them in a configuration file +and MkDocs generates a static Website out of it we host and you are reading right now. + +### Requirements + +- Python 3.5+ +- pip +- Python virtual environment _(optional)_ + +### Installation + +=== "*nix" + check system specific names and commands, below are some examples collected over time: + + __Ubuntu:__ + ```bash + sudo apt install python3 python3-pip python3-venv + ``` + +=== "Windows" + - download & install Python: [python.org][python-win-dl] (use executable installer version) + +- open a terminal inside the project's root directory +- _optional:_ create & activate new virtual environment: + + === "*unix" + ```bash + python3 -m venv env + . ./env/bin/activate + ``` + + === "Windows" + === "CMD" + ```cmd + python -m venv env + env\scripts\activate.bat + ``` + === "Power Shell" + !!! attention "execution policy" + You may have to first set the correct execution policy, + before able to run the activation script. + + ```powershell + Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + ``` + + ```powershell + python -m venv env + env\scripts\Activate.ps1 + ``` + +- install all required packages: + ``` + pip install -Ur requirements.txt + ``` + +### Usage + +To work on the documentation, the mkdocs development server has to run. +On start it tells you on which port it runs (default is `8000`). + +Open the Browser on the shown URL and edit the Markdown files. +On saving changes your Browser should automatically reload the page. + +- _optional:_ enter python virtual environment + + === "*unix" + ```bash + . ./env/bin/activate + ``` + + === "Windows" + === "CMD" + ```cmd + env\scripts\activate.bat + ``` + === "Power Shell" + !!! attention "execution policy" + You may have to first set the correct execution policy, + before able to run the activation script. + + ```powershell + Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + ``` + + ```powershell + env\scripts\Activate.ps1 + ``` + +- start MkDocs development server: + ```bash + mkdocs serve + ``` +- work +- kill dev server by pressing `ctrl+c` +- _optional:_ exit python virtual environment: + ```bash + deactivate + ``` + +### Editor/IDE + +You don't need any special IDE, as a bare minimum a text editor would work (even vim is possible). +__But don't you dare to use this crappy Microsoft built in editor!__ + +Practically it's very supportive of course, +to use a IDE that has good markdown support in terms of code-highlighting, +table formatting, etc. +Below are collected tips for different IDE's. + +=== "VSCode" + recommended extensions: + _these are the extension id's searchable from vscode_ + + - `editorconfig.editorconfig` + - `waderyan.gitblame` + - `yzhang.markdown-all-in-one` + - `jebbs.plantuml` + +[gitscm-win]: https://git-scm.com/download/win +[java-net]: https://jdk.java.net/ +[maven-dl]: https://maven.apache.org/download.cgi +[python-win-dl]: https://www.python.org/downloads/windows/ diff --git a/docs/developers-guide/styleguide.md b/docs/developers-guide/styleguide.md new file mode 100644 index 0000000000000000000000000000000000000000..85c4e4db3db39d31f9b47400669a8be30f998418 --- /dev/null +++ b/docs/developers-guide/styleguide.md @@ -0,0 +1,99 @@ +# Styleguide + +If not explicitly stated otherwise, +the following takes effect for all files: + +- character encoding __utf-8__ +- line endings with __lf__ +- indentation with __4 spaces__ +- final new line + +In general, +it's a good idea to have a look into the yet existing code, +to check how certain things were done up to now. + +## Java + +The most important thing to say here is: opening braces are written into the next line. +_(more to come if s.o. does s.th. differently I didn't think of)_ + +## Markdown + +most important bullet points: + +- leave always an empty line above and beneath of lists. + It may render fine in normal markdown viewers, + but not in the MkDocs Pages docs (like this) + + ??? example inline end + __bad:__ + ```markdown + some text + - bullet point + - another item + more normal text + ``` + __good:__ + ```markdown + some text + + - bullet point + - another item + + more normal text + ``` + +- if you insert a link, + __always__ write the link to the bottom of the file with an alias, + ordered alphabetically. + + ??? example + __bad:__ + ```markdown + Look [here](https://www.coolsite.not/with/ultra/long/url) to read more about this. + ``` + __good:__ + ```markdown + Look [here][coolsite] to read more about this. + + [coolsite]: https://www.coolsite.not/with/ultra/long/url + ``` + +- split long sentences on punctuation and connection words like `and` & `or`. + It will have the same appearance in viewers, + but be much easier to maintain on code side. + + ??? example + __bad__: + ```markdown + Some sentence that is very long, therefore it has punctuation and has absolutely no sense at all. + ``` + > Some sentence that is very long, therefore it has punctuation and has absolutely no sense at all. + + __good:__ + ```markdown + Some sentence that is very long, + therefore it has punctuation + and has absolutely no sense at all. + ``` + + > Some sentence that is very long, + > therefore it has punctuation + > and has absolutely no sense at all. + +- tables have to be formatted in code + + ??? example + __bad:__ + ```markdown + ||column 1| + |:-|:-| + |__row 1__|cell 1| + ``` + + __good:__ + ```markdown + | | column 1 | + | :-------- | :------- | + | __row 1__ | cell 1 | + ``` diff --git a/docs/developers-guide/uml.md b/docs/developers-guide/uml.md new file mode 100644 index 0000000000000000000000000000000000000000..c3666ae1af6d479a067cea973f12e996739251ce --- /dev/null +++ b/docs/developers-guide/uml.md @@ -0,0 +1,411 @@ +# Library UML-Diagram + +This is the full UML-diagram for the Unified-Ticketing library. + +!!! tip + You most likely can't read anything embedded to the site, + please open the graphics-URL in an extra tab and zoom in. + +```plantuml + +abstract Filter { + __ generics definition __ + T extends Ticket + F extends Filter + == + - {static} logger: Logger + + # {static} addToSet(\n\tfilterName: FilterNames,\n\tmap: Map,\n\tnewValue: String\n) + + __ instance definition __ + # setFilters: Map + + + constructor() + + + withAssigneeId(id: String): F + + withAssigneeName(name: String): F + + withDescriptionContain(substring: String): F + + withDescriptionMatch(regex: String): F + + withId(id: string): F + + isOpen(): F + + isClosed(): F + + withLabel(label: String): F + + setPage(page: int): F + + setPageSize(size: int): F + + withTitleContain(substring: String): F + + withTitleMatch(regex: String): F + + + {abstract} get(): List +} + +enum FilterNames { + + ASSIGNEEID + + ASSIGNEENAME + + DESCRIPTION_CONTAIN + + DESCRIPTION_MATCH + + IDS + + LABELS + + OPEN + + PAGE + + PAGINATION + + TITLE_CONTAINS + + TITLE_MATCH +} + +class Logging { + - {static} handler: Handler + - {static} mainLogger: Logger + - {static} logger: Logger + + + {static} getLogger(name: String): Logger + + {static} setFormatter(formatter: Formatter): void + + {static} setLevel(level: Level): void + + {static} test(message: String): void +} + +class RegisteredSystems <<(S, orange)>> { + - {static} logger: Logger + - {static} instance: RegisteredSystems + + # {static} getInstance(): RegisteredSystems + + __ instance definition __ + + constructor() + + + gitlab(): GitlabTicketSystemBuilder +} + +abstract Ticket { + __ generics definition __ + T \t extends Ticket + TS \t extends TicketSystem + == + - {static} logger: Logger + + __ instance definition __ + # assignees: Set + # description: String + # id: String + # labels: Set + # open: boolean + # title: String + + # updatedFields: Set + # parent: TS + + # constructor(parent: TS) + + + getAssignees(): Set + + {abstract} addAssignee(identifier: String): T + + clearAssignees(): T + + {asbtract} removeAssignee(identifier: String): T + + getDescription(): String + + setDescription(description: String): T + + getId(): String + + addLabel(label: String): T + + getLabels(): Set + + setLabels(labels: Set): T + + setLabels(labels: String[]): T + + isOpen(): boolean + + open(): T + + close(): T + + getParent(): TS + + getTitle(): String + + setTitle(title: String): T + + + {abstract} save(): T + + + equals(o: Object): boolean + + hashCode(): int + + toString(): String +} + +enum FieldNames { + + ASSIGNEES + + DESCRIPTION + + ID + + LABELS + + OPEN + + TITLE +} + +abstract TicketAssignee { + + email: String + + id: String + + fullName: String + + username: String + + # constructor(\n\temail: String,\n\tid: String,\n\tusername: String,\n\tfullName: String\n) + + + equals(o: Object): boolean + + hashCode(): int + + toString(): String +} + +abstract TicketBuilder { + __ generics definition __ + B \t extends TicketBuilder + T \t extends Ticket + TS \t extends TicketSystem + == + - {static} logger: Logger + + __ instance definition __ + # assignees: Set + # description: String + # labels: Set + # title: String + + # constructor(parent: TS) + + + assignees(identifiers: String...): B + + description(description: String): B + + labels(labels: Set): B + + labels(labels: String[]): B + + title(title: String): B + + + {abstract} create(): T +} + +abstract TicketSystem { + __ generics definition __ + B \t extends TicketBuilder + F \t extends Filter + T \t extends Ticket + TS \t extends TicketSystem + == + - {static} logger: Logger + + + {static} fromBuilder(): RegisteredSystems + + {static} fromUri(uri: String): TicketSystem + + __ instance definition __ + + apiKey: String + + baseUrl: String + + password: String + + username: String + + # configuration: Map + + + constructor() + + + config(option: ConfigurationOptions, value: String): TS + + config(option: ConfigurationOptions, value: boolean): TS + + getConfigTrue(option: ConfigurationOptions): boolean + + getConfigValue(option: ConfigurationOptions): Object + + {abstract} createTicket(): TB + + {abstract} find(): F + + {abstract} getTicketById(id: String): T + + {abstract} getTicketById(id: int): T + + + {abstract} hasAssigneeSupport(): boolean + + {abstract} hasDefaultPagination(): boolean + + {abstract} hasLabelSupport(): boolean + + {abstract} hasPaginationSupport(): boolean + + {abstract} hasReturnNullOnErrorSupport(): boolean +} + +enum ConfigurationOptions { + + RETURN_NULL_ON_ERROR +} + +abstract TicketSystemBuilder { + __ generics definition __ + B \t extends TicketBuilder + TS \t extends TicketSystem + == + - {static} logger: Logger + + __ instance definition __ + + baseUrl: String + + + withBaseUrl(url: String): B + + + {abstract} build(): TS +} + +' package connections +Filter *-- FilterNames: "inner class" +TicketSystem --> RegisteredSystems: "fromBuilder()" +TicketSystem *-- ConfigurationOptions: "inner class" +Ticket *-- FieldNames: "inner class" +Ticket --> Ticket: "save()" +Ticket o-- TicketSystem: "parent" +Ticket o-- TicketAssignee +TicketSystem --> TicketBuilder: "createTicket()" +TicketBuilder --> Ticket: "create()" + +class AssertionException { + + constructor() + + constructor(msg: String) + + constructor(msg: String, cause: Throwable) + + constructor(suppressed: Throwable) +} + +class DeserializationException { + + constructor() + + constructor(msg: String) + + constructor(msg: String, cause: Throwable) + + constructor(suppressed: Throwable) +} + +class HttpRequestException { + + constructor() + + constructor(msg: String) + + constructor(msg: String, cause: Throwable) + + constructor(suppressed: Throwable) +} + +class HttpResponseException { + + constructor() + + constructor(msg: String) + + constructor(msg: String, cause: Throwable) + + constructor(suppressed: Throwable) +} + +class SerializationException { + + constructor() + + constructor(msg: String) + + constructor(msg: String, cause: Throwable) + + constructor(suppressed: Throwable) +} + +class UnifiedticketingException { + + constructor() + + constructor(msg: String) + + constructor(msg: String, cause: Throwable) + + constructor(suppressed: Throwable) +} + +class UnsupportedFunctionException { + + constructor() + + constructor(msg: String) + + constructor(msg: String, cause: Throwable) + + constructor(suppressed: Throwable) +} + +AssertionException -[hidden]down- DeserializationException +DeserializationException -[hidden]down- HttpRequestException +HttpRequestException -[hidden]down- HttpResponseException +HttpResponseException -[hidden]down- SerializationException +SerializationException -[hidden]down- UnifiedticketingException +UnifiedticketingException -[hidden]down- UnsupportedFunctionException + +class GitlabFilter { + - {static} logger: Logger + + __ instance definition __ + # parent: GitlabTicketSystem + + # getHttpClient(): OkHttpClient + + get(): List +} + +class GitlabTicket { + - {static} logger: Logger + + # {static} fromTicketResponse(\n\tparent: GitlabTicketSystem,\n\tresponse: GitlabTicketResponse\n): GitlabTicket + + __ instance definition __ + # constructor(parent: GitLabTicketSystem) + + + addAssignee(userId: String): GitlabTicket + + addAssignee(userId: int): GitlabTicket + + removeAssignee(userId: String): GitlabTicket + + removeAssignee(userId: int): GitlabTicket + + save(): GitlabTicket + + + deepEquals(o: Object): boolean +} + +class GitlabTicketAssignee { + # constructor(id: int, fullName: String, username: String) +} + +class GitlabTicketBuilder { + - {static} logger: Logger + + __ instant definition __ + # constructor(parent: GitlabTicketSystem) + + + assignees(identifiers: String...): GitlabTicketBuilder + + assignees(identifiers: int...): GitlabTicketBuilder + + # getHttpClient(): OkHttpClient + + create(): GitlabTicket +} + +class GitlabTicketResponse { + + assignees: List + + description: String + + iid: int + + labels: Set + + state: String + + title: String + + # constructor() +} + +class Assignee { + + id: int + + name: String + + username: String +} + +class GitlabTicketSystem { + - {static} logger: Logger + + + {static} fromUri(uri: String): GitlabTicketSystem + + __ instance definition __ + # constructor() + + createTicket(): GitlabTicketBuilder + + find(): GitlabFilter + + getTicketById(id: String): GitlabTicket + + + hasAssigneeSupport(): boolean + + hasDefaultPagination(): boolean + + hasLabelSupport(): boolean + + hasPaginationSupport(): boolean + + hasReturnNullOnErrorSupport(): boolean +} + +class GitlabTicketSystemBuilder { + - {static} logger: Logger + + __ instance definition __ + # apiKey: String + # apiVersion: String + # projectId: int + # https: boolean + + + constructor() + + + withApiKey(apiKey: String): GitlabTicketSystemBuilder + + withHttp(): GitlabTicketSystemBuilder + + withHttps(): GitlabTicketSystemBuilder + + withProjectId(projectId: int): GitlabTicketSystemBuilder + + withProjectId(projectId: String): GitlabTicketSystemBuilder + + + build(): GitlabTicketSystem +} + +' package connections +GitlabFilter o-- GitlabTicketSystem: "parent" +GitlabTicketResponse o- Assignee: "inner class" +GitlabTicketSystemBuilder --> GitlabTicketSystem: "build()" +GitlabTicketSystem --> GitlabTicketBuilder: "createTicket()" +GitlabTicketBuilder --> GitlabTicket: "create()" +GitlabTicketSystem *-- GitlabTicketResponse + +' core package connections +GitlabFilter --|> Filter +GitlabTicket --|> Ticket +GitlabTicketAssignee --|> TicketAssignee +GitlabTicketBuilder --|> TicketBuilder +GitlabTicketSystem --|> TicketSystem +GitlabTicketSystemBuilder --|> TicketSystemBuilder + +RegisteredSystems --> GitlabTicketSystemBuilder: "gitlab()" + +``` diff --git a/docs/developers-guide/workflow.md b/docs/developers-guide/workflow.md new file mode 100644 index 0000000000000000000000000000000000000000..7373caafcc6363df474f20631b6bc47c304507f5 --- /dev/null +++ b/docs/developers-guide/workflow.md @@ -0,0 +1,397 @@ +# Workflow + +This project is maintained in a GitLab repository, +hosted on the [M4Lab's][m4lab] [Transfer-Portal][tr-portal] [GitLab instance][tr-gitlab]. +Source code for the maven Java library and the markdown docs are managed together in a [single repository][lib-repo-home]. + +This page tells you for the different parts of this project, +how to do it. +The following applies project wide: + +- language is english: code, comments, documentation, tickets, discussion, ... + +## Git/GitLab + +!!! danger "disclaimer" + There are a few rules any developer HAS TO follow, + in order to get any chance his merge-requests will be accepted. + +This project is managed using Git, hosted on the universities GitLab instance. + +### Issues/Merge Requests handling + +Project management happens in the GitLab repositories issue board. + +First of all, make sure for everything you do a ticket exists. +Extending this, also check regularly your tickets are: + +- assigned to you +- are in the correct column + +There are three columns as of writing this documentation: `To Do`, `Doing` and `review`. +Planning something, a new ticket get's created and placed into the `To Do` column. + +If you start to work on this ticket + +- move it to `Doing` +- create a new feature branch from the master + - named like: `-` +- push the new branch +- create a new merge request + - title starting with `wip: ` + - description containing `closes #` + - assign it to you (even if you're not able to merge) +- start working + +After implementing your change + +- move your ticket to `review` column +- change your merge requests labels: remove `Doing` and add `review` +- change assignee to someone to review your work + +### Branch Names + +Branches should always start with the number of the related ticket, followed by a dash. +This way the branch get's automatically shown in the ticket. + +### Committing + +!!! tip "golden rules" + - __many small__ > ~~few big~~ commits + - unrelated changes in separate commit + +We encourage everyone to make heavy use of `git status` and `git diff`. +Please always check before committing, what exactly you have changed. +What we won't accept: + +- whole file content removed and added back + This most likely happens if you make great use of auto format, + messing everything up. + Another one error source is something changed line endings. +- empty lines containing spaces, or trailing spaces on line end (without technical reason) + No big deal to fix, but time waste if we have to block your MR because of this. +- multiple changes in one commit, that have nothing to do with each other + Great you have fixed a typo in a comment at the other end of the file. + What do you think happens, if five people fix the same typo in their commits? + We would have four merge conflicts, needing manual work to fix this mess. + So create a new ticket for what you found, + instead of just doing it as it doesn't hurt. + It hurts, trust me. +- commit messages not following conventional commits specification + +!!! tip "view diff of not yet tracked files" + If you want to check a new file for flaws, sure `git diff` doesn't show anything. + But you can add the file and before committing check with `git diff --cached`. + +!!! tip "add only parts of changes in a file" + As we want to have more small commits, than one single big one, + it can be useful to split your changes into multiple commits, + even inside the same file. + You can use `git add -p [path|file]`. + This allows you to exactly decide which lines of your changes should be staged + , before committing. + +#### Commit Messages + +We use the [conventional commits][conv-comm] specification in this repository, +to auto generate a changelog with [conventional-changelog][conv-change]. + +### Protected Branches/Tags + +The repository has the master branch and release tags (format `^[0-9]+\.[0-9]+\.[0-9]+$`) +protected to project maintainers. + +### Branching-Model + +We use a branch per feature based branching model. +Base and target to merge is always latest `master`. + +## Java Development + +First step before changing the source code, +would be to check if there's something going on yet, +or this topic possibly was discussed yet and abandoned for some reason. +For this, check the [defined GitLab workflow](#gitgitlab). + +This library is a maven project. +In order to contribute to it, +make sure your machine is setup according to the [setup guide][setup-guide]. + +### Change an existing functionality + +- check with the [source structure below](#source-code-structure), + where to find the part you want to change. +- make your changes +- make sure all unittests still pass +- commit your changes following the Git/GitLab workflow defined. + +### Add integration for new system + +- familiarize with the [code structure](#source-code-structure) +- create a new package under `de.hftstuttgart.unifiedticketing.systems`, + identifying the new system +- prepare to implement all abstract classes from the `core` package + - class names have to be the same as the `core` ones, + prefixed with the identifier you named your package after +- create unittests for the planned integration, + either by putting a `fail();` into each testmethod, + or really writing tests first for TDD +- commit & push this skeleton-like state +- create WIP merge-request +- implement + +### Source code structure + +After cloning the repository, +you'll have to open/import an existing maven project in your IDE of choice. +There WILL NOT be any configuration files for a specific IDE committed into the code. +In regards to the maven project parts, +only the `pom.xml` and the contents under `/src` are committed. + +The main package for everything of this library is `de.hftstuttgart.unifiedticketing`. +Beneath it is split into three sub-packages: + +| subpackage | content | +| :----------- | :------------------------------------------------------------------------- | +| `core` | root classes defining lib core, generic public interface | +| `exceptions` | library own exceptions | +| `systems` | subpackage per system integration, implementation of abstract core-classes | + +__core:__ +The majority of the classes are abstract ones. +They define the generic interface available to the user of this lib. +Logic identical for all system integrations are found in these classes. +Only few methods are really declared abstract, +in most cases it's the part calling the external system. + +__exceptions:__ +The library defines its own exceptions, based on `RuntimeException`. +If you throw any exception, +__only__ use exceptions from this package, +never anything else. + +If you miss an exception you'd like to throw, +add a new one that extends `UnifiedTicketingException`. + +__systems:__ +Each system that's integrated into this lib, +will have a sub-package under `de.hftstuttgart.unifiedticketing.systems`. +In this very own package every abstract class from the `core`-package has to be implemented. +Apart from that, +every system can define as many helper classes +or additional sub-packages. + +### Unittests + +The logical code is structured under `/src/main/java`. +For unittests the same package structure is created under `/src/test/java`. +Tests are written using the `jupiter-engine` from JUnit5, +combined with `Mockito3`. + +- test-classes are named identical to the class under test, + suffixed with `Test` +- test-classes have to be in the same package than the class under test + +What has to be tested: + +- constructors +- getters/setters +- calculations/transformations/... +- fluent-api to return the same instance +- serializing request data before request +- failing web-request +- successful web-request & deserializing of received data + +!!! warning "testing external resources" + All tests _have to_ run offline. + To test external resources, + e.g. a web-request, + use Mockito to block the code under test to really access the external resource + and transparently return your mock answer expected for the assertions following. + +??? tip "test abstract classes" + To test non-abstract code of abstract classes, + you can instantiate a mock of it through Mockito, + set to call the real methods: + + ```java + instance = mock(ClassUnderTest.class, + withSettings().useConstructor().defaultAnswer(CALLS_REAL_METHODS)); + ``` + +## Documentation + +Documentation for the project is done entirely in Markdown +and rendered through MkDocs to a Website. +The repository global `README.md` just points to the documentation root, +which is `/docs/index.md`. +The same applies for the `CONTRIBUTING.md`. +`CHANGELOG.md` and `LICENSE.md` are kept with content in project root, +they are linked with a relative soft-link into the documentation folder. + +Files related to the documentation: + +| path | description | +| :----------------- | :---------------------------------------------- | +| `mkdocs.yml` | configuration file for mkdocs | +| `requirements.txt` | needed pypi packages to pass to pip for install | +| `/docs/**/*` | documentation files | +| `/docs/index.md` | Pages root | + +With the aim to give the documentation an appealing appearance, +additional to the default markdown specification, +a few extensions are enabled in the mkdocs config. +Please have a look at them and make use of, +where it seems adequate. +Reference for them can be found in the [MkDocs-Material site][mat-mkdocs-ext-ref]. + +To make any kind of diagram, sketch or similar, +use [PlantUML][puml]. +You have to surround the PlantUML code with code fences, +marked as `plantuml` as language identifier. +Then they will be rendered into an svg on pages creation. + +!!! bug + I tried to put this into an collapsed example admonition, + but the PlantUML diagram get's always placed outside the admonition. + Same applies for a tabbed environment. + +Example: +__code:__ +`````` +```plantuml +queue "write\nmarkdown" as write +queue "commit/push/\nmerge changes" as update +queue "pipeline\ntriggered" as cicd +queue "MkDocs\nMaterial" as MkDocsMat +queue "transpiled HTML\nonline" as deployed + +write -right-> update +update -right-> cicd +cicd -right-> MkDocsMat +MkDocsMat -right-> deployed +``` +`````` + +__result:__ +```plantuml +queue "write\nmarkdown" as write +queue "commit/push/\nmerge changes" as update +queue "pipeline\ntriggered" as cicd +queue "MkDocs\nMaterial" as MkDocsMat +queue "transpiled HTML\nonline" as deployed + +write -right-> update +update -right-> cicd +cicd -right-> MkDocsMat +MkDocsMat -right-> deployed +``` + +## Schedule a release + +For releases this project uses [standard-version][std-ver]. +This generates an automatic changelog based on the commits +and tags it. +The version of the library has three numbers +and has to follow the [semantic-version][semver] scheme. + +Tags marking a release have the format `^[0-9]+\.[0-9]+\.[0-9]+$`. +Pushing these tags is restricted in the GitLab Repo settings +for maintainers only. +Pushing a release tag triggers the CI/CD release pipeline for the maven project. + +## CI/CD + +This project uses GitLab-CI pipelines for + +- publishing the maven library to the repository own package registry +- deploying this pages documentation + +These pipelines are defined in several files: + +| file | content | +| :---------------------- | :------------------------------------------------------------ | +| `.gitlab-ci.yml` | root file, stages definition, include of other pipeline parts | +| `.gitlab-ci-maven.yml` | jobs regarding java library | +| `.gitlab-ci-mkdocs.yml` | jobs regarding pages documentation | + +pipeline graph overview: +```plantuml +rectangle "compile" as stageCompile { + ' maven + agent "maven:compile" as mvnCompile + + ' mkdocs + agent "mkdocs:compile" as mkdocsCompile +} +rectangle "test" as stageTest { + ' maven + agent "maven:test" as mvnTest + + ' mkdocs + agent "none" as mkdocsTest +} +rectangle "deploy" as stageDeploy { + ' maven + agent "maven:publish:master" as mvnPublMaster + agent "maven:publish:release" as mvnPublRelease + label "get's deployed with\n'devel' as version" as labelMvnPublMaster + label "get's deployed\nwith release version" as labelMvnPublRelease + + ' mkdocs + agent "mkdocs:bundle" as mkdocsBundle + agent "mkdocs:deploy" as mkdocsDeploy + label "creates tar archive as\ndownloadable job artifact" as labelMkdocsBundle + label "only triggered\non master branch" as labelMkdocsDeploy +} + +' maven pipeline connections +mvnCompile -right-> mvnTest +mvnTest -right-> mvnPublMaster +mvnTest -right-> mvnPublRelease + +mvnPublMaster -right- labelMvnPublMaster +mvnPublRelease -right- labelMvnPublRelease + +' mkdocs pipeline connections +mkdocsCompile -right-> mkdocsTest +mkdocsTest -right-> mkdocsBundle +mkdocsTest -right-> mkdocsDeploy + +mkdocsBundle -right- labelMkdocsBundle +mkdocsDeploy -right- labelMkdocsDeploy + +' compile stage keep in place +mvnCompile --[hidden]down- mkdocsCompile + +' test stage keep in place +mvnTest --[hidden]down-mkdocsTest + +' deploy stage keep in place +mvnPublMaster -[hidden]down- mvnPublRelease +mvnPublRelease -[hidden]down- mkdocsBundle +mkdocsBundle -[hidden]down- mkdocsDeploy +``` + +These jobs are defined with the `needs` keyword, +to make them only depend on exactly the needed previous jobs. +This makes it possible to run docs and library pipelines in parallel, +without waiting that all jobs of a stage must have finished before entering the next stage. + +With the `only` keyword the trigger of these pipelines is optimized, +to only run if necessary. +In general the final deployment jobs have configurations to run only on the secured branches/tags. +Additionally all jobs are configured to only run, +if changes on related files of this pipeline were made. + +[conv-comm]: https://www.conventionalcommits.org/en/v1.0.0/ +[conv-change]: https://github.com/conventional-changelog/conventional-changelog +[lib-repo-home]: https://transfer.hft-stuttgart.de/gitlab/9Lukas5/unified-ticketing/ +[m4lab]: https://www.hft-stuttgart.de/forschung/innovative-hochschule-m4-lab +[mat-mkdocs-ext-ref]: https://squidfunk.github.io/mkdocs-material/reference/abbreviations/ +[puml]: https://plantuml.com/ +[setup-guide]: /404.html +[semver]: https://semver.org/ +[std-ver]: https://github.com/conventional-changelog/standard-version +[tr-gitlab]: https://transfer.hft-stuttgart.de/gitlab/explore/projects +[tr-portal]: https://transfer.hft-stuttgart.de/ diff --git a/docs/index.md b/docs/index.md index 89802646862816fe7be48552e85509066943765c..14ae6b667f62fb2dc526143ca7585261b7e8d558 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,3 +1,78 @@ +[![maven][badge-latest-tag]][project-packages] +[![pipeline state][badge-master-pipe]][project-pipelines] +[![latest dev pipeline][badge-latest-pipe]][project-pipelines] +[![License GPLv3][badge-gplv3]][gplv3] +[![Conventional Commits][badge-conventional-commits]][convcomm] + # Unified Ticketing -!!! Todo +This is the documentation for a Java-library called `unified-ticketing`. +This lib provides generic interfaces to interact with tickets +from different ticket systems out of your Java code. + +This library is a maven artifact, +published under the [GNU GPL-v3][gplv3] license. +The source code is publicly available from the [transfer portal][transferportal] of the [University of Applied Sciences Stuttgart][hfthome]. + +## What to find where + +The documentation is split in three main parts, navigable on the top-bar. +Each main-part gives you a navigation of it's content on the left. +On the right, the currents page table of contents is shown. +The icon in the upper left brings you from anywhere back to this start-page. +In the upper right you can go to the source code repository of this library and documentation. +Leftwards a full-text search is provided. + +The part you are reading right now (__Home__), is the main website. +Following is a list, what each site contains: + + - __Changelog:__ auto-generated changelog from the commits + - __Contributing:__ + - Prerequisites to be able to be a contributor to this project + - __License:__ GNU GPLv3 content + - __Usage:__ + - needed entries to get this library into your own maven-project + - some code-snippets showing the libs capabilites + +The __API__ part holds a detailed description, for each publicly accessible class and their methods. +There is an own index file, explaining the package structure of the library +and how it is documented. + +The __Developers Guide__ is the part, you have to lookup how to setup your machine and conventions and workflows used in this project, +if you decide to contribute to it. + +## Maintainer + +This library and it's development belongs to the University of Applied Sciences Stuttgart. + +It was originally developed as bachelors-thesis by Lukas Wiest +[:material-email-send:{: style="color: black"}][9l5-hft-mail] +[:fontawesome-brands-twitter:{: style="color: #1DA1F2"}][9l5Twitter] +[:fontawesome-brands-github:{: style="color: black"}][9l5GH] +[:fontawesome-brands-gitlab:{: style="color: orange"}][9l5GL]. +The guardian professor was Prof. Dr. Gero Lueckemeyer +[:material-email-send:{: style="color: black"}][lueck-hft-mail] +[:fontawesome-solid-university:{: style="color: black"}][lueck-hft-profile] +[:fontawesome-brands-github:{: style="color: black"}][lueck-GH] +[:fontawesome-brands-xing:{: style="color: teal"}][lueck-Xing]. +He is the current maintainer for this project and the appropriate contact for questions, access request, etc. + +[9l5-hft-mail]: mailto:62wilu1bif@hft-stuttgart.de +[9l5GH]: https://www.github.com/9Lukas5 +[9l5GL]: https://www.gitlab.com/9Lukas5 +[9l5Twitter]: https://twitter.com/9Lukas5 +[badge-conventional-commits]: https://img.shields.io/badge/Conventional%20Commits-1.0.0-orange.svg +[badge-gplv3]: https://img.shields.io/badge/License-GPLv3-blue.svg +[badge-latest-pipe]: https://img.shields.io/badge/dynamic/json?color=lightgrey&label=latest%20dev%20pipeline&query=%24%5B0%5D.status&url=https%3A%2F%2Ftransfer.hft-stuttgart.de%2Fgitlab%2Fapi%2Fv4%2F%2Fprojects%2F154%2Fpipelines%3Fper_page%3D1 +[badge-latest-tag]: https://img.shields.io/badge/dynamic/json?color=green&label=maven&query=%24%5B0%5D.name&url=https%3A%2F%2Ftransfer.hft-stuttgart.de%2Fgitlab%2Fapi%2Fv4%2Fprojects%2F154%2Frepository%2Ftags%3Fper_page%3D1 +[badge-master-pipe]: https://transfer.hft-stuttgart.de/gitlab/9Lukas5/unified-ticketing/badges/master/pipeline.svg +[convcomm]: https://conventionalcommits.org +[gplv3]: unified-ticketing/license-softlink.md +[hfthome]: https://www.hft-stuttgart.de +[lueck-GH]: https://github.com/lueckemeyer +[lueck-hft-mail]: mailto:gero.lueckemeyer@hft-stuttgart.de +[lueck-hft-profile]: https://www.hft-stuttgart.de/p/gero-lueckemeyer +[lueck-Xing]: https://www.xing.com/profile/Gero_Lueckemeyer +[project-packages]: https://transfer.hft-stuttgart.de/gitlab/9Lukas5/unified-ticketing/-/packages +[project-pipelines]: https://transfer.hft-stuttgart.de/gitlab/9Lukas5/unified-ticketing/pipelines +[transferportal]: https://transfer.hft-stuttgart.de diff --git a/docs/unified-ticketing/changelog-softlink.md b/docs/unified-ticketing/changelog-softlink.md new file mode 120000 index 0000000000000000000000000000000000000000..699cc9e7b7c5bf63c3549abe36e3eecf8efab625 --- /dev/null +++ b/docs/unified-ticketing/changelog-softlink.md @@ -0,0 +1 @@ +../../CHANGELOG.md \ No newline at end of file diff --git a/docs/unified-ticketing/contributing.md b/docs/unified-ticketing/contributing.md new file mode 100644 index 0000000000000000000000000000000000000000..ccdc25e47930548ae5bb63a2a0d3689ebb3d566c --- /dev/null +++ b/docs/unified-ticketing/contributing.md @@ -0,0 +1,19 @@ +# Contributing + +To contribute to this project, +you primarily have to be a member of the University of Applied Sciences Stuttgart. +This project is hosted on our Transferportal's GitLab instance, +to which only HFT members have access to my knowledge. + +Apart from that, for contributing to the library code itself, +you should be able to program Java and be familiar with maven. +For the documentation you need to have Python installed and know how to write Markdown. + +For all contributions you need to use Git. + +For details see the [Developer Guide][dev-guide]. +There you can find information about getting ready, +what rules to follow +and more developers than user based documentation about the library. + +[dev-guide]: ../developers-guide/machine-setup.md diff --git a/docs/unified-ticketing/license-softlink.md b/docs/unified-ticketing/license-softlink.md new file mode 120000 index 0000000000000000000000000000000000000000..f0608a63ae16053f55e32ab4abf40e7a61f2dccb --- /dev/null +++ b/docs/unified-ticketing/license-softlink.md @@ -0,0 +1 @@ +../../LICENSE.md \ No newline at end of file diff --git a/docs/unified-ticketing/usage.md b/docs/unified-ticketing/usage.md new file mode 100644 index 0000000000000000000000000000000000000000..a7c834db5406e01ab3d7f6546d23dc49f39d6f1c --- /dev/null +++ b/docs/unified-ticketing/usage.md @@ -0,0 +1,66 @@ +# Usage + +## Add as dependency in own project + +This library can be used as maven dependency in an own project. + +!!! attention + As it is not published to maven central, + but the GitLab integrated package registry, + you must configure an additional repository in your pom. + +__repository config:__ +```xml + + unified-ticketing + https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/154/packages/maven + +``` + +__dependency information:__ +```xml + + de.hftstuttgart + unified-ticketing + 0.1.0 + +``` + +??? tip "example how your pom should look like" + ```xml + + + + + + de.hftstuttgart + unified-ticketing + 0.1.0 + + + + + + + gitlab-maven + https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/154/packages/maven + + + + + ``` + +## Use in code + +There are two central classes: `TicketSystem` and `Ticket`. +The majority of the library is written with the fluent-api design pattern. + +To begin, you'll need an instance of `TicketSystem`. +This can be done, by calling the builder mechanism or pass a URI with all needed information. + +Using this `TicketSystem` object you can search for tickets in the connected space, +change and save them or create new tickets. + +To get full details of the available API, please switch to the [API docs](../api/index.md). +There you can find information and examples regarding the generic parts of the library, +as-well as system specific information, e.g. how an URI instantiation string has to look like, etc. diff --git a/mkdocs.yml b/mkdocs.yml index 46a70d5b4f162be2bf11700d1c9b71f7b38b0d6e..e3df64ad89299ebcbbbb0dfdfc4e0ef76c128f24 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,42 +1,66 @@ -site_name: Unified Ticketing Doku +site_name: Unified Ticketing Docs -repo_name: 'Unified Ticketing Java Bibliothek' -repo_url: 'https://transfer.hft-stuttgart.de/gitlab/9Lukas5/unified-ticketing' -edit_uri: 'blob/master/docs/' docs_dir: docs +edit_uri: 'blob/master/docs/' +repo_name: 'Code on Transfer Portal' +repo_url: 'https://transfer.hft-stuttgart.de/gitlab/9Lukas5/unified-ticketing' -copyright: 'Copyright © 2020 Hochschule für Technik Stuttgart' +copyright: 'Copyright © 2020 University for Applied Sciences Stuttgart' use_directory_urls: false nav: - Home: - Index: 'index.md' + - Changelog: 'unified-ticketing/changelog-softlink.md' + - Usage: 'unified-ticketing/usage.md' + - Contributing: 'unified-ticketing/contributing.md' + - License: 'unified-ticketing/license-softlink.md' + - API: + - Index: 'api/index.md' + - Core: + - Logging: 'api/core/logging.md' + - Ticket: 'api/core/ticket.md' + - Ticketsystem: 'api/core/ticket-system.md' + - Exceptions: 'api/exceptions.md' + - Systems: + - GitLab: + - Ticket: 'api/systems/gitlab/ticket.md' + - Ticketsystem: 'api/systems/gitlab/ticket-system.md' + - Developers Guide: + - Machine Setup: 'developers-guide/machine-setup.md' + - Styleguide: 'developers-guide/styleguide.md' + - UML Diagram: 'developers-guide/uml.md' + - Workflow: 'developers-guide/workflow.md' theme: + features: + - navigation.tabs + icon: + logo: material/book-open + language: 'en' name: 'material' palette: - primary: 'white' - accent: 'teal' - language: 'en' - feature: - tabs: true - logo: - icon: library_books + accent: 'blue' + primary: 'red' markdown_extensions: -- admonition -- codehilite: - linenums: true -- toc: - permalink: True -- footnotes -- tables -- plantuml_markdown: - server: http://plantuml.com/plantuml - format: svg -- pymdownx.emoji: - emoji_generator: !!python/name:pymdownx.emoji.to_svg -- pymdownx.tasklist -- pymdownx.details -- pymdownx.superfences + - admonition + - attr_list + - footnotes + - markdown_del_ins + - plantuml_markdown: + format: svg + server: http://plantuml.com/plantuml + - pymdownx.details + - pymdownx.emoji: + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg + - pymdownx.highlight: + linenums: true + - pymdownx.superfences + - pymdownx.tabbed + - pymdownx.tasklist + - toc: + permalink: True + - tables diff --git a/requirements.txt b/requirements.txt index 916d0f154b4884ab7f867f308a5a54687261df49..c67bf3f3efbe9a08b2ba68f8800b1b483716c7f3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,8 @@ +certifi~=2020.11 +markdown_del_ins~=1.0 Markdown~=3.1 +mkdocs-material~=6.0 mkdocs~=1.0 -mkdocs-material~=4.0 -plantuml~=0.2 plantuml-markdown~=3.1 -pymdown-extensions~=6.2 -certifi~=2019.9 +plantuml~=0.2 +pymdown-extensions~=8.0