diff --git a/CHANGELOG.md b/CHANGELOG.md index cfa98f4782..8fc627f6f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,14 +4,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## [2.3.0] - 2020-07-23 + ### Added - Add branch link provider to access branch links in plugins ([#1243](https://github.com/scm-manager/scm-manager/pull/1243)) - Add key value input field component ([#1246](https://github.com/scm-manager/scm-manager/pull/1246)) -- Add Jexl parser ([#1251](https://github.com/scm-manager/scm-manager/pull/1251)) +- Update installed optional plugin dependencies upon plugin upgrade ([#1260](https://github.com/scm-manager/scm-manager/pull/1260)) ### Changed - Adding start delay to liveness and readiness probes in helm chart template +- Init svn repositories with trunk folder ([#1259](https://github.com/scm-manager/scm-manager/pull/1259)) +- Show line numbers in source code view by default ([#1265](https://github.com/scm-manager/scm-manager/pull/1265)) ### Fixed - Fixed file extension detection with new spotter version @@ -19,6 +22,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed error in update step ([#1237](https://github.com/scm-manager/scm-manager/issues/1237) and [#1244](https://github.com/scm-manager/scm-manager/issues/1244)) - Fix incorrect trimming of whitespaces in helm chart templates - Fixed error on empty diff expand response ([#1247](https://github.com/scm-manager/scm-manager/pull/1247)) +- Ignore ports on proxy exclusions ([#1256](https://github.com/scm-manager/scm-manager/pull/1256)) +- Invalidate branches cache synchronously on create new branch ([#1261](https://github.com/scm-manager/scm-manager/pull/1261)) ## [2.2.0] - 2020-07-03 ### Added @@ -239,3 +244,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [2.1.0]: https://www.scm-manager.org/download/2.1.0 [2.1.1]: https://www.scm-manager.org/download/2.1.1 [2.2.0]: https://www.scm-manager.org/download/2.2.0 +[2.3.0]: https://www.scm-manager.org/download/2.3.0 diff --git a/docs/de/user/group/index.md b/docs/de/user/group/index.md index 13a565e433..f8578c0d0b 100644 --- a/docs/de/user/group/index.md +++ b/docs/de/user/group/index.md @@ -12,7 +12,7 @@ Der Bereich Gruppen umfasst alles, was auf einen Zusammenschluss mehrerer Anwend Um nicht jeden Benutzer einzeln berechtigen zu müssen, gibt es im SCM-Manager die Möglichkeit Gruppen anzulegen. Diese Gruppen können mit Berechtigungen ausgestattet werden und können beliebig viele Benutzer enthalten. ### Übersicht -Die Gruppenübersicht zeigt eine Liste der existierenden Gruppen an. Die Gruppen werden dabei nach internen Gruppen und externen Gruppen unterschieden. Interne Gruppen werden in der Übersicht durch das Haus-Symbol kenntlich gemacht und sind Gruppen, die im SCM-Manager erstellt wurden. Externe Gruppen wiederum haben das Planeten-Symbol und sind Gruppen, dessen Mitglieder von externen Quellen wie beispielsweise einer LDAP-Instanz verwaltet werden. +Die Gruppenübersicht zeigt eine Liste der existierenden Gruppen an. Die Gruppen werden dabei nach internen Gruppen und externen Gruppen unterschieden. Interne Gruppen werden in der Übersicht durch das Haus-Symbol kenntlich gemacht und sind Gruppen, die im SCM-Manager erstellt wurden. Externe Gruppen wiederum haben das Planeten-Symbol und sind Gruppen, dessen Mitglieder von [externen Quellen](./external.md) wie beispielsweise einer LDAP-Instanz verwaltet werden. ![Gruppen Übersicht](assets/groups-overview.png) diff --git a/docs/de/user/repo/assets/repository-code-changesetDetails.png b/docs/de/user/repo/assets/repository-code-changesetDetails.png index 41fc42ffee..f576e0736a 100644 Binary files a/docs/de/user/repo/assets/repository-code-changesetDetails.png and b/docs/de/user/repo/assets/repository-code-changesetDetails.png differ diff --git a/docs/de/user/repo/assets/repository-code-fileAnnotate.png b/docs/de/user/repo/assets/repository-code-fileAnnotate.png new file mode 100644 index 0000000000..1d6f202e9b Binary files /dev/null and b/docs/de/user/repo/assets/repository-code-fileAnnotate.png differ diff --git a/docs/de/user/repo/assets/repository-code-fileHistory.png b/docs/de/user/repo/assets/repository-code-fileHistory.png index 3c6b21d1e9..120d83d7f3 100644 Binary files a/docs/de/user/repo/assets/repository-code-fileHistory.png and b/docs/de/user/repo/assets/repository-code-fileHistory.png differ diff --git a/docs/de/user/repo/assets/repository-code-fileViewer.png b/docs/de/user/repo/assets/repository-code-fileViewer.png index f141c07920..4afa726c01 100644 Binary files a/docs/de/user/repo/assets/repository-code-fileViewer.png and b/docs/de/user/repo/assets/repository-code-fileViewer.png differ diff --git a/docs/de/user/repo/assets/repository-settings-general-git.png b/docs/de/user/repo/assets/repository-settings-general-git.png index 697562a126..3047de709c 100644 Binary files a/docs/de/user/repo/assets/repository-settings-general-git.png and b/docs/de/user/repo/assets/repository-settings-general-git.png differ diff --git a/docs/de/user/repo/code.md b/docs/de/user/repo/code.md index 7a2f5ed3df..9ec3f29938 100644 --- a/docs/de/user/repo/code.md +++ b/docs/de/user/repo/code.md @@ -22,7 +22,13 @@ Die Übersicht der Changesets/Commits zeigt die Änderungshistorie je Branch an. ![Repository-Code-Changesets](assets/repository-code-changesetsView.png) ### Changeset Details -Auf der Detailseite eines Changesets sieht man zusätzlich zu den Metadaten des Changesets sämtliche Änderungen, die in diesem Changeset enthalten sind. Die Diffs werden dabei im bekannten Format je Datei inklusive Syntax-Highlighting angezeigt. +Auf der Detailseite eines Changesets sieht man zusätzlich zu den Metadaten (z. B. Mitwirkende und Parent-Changeset) des Changesets sämtliche Änderungen, die in diesem Changeset enthalten sind. +Die Mitwirkenden können zu einer detaillierten Tabelle aufklappt werden und enthalten den Autor, die Co-Autoren, den Committer und den Signierer des Changesets. +Die Diffs werden dabei im bekannten Format je Datei inklusive Syntax-Highlighting angezeigt. +Die Diffs können durch Klicken auf den blauen Balken schrittweise oder vollständig erweitert werden. + +Falls sich Commit Links im Format "namespace/name@commitId" in der Changeset Beschreibung befinden, werden die zu relativen SCM-Manager Links erweitert. +Beispielsweise wird der Text hitchhiker/HeartOfGold@1a2b3c4 zu einem Link zu dem Commit 1a2b3c4 im Repository hitchhiker/HeartOfGold umgewandelt. ![Repository-Code-Changesets](assets/repository-code-changesetDetails.png) @@ -30,12 +36,17 @@ Auf der Detailseite eines Changesets sieht man zusätzlich zu den Metadaten des Nach einem Klick auf eine Datei in den Sources landet man in der Detailansicht der Datei. Dabei sind je nach Dateiformat unterschiedliche Ansichten zu sehen: - Bild-Datei: Bild wird gerendert angezeigt. -- Markdown-Datei: Markdown wird gerendert dargestellt. Die Ansicht kann auf eine nicht gerenderte Textansicht umgeschaltet werden. +- Markdown-Datei: Markdown wird gerendert dargestellt. Die Ansicht kann auf eine nicht gerenderte Textansicht umgeschaltet werden. Im gerenderten Markdown können ebenfalls Commit Links wie bei den Changeset Details verwendet werden. - Text-basierte Datei: Der Text wird angezeigt. Falls verfügbar mit Syntax-Highlighting. - Nicht unterstützte Formate: Ein Download-Button wird angezeigt. ![Repository-Code-FileDetails](assets/repository-code-fileViewer.png) +### Datei Annotate +Ergänzt jede Codezeile mit entsprechenden Informationen, wann und von welchem Autor diese zuletzt geändert wurde. Mit einem Hover auf der linken Seite erscheint ein Popover mit Changeset und weiteren Informationen. + +![Repository-Code-FileAnnotate](assets/repository-code-fileAnnotate.png) + ### Datei Historie Bei der Datei Details Ansicht kann man über einen Switch oben rechts auf die Historien-Ansicht wechseln. Dort werden die Commits aufgelistet, die diese Datei verändert haben. diff --git a/docs/de/user/repo/index.md b/docs/de/user/repo/index.md index 1b240f6a6e..e1d0b554a3 100644 --- a/docs/de/user/repo/index.md +++ b/docs/de/user/repo/index.md @@ -29,7 +29,8 @@ Icon | Beschreibung ### Repository erstellen Im SCM-Manager können neue Git, Mercurial & Subersion (SVN) Repositories über ein Formular angelegt werden. Dieses kann über den Button "Repository erstellen" aufgerufen werden. Dabei muss ein gültiger Name eingetragen und der Repository-Typ bestimmt werden. -Optional kann man das Repository beim Erstellen direkt initialisieren. Damit werden für Git und Mercurial jeweils der Standard-Branch (master bzw. default) angelegt. Außerdem wird ein initialer Commit ausgeführt, der eine README.md erzeugt. +Optional kann man das Repository beim Erstellen direkt initialisieren. Damit werden für Git und Mercurial jeweils der Standard-Branch (master bzw. default) angelegt. Außerdem wird ein initialer Commit ausgeführt, der eine README.md erzeugt. +Für Subversion Repositories wird die README.md in einen Ordner `trunk` abgelegt. Ist die Namespace-Strategie auf "Benutzerdefiniert" eingestellt, muss noch ein Namespace eingetragen werden. diff --git a/docs/de/user/repo/settings.md b/docs/de/user/repo/settings.md index 14cd4d5305..e7f87b241f 100644 --- a/docs/de/user/repo/settings.md +++ b/docs/de/user/repo/settings.md @@ -7,7 +7,7 @@ Unter den Repository Einstellungen befinden sich zwei Einträge. Wenn weitere Pl ### Generell Unter dem Eintrag "Generell" kann man die Zusatzinformationen zum Repository editieren. Da es sich im Beispiel um ein Git Repository handelt, kann ebenfalls der Standard-Branch für dieses Repository gesetzt werden. Der Standard-Branch sorgt dafür, dass beim Arbeiten mit diesem Repository dieser Branch vorrangig geöffnet wird, falls kein expliziter Branch ausgewählt wurde. -Über den Button unten auf dieser Seite besteht noch die Möglichkeit dieses Repository aus dem SCM-Manager zu löschen. Dieser Vorgang kann nicht rückgängig gemacht werden. +Innerhalb der Gefahrenzone unten auf der Seite gibt es mit entsprechenden Rechten die Möglichkeit das Repository umzubenennen oder zu löschen. Wenn in der globalen SCM-Manager Konfiguration die Namespace Strategie `benutzerdefiniert` ausgewählt ist, kann zusätzlich zum Repository Namen auch der Namespace umbenannt werden. ![Repository-Settings-General-Git](assets/repository-settings-general-git.png) diff --git a/docs/en/administration/reverse-proxies.md b/docs/en/administration/reverse-proxies.md index 57bf4e5ec0..11d5e60c71 100644 --- a/docs/en/administration/reverse-proxies.md +++ b/docs/en/administration/reverse-proxies.md @@ -4,62 +4,69 @@ subtitle: How to use SCM-Manager with common reverse proxies displayToc: true --- -TODO reverse proxies in general send X-Forwarded headers ... +SCM-Manager can run behind any reverse proxy, but a few rules must be respected. +The reverse proxy should not encode slashes and the `X-Forwarded-For` and `X-Forwarded-Host` headers must be send to SCM-Manager. +If the proxy uses a different protocol as the SCM-Manager e.g. https on proxy and http on scm-manager, the `X-Forwarded-Proto` header must be send too. -### nginx +## nginx -TODO ... +```nginx +# set required forward headers +proxy_set_header X-Forwarded-Host $host:$server_port; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +# if https is used make sure X-Forwarded-Proto header is send +proxy_set_header X-Forwarded-Proto $scheme; -### Apache +# assuming scm-manager is running on localhost at port 8080 +location /scm { + proxy_pass http://scm:8080; +} +``` - +## Apache -```apache -ProxyPass /scm http://localhost:8080/scm +```apacheconf +# Ensure mod_proxy and mod_proxy_http modules are loaded +LoadModule proxy_module modules/mod_proxy.so +LoadModule proxy_http_module modules/mod_proxy_http.so + +# avoid encoding of slashes +AllowEncodedSlashes NoDecode + +# if https is used, make sure X-Forwarded-Proto is send +RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME} +RequestHeader set "X-Forwarded-SSL" expr=%{HTTPS} + +# assuming scm-manager is running on localhost at port 8080 +ProxyPass /scm http://localhost:8080/scm nocanon ProxyPassReverse /scm http://localhost:8080/scm -ProxyPassReverse /scm http://servername:8080/scm +ProxyPassReverse /scm http://localhost:8080/scm + - Order allow,deny - Allow from all + Order allow,deny + Allow from all ``` -- **Warning**: Setting ProxyPassReverseCookiePath would most likely cause problems with session handling! -- **Note**: If you encounter timeout problems, please have a look at [Apache Module mod_proxy#Workers](http://httpd.apache.org/docs/current/mod/mod_proxy.html#workers). -### HA-Proxy +### Notes -TODO ... +* Setting ProxyPassReverseCookiePath would most likely cause problems with session handling! +* If you encounter timeout problems, please have a look at [Apache Module mod_proxy#Workers](http://httpd.apache.org/docs/current/mod/mod_proxy.html#workers). -### SCM-Server conf/server-config.xml +## HAProxy - - -NOTE: This file is found in the installation directory, not the user\'s -home directory. - -Uncomment following line: -```xml -true -``` - -Example: -```xml - - - - - - - - - - - true - - - +```apacheconf +backend scm + # use http as proxy protocol + mode http + # sets X-Forwarded-For header + option forwardfor + # check if scm is running + option httpchk GET /scm/api/v2 + # assuming scm-manager is running on localhost at port 8080 + server dcscm1 localhost:8080 check + # sets X-Forwarded-Host header + http-request set-header X-Forwarded-Host %[req.hdr(Host)] + # sets X-Forwarded-Proto to https if ssl is enabled + http-request set-header X-Forwarded-Proto https if { ssl_fc } ``` diff --git a/docs/en/administration/scm-server-ssl.md b/docs/en/administration/scm-server-ssl.md deleted file mode 100644 index 71debe72c6..0000000000 --- a/docs/en/administration/scm-server-ssl.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: SCM-Server SSL ---- - - - -**Note**: This document describes a ssl configuration with a - self-signed certificate - -1\. Open a shell and go to the conf directory of the scm-server - -2\. Create a certificate request. Replace all variables (\*varname\*) - -```bash -$ keytool -genkey -alias scm -keyalg RSA -keystore keystore.jks - -Enter keystore password: your password -Re-enter new password: your password -What is your first and last name? - [Unknown]: *your servername* -What is the name of your organizational unit? - [Unknown]: *organisation unit* -What is the name of your organization? - [Unknown]: *organisation* -What is the name of your City or Locality? - [Unknown]: *city* -What is the name of your State or Province? - [Unknown]: *state* -What is the two-letter country code for this unit? - [Unknown]: *country code* -Is CN=your servername, OU=your organisation unit, O=your organisation, L=your city, ST=your state, C=cc correct? - [no]: yes - -Enter key password for - (RETURN if same as keystore password): *password* -Re-enter new password: *password* -``` - -**Note**: You have to enter the full qualified hostname of your - server for the cn (cn = What is your first and last name?) - -3\. Edit the server-config.xml, uncomment the SSL-Connector and set your -password. For example: - -```xml - - - - - - - - - SSLv2Hello - SSLv3 - - - - - 8181 - 30000 - /conf/keystore.jks - *password* - *password* - /conf/keystore.jks - *password* - - - -``` - -4\. Start or restart the scm-server - -**Note**: It looks like there is a error in some version of - OpenJDK (issues \#84 and \#151). If you have such a problem, - please try to use the Oracle JDK. - -### Configure Git - -1\. Export the certificate from keystore: - -```bash -$ keytool -exportcert -keystore keystore.jks -alias scm -rfc -file cert.pem -``` - -2\. Copy the certificate to your client and add it to your git config: - -```bash -$ git config http.sslCAInfo /complete/path/to/cert.pem -``` - -### Configure Mercurial - -1\. Export the certificate from keystore: - -```bash -$ keytool -exportcert -keystore keystore.jks -alias scm -rfc -file cert.pem -``` - -2\. Copy the certificate to your client and add it to your .hgrc config -file: - -```bash -[web] -cacerts = /complete/path/to/cert.pem -``` - -### Sources - -- [Keytool](http://download.oracle.com/javase/1.4.2/docs/tooldocs/windows/keytool.html) -- [Jetty SSL-Connectors](http://wiki.eclipse.org/Jetty/Reference/SSL_Connectors) diff --git a/docs/en/administration/scm-server.md b/docs/en/administration/scm-server.md new file mode 100644 index 0000000000..fb382e03f2 --- /dev/null +++ b/docs/en/administration/scm-server.md @@ -0,0 +1,183 @@ +--- +title: SCM-Server Configuration +subtitle: Various configuration options for the SCM-Server +displayToc: true +--- + +## Https + +In order to use https with scm-server, you need a keystore with a certificate and the corresponding secret key. +In the following we will use `openssl` to create a self signed certificate for demonstration purposes. + +### Create self signed certificate + +**Warning**: Do not use self signed certificates in production, this is only for demonstration purposes. + +```bash +openssl req -new -x509 -newkey rsa:2048 -sha256 -keyout tls.key -out tls.crt +``` + +This command will ask a few questions about metadata for generated certificate: + +* PEM pass phrase: This is a password to protect the scret key +* Country Name (2 letter code) +* State or Province Name (full name) +* Locality Name (eg, city) +* Organization Name (eg, company) +* Organizational Unit Name (eg, section) +* Common Name (eg, fully qualified host name) +* Email Address + +Make sure that the common name matches the fqdn, which you are using to access SCM-Manager. + +#### Browsers + +In order to use a self signed certificate the certificate must be imported into you browser. + +#### Configure Git + +To use git with a self signed certificate, we have to add the certificate path to the configuration. + +```bash +git config http.sslCAInfo /complete/path/to/tls.crt +``` + +#### Configure Mercurial + +To use mercurial with a self signed certificate, we have to add the certificate path to the configuration. + +```ini +[web] +cacerts = /complete/path/to/cert.pem +``` + +### Create keystore + +Create a keystore in pkcs12 format. +This command can be used with the self signed certificate from above or with a valid certificate from an authority. + +```bash +openssl pkcs12 -inkey tls.key -in tls.crt -export -out keystore.pkcs12 +``` + +If your secret key is protected with a pass phrase, you have to enter it first. +Than you have to enter an export password to protect your keystore. + +### Server configuration + +Add the following snippet at the end of your `server-config.xml`, be sure it is inside the `Configure` tag: + +```xml + + + + + + /conf/keystore.pkcs12 + + + PKCS12 + + secret + + + + + + + TLSv1.2 + TLSv1.3 + + + + + + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + http/1.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +The snipped above assumes your keystore is in the pkcs12 format and is stored at `conf/keystore.pkcs12` with the password `secret`. +You have to tweek this settings to match your setup. +After modifying your `server-config.xml`, you have to **restart** your SCM-Manager instance. +Now SCM-Manager should open a second port with **https** (in the example above **8443**). diff --git a/docs/en/navigation.yml b/docs/en/navigation.yml index 55d9971267..e696c98bc6 100644 --- a/docs/en/navigation.yml +++ b/docs/en/navigation.yml @@ -16,7 +16,7 @@ entries: - /administration/basedirectory/ - /administration/logging/ - - /administration/scm-server-ssl/ + - /administration/scm-server/ - /administration/reverse-proxies/ - section: Development diff --git a/docs/en/user/group/index.md b/docs/en/user/group/index.md index 7eda34d067..511f7e143f 100644 --- a/docs/en/user/group/index.md +++ b/docs/en/user/group/index.md @@ -10,7 +10,7 @@ The group area includes everything that can be broken down into a group of sever It is possible to create groups in SCM-Manager to not authorize each user individually. Groups can be authorized and can contain an unlimited number of users. ### Overview -The groups overview shows a list of all groups that are existing. Groups are distinguished between internal and external groups. Internal groups are groups that were created in SCM-Manager and are indicated by a house icon. External groups were created by external sources like a connected LDAP instance and have a world icon. +The groups overview shows a list of all groups that are existing. Groups are distinguished between internal and external groups. Internal groups are groups that were created in SCM-Manager and are indicated by a house icon. External groups were created for [external sources](./external.md) like a connected LDAP instance and have a world icon. ![Groups Overview](assets/groups-overview.png) diff --git a/docs/en/user/repo/assets/repository-code-changesetDetails.png b/docs/en/user/repo/assets/repository-code-changesetDetails.png index 056062eb96..c157813470 100644 Binary files a/docs/en/user/repo/assets/repository-code-changesetDetails.png and b/docs/en/user/repo/assets/repository-code-changesetDetails.png differ diff --git a/docs/en/user/repo/assets/repository-code-fileAnnotate.png b/docs/en/user/repo/assets/repository-code-fileAnnotate.png new file mode 100644 index 0000000000..932cac778c Binary files /dev/null and b/docs/en/user/repo/assets/repository-code-fileAnnotate.png differ diff --git a/docs/en/user/repo/assets/repository-code-fileHistory.png b/docs/en/user/repo/assets/repository-code-fileHistory.png index d386c8291a..4260af9e39 100644 Binary files a/docs/en/user/repo/assets/repository-code-fileHistory.png and b/docs/en/user/repo/assets/repository-code-fileHistory.png differ diff --git a/docs/en/user/repo/assets/repository-code-fileViewer.png b/docs/en/user/repo/assets/repository-code-fileViewer.png index 622e7b0045..c484b2e962 100644 Binary files a/docs/en/user/repo/assets/repository-code-fileViewer.png and b/docs/en/user/repo/assets/repository-code-fileViewer.png differ diff --git a/docs/en/user/repo/assets/repository-settings-general-git.png b/docs/en/user/repo/assets/repository-settings-general-git.png index 422392f892..2a0f5258da 100644 Binary files a/docs/en/user/repo/assets/repository-settings-general-git.png and b/docs/en/user/repo/assets/repository-settings-general-git.png differ diff --git a/docs/en/user/repo/code.md b/docs/en/user/repo/code.md index 0f28634da8..b0a8995c88 100644 --- a/docs/en/user/repo/code.md +++ b/docs/en/user/repo/code.md @@ -22,7 +22,14 @@ The Sources button leads to the sources overview that shows the state from after ![Repository-Code-Changesets](assets/repository-code-changesetsView.png) ### Changeset Details -The details page of a changeset shows the metadata and all changes that are part of the changeset. The diffs are presented in the well-known format per file with syntax highlighting. +The details page of a changeset shows the metadata (like contributors and the parent changeset) and all changes that are part of the changeset. +The contributors consist of the authors, co-authors, the committer and the signer. +The diffs are presented in the well-known format per file with syntax highlighting. +You can expand the diffs gradually or completely by clicking on the blue bars. + +If commit links formatted like "namespace/name@commitId" are used in the changeset description they will be rendered to internal links. +For example the text hitchhiker/HeartOfGold@1a2b3c4 will be transformed to a link directing to the commit 1a2b3c4 of the repository hitchhiker/heartOfGold. + ![Repository-Code-Changesets](assets/repository-code-changesetDetails.png) @@ -30,12 +37,17 @@ The details page of a changeset shows the metadata and all changes that are part After clicking on a file in the sources, the details of the file are shown. Depending on the format of the file, there are different views: - Image file: The rendered image is shown. -- Markdown file: The rendered markdown is shown. The view can also be changed to a text view that is not rendered. +- Markdown file: The rendered markdown is shown. The view can also be changed to a text view that is not rendered. The commit links will also be rendered like in the changeset details view. - Text based file: The content is shown. If available with syntax highlighting. - Unsupported formats: A download button is shown. ![Repository-Code-FileDetails](assets/repository-code-fileViewer.png) +### File Annotate +Supplements each line of code with the relevant information when and by which author it was last modified. With a hover on the left side a popover with changeset and further information appears. + +![Repository-Code-FileAnnotate](assets/repository-code-fileAnnotate.png) + ### File History In the detailed file view there is a switch button in the upper right corner which allows to switch to the history view. The history shows all commits that changed the file. diff --git a/docs/en/user/repo/index.md b/docs/en/user/repo/index.md index 40738ee3ae..f1569cffa4 100644 --- a/docs/en/user/repo/index.md +++ b/docs/en/user/repo/index.md @@ -27,7 +27,8 @@ Icon | Description ### Create a Repository In SCM-Manager new Git, Mercurial & Subversion (SVN) repositories can be created via a form that can be accessed via the "Create Repository" button. A valid name and the repository type are mandatory. -Optionally, repositories can be initialized during the creation. That creates a standard branch (master or default) for Git and Mercurial repositories. Additionally, it performs a commit that creates a README.md. +Optionally, repositories can be initialized during the creation. That creates a standard branch (master or default) for Git and Mercurial repositories. +Additionally, it performs a commit that creates a README.md. For Subversion repositories the README.md will be created in a directory named `trunk`. If the namespace strategy is set to custom, the namespace field is also mandatory. diff --git a/docs/en/user/repo/settings.md b/docs/en/user/repo/settings.md index ae92b5da33..19d82f45d2 100644 --- a/docs/en/user/repo/settings.md +++ b/docs/en/user/repo/settings.md @@ -7,7 +7,7 @@ By default, there are two items in the repository settings. Depending on additio ### General The "General" item allows you to edit the additional information of the repository. Git repositories for example also have the option to change the default branch here. The default branch is the one that is used when working with the repository if no specific branch is selected. -At the bottom of this screen is also a button to delete the repository from SCM-Manager. The deletion is irreversible. +In the danger zone at the bottom you may rename the repository or delete it. If the namespace strategy in the global SCM-Manager config is set to `custom` you may even rename the repository namespace. ![Repository-Settings-General-Git](assets/repository-settings-general-git.png) diff --git a/lerna.json b/lerna.json index 5111fd0b7a..dd2664e01c 100644 --- a/lerna.json +++ b/lerna.json @@ -5,5 +5,5 @@ ], "npmClient": "yarn", "useWorkspaces": true, - "version": "2.3.0-SNAPSHOT" + "version": "2.3.0" } diff --git a/pom.xml b/pom.xml index f7eff5138d..c14dd7a276 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ sonia.scm scm pom - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT The easiest way to share your Git, Mercurial and Subversion repositories. @@ -580,7 +580,7 @@ sonia.scm.maven smp-maven-plugin - 1.0.0 + 1.1.0 @@ -915,7 +915,7 @@ 2.1.1 4.5.5.Final 1.19.4 - 2.11.0 + 2.11.1 4.2.3 2.3.3 6.1.5.Final diff --git a/scm-annotation-processor/pom.xml b/scm-annotation-processor/pom.xml index 0c8aabacbb..30599bb27e 100644 --- a/scm-annotation-processor/pom.xml +++ b/scm-annotation-processor/pom.xml @@ -31,12 +31,12 @@ sonia.scm scm - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT sonia.scm scm-annotation-processor - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-annotation-processor @@ -46,7 +46,7 @@ sonia.scm scm-annotations - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT diff --git a/scm-annotations/pom.xml b/scm-annotations/pom.xml index 07fcc7138a..45cc5aea7f 100644 --- a/scm-annotations/pom.xml +++ b/scm-annotations/pom.xml @@ -31,11 +31,11 @@ sonia.scm scm - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-annotations - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-annotations diff --git a/scm-core/pom.xml b/scm-core/pom.xml index 1cadd49ae7..9d4f7e388f 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -31,11 +31,11 @@ scm sonia.scm - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-core - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-core @@ -54,7 +54,7 @@ sonia.scm scm-annotations - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT @@ -222,28 +222,12 @@ 2.6 - - org.apache.commons - commons-jexl - 2.1.1 - - - commons-logging - commons-logging - - - org.slf4j - jcl-over-slf4j - - - - sonia.scm scm-annotation-processor - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT provided diff --git a/scm-core/src/main/java/sonia/scm/net/Proxies.java b/scm-core/src/main/java/sonia/scm/net/Proxies.java index abafb75623..a2d60eb9ca 100644 --- a/scm-core/src/main/java/sonia/scm/net/Proxies.java +++ b/scm-core/src/main/java/sonia/scm/net/Proxies.java @@ -91,6 +91,13 @@ public final class Proxies url = url.substring(0, index); } + index = url.indexOf(':'); + + if (index > 0) + { + url = url.substring(0, index); + } + for (String exclude : configuration.getProxyExcludes()) { if (GlobUtil.matches(exclude, url)) diff --git a/scm-core/src/main/java/sonia/scm/plugin/AvailablePluginDescriptor.java b/scm-core/src/main/java/sonia/scm/plugin/AvailablePluginDescriptor.java index f8dd2d1a71..e251753113 100644 --- a/scm-core/src/main/java/sonia/scm/plugin/AvailablePluginDescriptor.java +++ b/scm-core/src/main/java/sonia/scm/plugin/AvailablePluginDescriptor.java @@ -21,12 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + package sonia.scm.plugin; import java.util.Optional; import java.util.Set; +import static java.util.Collections.emptySet; + /** * @since 2.0.0 */ @@ -35,13 +37,23 @@ public class AvailablePluginDescriptor implements PluginDescriptor { private final PluginInformation information; private final PluginCondition condition; private final Set dependencies; + private final Set optionalDependencies; private final String url; private final String checksum; + /** + * @deprecated Use {@link #AvailablePluginDescriptor(PluginInformation, PluginCondition, Set, Set, String, String)} instead + */ + @Deprecated public AvailablePluginDescriptor(PluginInformation information, PluginCondition condition, Set dependencies, String url, String checksum) { + this(information, condition, dependencies, emptySet(), url, checksum); + } + + public AvailablePluginDescriptor(PluginInformation information, PluginCondition condition, Set dependencies, Set optionalDependencies, String url, String checksum) { this.information = information; this.condition = condition; this.dependencies = dependencies; + this.optionalDependencies = optionalDependencies; this.url = url; this.checksum = checksum; } @@ -68,4 +80,9 @@ public class AvailablePluginDescriptor implements PluginDescriptor { public Set getDependencies() { return dependencies; } + + @Override + public Set getOptionalDependencies() { + return optionalDependencies; + } } diff --git a/scm-core/src/main/java/sonia/scm/plugin/InstalledPluginDescriptor.java b/scm-core/src/main/java/sonia/scm/plugin/InstalledPluginDescriptor.java index 916c8691d9..faedb2a6f5 100644 --- a/scm-core/src/main/java/sonia/scm/plugin/InstalledPluginDescriptor.java +++ b/scm-core/src/main/java/sonia/scm/plugin/InstalledPluginDescriptor.java @@ -191,6 +191,7 @@ public final class InstalledPluginDescriptor extends ScmModule implements Plugin * * @since 2.0.0 */ + @Override public Set getOptionalDependencies() { if (optionalDependencies == null) { diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginDescriptor.java b/scm-core/src/main/java/sonia/scm/plugin/PluginDescriptor.java index b93f3b0798..76d2fd2cdb 100644 --- a/scm-core/src/main/java/sonia/scm/plugin/PluginDescriptor.java +++ b/scm-core/src/main/java/sonia/scm/plugin/PluginDescriptor.java @@ -21,11 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + package sonia.scm.plugin; import java.util.Set; +import static java.util.Collections.emptySet; + public interface PluginDescriptor { PluginInformation getInformation(); @@ -34,4 +36,8 @@ public interface PluginDescriptor { Set getDependencies(); + default Set getOptionalDependencies() { + return emptySet(); + } + } diff --git a/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedPerson.java b/scm-core/src/main/java/sonia/scm/repository/BranchCreatedEvent.java similarity index 75% rename from scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedPerson.java rename to scm-core/src/main/java/sonia/scm/repository/BranchCreatedEvent.java index c5ede4cdfa..e7f5fdb364 100644 --- a/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedPerson.java +++ b/scm-core/src/main/java/sonia/scm/repository/BranchCreatedEvent.java @@ -21,23 +21,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package sonia.scm.web.data; -import sonia.scm.repository.Person; +package sonia.scm.repository; -public final class ImmutableEncodedPerson { +import lombok.Value; +import sonia.scm.event.Event; - private final Person person; - - public ImmutableEncodedPerson(Person person) { - this.person = person; - } - - public String getMail() { - return Encoder.encode(person.getMail()); - } - - public String getName() { - return Encoder.encode(person.getName()); - } +/** + * This event is fired when a new branch was created from SCM-Manager. + * Warning: This event will not be fired if a new branch was pushed. + * @since 2.3.0 + */ +@Event +@Value +public class BranchCreatedEvent { + private Repository repository; + private String branchName; } diff --git a/scm-core/src/main/java/sonia/scm/repository/api/ModifyCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/ModifyCommandBuilder.java index 1035ccf009..3067d7a054 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/ModifyCommandBuilder.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/ModifyCommandBuilder.java @@ -175,6 +175,11 @@ public class ModifyCommandBuilder { return this; } + public ModifyCommandBuilder useDefaultPath(boolean useDefaultPath) { + request.setDefaultPath(useDefaultPath); + return this; + } + public interface ContentLoader { /** * Specify the data of the file using a {@link ByteSource}. diff --git a/scm-core/src/main/java/sonia/scm/repository/api/RepositoryServiceFactory.java b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryServiceFactory.java index 60b11162d1..31ca9ca15d 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/RepositoryServiceFactory.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryServiceFactory.java @@ -42,6 +42,7 @@ import sonia.scm.cache.Cache; import sonia.scm.cache.CacheManager; import sonia.scm.config.ScmConfiguration; import sonia.scm.event.ScmEventBus; +import sonia.scm.repository.BranchCreatedEvent; import sonia.scm.repository.ClearRepositoryCacheEvent; import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.PostReceiveRepositoryHookEvent; @@ -287,6 +288,7 @@ public final class RepositoryServiceFactory { private final Set> caches = Sets.newHashSet(); + private final CacheManager cacheManager; /** * Constructs a new instance and collect all repository relevant @@ -296,6 +298,7 @@ public final class RepositoryServiceFactory */ public CacheClearHook(CacheManager cacheManager) { + this.cacheManager = cacheManager; this.caches.add(cacheManager.getCache(BlameCommandBuilder.CACHE_NAME)); this.caches.add(cacheManager.getCache(BrowseCommandBuilder.CACHE_NAME)); this.caches.add(cacheManager.getCache(LogCommandBuilder.CACHE_NAME)); @@ -347,7 +350,14 @@ public final class RepositoryServiceFactory } } - @SuppressWarnings("unchecked") + @Subscribe(async = false) + @SuppressWarnings({"unchecked", "java:S3740", "rawtypes"}) + public void onEvent(BranchCreatedEvent event) { + RepositoryCacheKeyPredicate predicate = new RepositoryCacheKeyPredicate(event.getRepository().getId()); + cacheManager.getCache(BranchesCommandBuilder.CACHE_NAME).removeAll(predicate); + } + + @SuppressWarnings({"unchecked", "java:S3740", "rawtypes"}) private void clearCaches(final String repositoryId) { if (logger.isDebugEnabled()) diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommandRequest.java b/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommandRequest.java index 0e5d794440..8f077430df 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommandRequest.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommandRequest.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + package sonia.scm.repository.spi; import org.apache.commons.lang.StringUtils; @@ -48,6 +48,7 @@ public class ModifyCommandRequest implements Resetable, Validateable, CommandWit private String commitMessage; private String branch; private String expectedRevision; + private boolean defaultPath; @Override public void reset() { @@ -55,6 +56,7 @@ public class ModifyCommandRequest implements Resetable, Validateable, CommandWit author = null; commitMessage = null; branch = null; + defaultPath = false; } public void addRequest(PartialRequest request) { @@ -93,6 +95,10 @@ public class ModifyCommandRequest implements Resetable, Validateable, CommandWit return expectedRevision; } + public boolean isDefaultPath() { + return defaultPath; + } + @Override public boolean isValid() { return StringUtils.isNotEmpty(commitMessage) && !requests.isEmpty(); @@ -102,6 +108,10 @@ public class ModifyCommandRequest implements Resetable, Validateable, CommandWit this.expectedRevision = expectedRevision; } + public void setDefaultPath(boolean defaultPath) { + this.defaultPath = defaultPath; + } + public interface PartialRequest { void execute(ModifyCommand.Worker worker) throws IOException; } diff --git a/scm-core/src/main/java/sonia/scm/util/JexlUrlExpression.java b/scm-core/src/main/java/sonia/scm/util/JexlUrlExpression.java deleted file mode 100644 index a6b8742cc3..0000000000 --- a/scm-core/src/main/java/sonia/scm/util/JexlUrlExpression.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020-present Cloudogu GmbH and Contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package sonia.scm.util; - -import org.apache.commons.jexl2.MapContext; -import org.apache.commons.jexl2.UnifiedJEXL.Expression; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Map; - -public class JexlUrlExpression { - - private static final Logger logger = LoggerFactory.getLogger(JexlUrlExpression.class); - - private final Expression expression; - - public JexlUrlExpression(Expression expression) { - this.expression = expression; - } - - public String evaluate(Map environment) { - String url = Util.EMPTY_STRING; - Object result = expression.evaluate(new MapContext(environment)); - - if (result != null) { - url = result.toString(); - } - - logger.trace("result of expression evaluation: {}", url); - - return url; - } -} diff --git a/scm-core/src/main/java/sonia/scm/util/JexlUrlParser.java b/scm-core/src/main/java/sonia/scm/util/JexlUrlParser.java deleted file mode 100644 index c4657450ea..0000000000 --- a/scm-core/src/main/java/sonia/scm/util/JexlUrlParser.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020-present Cloudogu GmbH and Contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package sonia.scm.util; - -import org.apache.commons.jexl2.JexlEngine; -import org.apache.commons.jexl2.UnifiedJEXL; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class JexlUrlParser { - - private static final Logger logger = LoggerFactory.getLogger(JexlUrlParser.class); - private final UnifiedJEXL uel = new UnifiedJEXL(new JexlEngine()); - - public JexlUrlExpression parse(String urlPattern) { - logger.trace("try to parse url pattern: {}", urlPattern); - return new JexlUrlExpression(uel.parse(urlPattern)); - } -} diff --git a/scm-core/src/main/java/sonia/scm/web/data/EncodedStringList.java b/scm-core/src/main/java/sonia/scm/web/data/EncodedStringList.java deleted file mode 100644 index 9f652dd65c..0000000000 --- a/scm-core/src/main/java/sonia/scm/web/data/EncodedStringList.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020-present Cloudogu GmbH and Contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package sonia.scm.web.data; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.google.common.base.Joiner; - -import java.util.List; - -public final class EncodedStringList { - private final List list; - - public EncodedStringList(List list) { - this.list = list; - } - - @Override - public String toString() { - return Joiner.on(',').join(Encoder.encode(list)); - } - - public List getList() { - return list; - } -} diff --git a/scm-core/src/main/java/sonia/scm/web/data/Encoder.java b/scm-core/src/main/java/sonia/scm/web/data/Encoder.java deleted file mode 100644 index d69bfc31a8..0000000000 --- a/scm-core/src/main/java/sonia/scm/web/data/Encoder.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020-present Cloudogu GmbH and Contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package sonia.scm.web.data; - -import com.google.common.collect.Lists; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.List; - -public final class Encoder { - - private static final String ENCODING = "UTF-8"; - private static final Logger logger = LoggerFactory.getLogger(Encoder.class); - - private Encoder() { - } - - public static String encode(String value) { - if (value != null) { - try { - value = URLEncoder.encode(value, ENCODING); - } catch (UnsupportedEncodingException ex) { - logger.error("encoding is not supported", ex); - } - - } - - return value; - } - - public static List encode(List values) { - return Lists.transform(values, Encoder::encode); - } -} diff --git a/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedChangeset.java b/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedChangeset.java deleted file mode 100644 index d074ade672..0000000000 --- a/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedChangeset.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020-present Cloudogu GmbH and Contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package sonia.scm.web.data; - -//~--- non-JDK imports -------------------------------------------------------- - -import sonia.scm.repository.Changeset; - -public final class ImmutableEncodedChangeset { - - private final Changeset changeset; - - public ImmutableEncodedChangeset(Changeset changeset) { - this.changeset = changeset; - } - - public ImmutableEncodedPerson getAuthor() { - return new ImmutableEncodedPerson(changeset.getAuthor()); - } - - public EncodedStringList getBranches() { - return new EncodedStringList(changeset.getBranches()); - } - - public Long getDate() { - return changeset.getDate(); - } - - public String getDescription() { - return Encoder.encode(changeset.getDescription()); - } - - public String getId() { - return changeset.getId(); - } - - public EncodedStringList getParents() { - return new EncodedStringList(changeset.getParents()); - } - - public EncodedStringList getTags() { - return new EncodedStringList(changeset.getTags()); - } -} diff --git a/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedModifications.java b/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedModifications.java deleted file mode 100644 index 7b412cbc98..0000000000 --- a/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedModifications.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020-present Cloudogu GmbH and Contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package sonia.scm.web.data; - -import sonia.scm.repository.Added; -import sonia.scm.repository.Modifications; -import sonia.scm.repository.Modified; -import sonia.scm.repository.Removed; - -import java.util.stream.Collectors; - -public final class ImmutableEncodedModifications { - - private final Modifications modifications; - - public ImmutableEncodedModifications(Modifications modifications) { - this.modifications = modifications; - } - - @Override - public String toString() { - return String.format("A:%s;M:%s;R:%s", getAdded(), getModified(), getRemoved()); - } - - public EncodedStringList getAdded() { - return new EncodedStringList(modifications.getAdded().stream().map(Added::getPath).collect(Collectors.toList())); - - } - - public EncodedStringList getModified() { - return new EncodedStringList(modifications.getModified().stream().map(Modified::getPath).collect(Collectors.toList())); - } - - public EncodedStringList getRemoved() { - return new EncodedStringList(modifications.getRemoved().stream().map(Removed::getPath).collect(Collectors.toList())); - } - -} diff --git a/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedRepository.java b/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedRepository.java deleted file mode 100644 index 965bdc4754..0000000000 --- a/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedRepository.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020-present Cloudogu GmbH and Contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package sonia.scm.web.data; - -import sonia.scm.repository.Repository; - -public final class ImmutableEncodedRepository { - - private final Repository repository; - - public ImmutableEncodedRepository(Repository repository) { - this.repository = repository; - } - - public String getContact() { - return Encoder.encode(repository.getContact()); - } - - public Long getCreationDate() { - return repository.getCreationDate(); - } - - public String getDescription() { - return Encoder.encode(repository.getDescription()); - } - - public String getId() { - return repository.getId(); - } - - public Long getLastModified() { - return repository.getLastModified(); - } - - public String getName() { - return repository.getName(); - } - - public String getType() { - return repository.getType(); - } - -} diff --git a/scm-core/src/test/java/sonia/scm/net/ProxiesTest.java b/scm-core/src/test/java/sonia/scm/net/ProxiesTest.java index 96679023d3..7bc0045994 100644 --- a/scm-core/src/test/java/sonia/scm/net/ProxiesTest.java +++ b/scm-core/src/test/java/sonia/scm/net/ProxiesTest.java @@ -21,99 +21,65 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + package sonia.scm.net; -//~--- non-JDK imports -------------------------------------------------------- - import com.google.common.collect.Sets; - import org.junit.Test; - import sonia.scm.config.ScmConfiguration; -import static org.junit.Assert.*; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; -/** - * - * @author Sebastian Sdorra - */ -public class ProxiesTest -{ +public class ProxiesTest { - /** - * Method description - * - */ @Test - public void testDisabledWithoutExcludes() - { + public void testDisabledWithoutExcludes() { ScmConfiguration config = createConfiguration(false); assertFalse(Proxies.isEnabled(config, "localhost")); + assertFalse(Proxies.isEnabled(config, "localhost:8082")); assertFalse(Proxies.isEnabled(config, "download.scm-manager.org")); assertFalse(Proxies.isEnabled(config, "http://127.0.0.1")); assertFalse(Proxies.isEnabled(config, "http://127.0.0.1/test/ka")); } - /** - * Method description - * - */ @Test - public void testEnabledWithoutExcludes() - { + public void testEnabledWithoutExcludes() { ScmConfiguration config = createConfiguration(true); assertTrue(Proxies.isEnabled(config, "localhost")); + assertTrue(Proxies.isEnabled(config, "localhost:8082")); assertTrue(Proxies.isEnabled(config, "download.scm-manager.org")); assertTrue(Proxies.isEnabled(config, "http://127.0.0.1")); assertTrue(Proxies.isEnabled(config, "http://127.0.0.1/test/ka")); } - /** - * Method description - * - */ @Test - public void testWithExcludes() - { + public void testWithExcludes() { ScmConfiguration config = createConfiguration(true, "127.0.0.1", - "localhost"); + "localhost"); assertFalse(Proxies.isEnabled(config, "localhost")); + assertFalse(Proxies.isEnabled(config, "localhost:8082")); assertTrue(Proxies.isEnabled(config, "download.scm-manager.org")); assertFalse(Proxies.isEnabled(config, "http://127.0.0.1")); assertFalse(Proxies.isEnabled(config, "http://127.0.0.1/test/ka")); } - /** - * Method description - * - */ @Test - public void testWithGlobExcludes() - { + public void testWithGlobExcludes() { ScmConfiguration config = createConfiguration(true, "127.*", "*host"); assertFalse(Proxies.isEnabled(config, "localhost")); + assertFalse(Proxies.isEnabled(config, "localhost:8082")); assertTrue(Proxies.isEnabled(config, "download.scm-manager.org")); assertFalse(Proxies.isEnabled(config, "http://127.0.0.1")); assertFalse(Proxies.isEnabled(config, "http://127.0.0.1/test/ka")); } - /** - * Method description - * - * - * @param enabled - * @param excludes - * - * @return - */ private ScmConfiguration createConfiguration(boolean enabled, - String... excludes) - { + String... excludes) { ScmConfiguration configuration = new ScmConfiguration(); configuration.setEnableProxy(enabled); diff --git a/scm-core/src/test/java/sonia/scm/util/JexlUrlParserTest.java b/scm-core/src/test/java/sonia/scm/util/JexlUrlParserTest.java deleted file mode 100644 index 2d5ec98e0e..0000000000 --- a/scm-core/src/test/java/sonia/scm/util/JexlUrlParserTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020-present Cloudogu GmbH and Contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package sonia.scm.util; - -import org.junit.jupiter.api.Test; -import sonia.scm.repository.Changeset; -import sonia.scm.repository.Person; - -import java.util.HashMap; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; - -class JexlUrlParserTest { - - @Test - void shouldParseUrlWithoutExpression() { - JexlUrlParser jexlUrlParser = new JexlUrlParser(); - Map env = new HashMap<>(); - env.put("changeset", new Changeset("1", 1L, Person.toPerson("trillian"))); - - String parsedUrl = jexlUrlParser.parse("http://hitchhiker.org").evaluate(env); - - assertThat(parsedUrl).isEqualTo("http://hitchhiker.org"); - } - - @Test - void shouldParseUrlWithExpression() { - JexlUrlParser jexlUrlParser = new JexlUrlParser(); - Map env = new HashMap<>(); - env.put("changeset", new Changeset("1", 1L, Person.toPerson("trillian"))); - - String parsedUrl = jexlUrlParser.parse("http://${changeset.author.name}.org").evaluate(env); - - assertThat(parsedUrl).isEqualTo("http://trillian.org"); - } -} diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index f8f9d93b50..73f21b899f 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -31,11 +31,11 @@ sonia.scm scm - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-dao-xml - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-dao-xml @@ -50,7 +50,7 @@ sonia.scm scm-core - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT @@ -58,7 +58,7 @@ sonia.scm scm-test - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT test diff --git a/scm-it/pom.xml b/scm-it/pom.xml index 011fe18451..90c22cda75 100644 --- a/scm-it/pom.xml +++ b/scm-it/pom.xml @@ -31,40 +31,40 @@ sonia.scm scm - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT sonia.scm scm-it war - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-it sonia.scm scm-core - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT sonia.scm scm-test - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT sonia.scm.plugins scm-git-plugin - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT test sonia.scm.plugins scm-git-plugin - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT tests test @@ -72,14 +72,14 @@ sonia.scm.plugins scm-hg-plugin - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT test sonia.scm.plugins scm-hg-plugin - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT tests test @@ -87,14 +87,14 @@ sonia.scm.plugins scm-svn-plugin - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT test sonia.scm.plugins scm-svn-plugin - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT tests test diff --git a/scm-packaging/deb/pom.xml b/scm-packaging/deb/pom.xml index 2f1c850838..1b55fd5033 100644 --- a/scm-packaging/deb/pom.xml +++ b/scm-packaging/deb/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT deb deb - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT Packaging for Debian/Ubuntu deb @@ -46,7 +46,7 @@ sonia.scm scm-server - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT @@ -54,6 +54,30 @@ + + org.apache.maven.plugins + maven-resources-plugin + 3.1.0 + + + copy-resources + prepare-package + + copy-resources + + + ${project.build.directory}/deb/etc/scm + + + src/main/fs/etc/scm + true + + + + + + + org.apache.maven.plugins maven-dependency-plugin @@ -135,7 +159,7 @@ file - src/main/fs/etc/scm/logging.xml + ${project.build.directory}/deb/etc/scm/logging.xml /etc/scm/logging.xml true @@ -148,7 +172,7 @@ file - src/main/fs/etc/scm/server-config.xml + ${project.build.directory}/deb/etc/scm/server-config.xml /etc/scm/server-config.xml true diff --git a/scm-packaging/deb/src/main/fs/etc/scm/server-config.xml b/scm-packaging/deb/src/main/fs/etc/scm/server-config.xml index 89f9d56ca4..217e1ae052 100644 --- a/scm-packaging/deb/src/main/fs/etc/scm/server-config.xml +++ b/scm-packaging/deb/src/main/fs/etc/scm/server-config.xml @@ -27,6 +27,14 @@ + + 16384 @@ -110,88 +118,4 @@ - - - - - - - - - - - - - - - - diff --git a/scm-packaging/docker/pom.xml b/scm-packaging/docker/pom.xml index ad3b3abab1..156ff6a028 100644 --- a/scm-packaging/docker/pom.xml +++ b/scm-packaging/docker/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT docker pom - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT @@ -113,6 +113,16 @@ src/main/fs false + + **/scm/* + + + + src/main/fs + true + + **/scm/* + diff --git a/scm-packaging/docker/src/main/fs/etc/scm/server-config.xml b/scm-packaging/docker/src/main/fs/etc/scm/server-config.xml index 89f9d56ca4..217e1ae052 100644 --- a/scm-packaging/docker/src/main/fs/etc/scm/server-config.xml +++ b/scm-packaging/docker/src/main/fs/etc/scm/server-config.xml @@ -27,6 +27,14 @@ + + 16384 @@ -110,88 +118,4 @@ - - - - - - - - - - - - - - - - diff --git a/scm-packaging/helm/pom.xml b/scm-packaging/helm/pom.xml index 8b25cf7465..93817d57c2 100644 --- a/scm-packaging/helm/pom.xml +++ b/scm-packaging/helm/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT helm helm - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT 3.2.1 diff --git a/scm-packaging/pom.xml b/scm-packaging/pom.xml index 85ec7e86ac..ed85aff8e2 100644 --- a/scm-packaging/pom.xml +++ b/scm-packaging/pom.xml @@ -31,19 +31,37 @@ sonia.scm scm - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT sonia.scm.packaging scm-packaging pom - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT packages.scm-manager.org https://packages.scm-manager.org + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.2.0 + + + parse-version + + parse-version + + + + + + + packaging diff --git a/scm-packaging/release-yaml/pom.xml b/scm-packaging/release-yaml/pom.xml index b3308e860c..af5e983661 100644 --- a/scm-packaging/release-yaml/pom.xml +++ b/scm-packaging/release-yaml/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT release-yaml pom - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT diff --git a/scm-packaging/rpm/pom.xml b/scm-packaging/rpm/pom.xml index bcfe3533eb..5af952fd87 100644 --- a/scm-packaging/rpm/pom.xml +++ b/scm-packaging/rpm/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT rpm rpm - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT Packaging for RedHat/Centos/Fedora rpm @@ -52,7 +52,7 @@ sonia.scm scm-server - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT @@ -60,6 +60,30 @@ + + org.apache.maven.plugins + maven-resources-plugin + 3.1.0 + + + copy-resources + prepare-package + + copy-resources + + + ${project.build.directory}/rpm/etc/scm + + + src/main/fs/etc/scm + true + + + + + + + org.apache.maven.plugins maven-dependency-plugin @@ -172,7 +196,7 @@ /etc/scm/logging.xml - src/main/fs/etc/scm/logging.xml + ${project.build.directory}/rpm/etc/scm/logging.xml root scm 0640 @@ -181,7 +205,7 @@ /etc/scm/server-config.xml - src/main/fs/etc/scm/server-config.xml + ${project.build.directory}/rpm/etc/scm/server-config.xml root scm 0640 diff --git a/scm-packaging/rpm/src/main/fs/etc/scm/server-config.xml b/scm-packaging/rpm/src/main/fs/etc/scm/server-config.xml index 89f9d56ca4..bd3b75b72a 100644 --- a/scm-packaging/rpm/src/main/fs/etc/scm/server-config.xml +++ b/scm-packaging/rpm/src/main/fs/etc/scm/server-config.xml @@ -27,6 +27,14 @@ + + 16384 @@ -109,89 +117,5 @@ - - - - - - - - - - - - - - - - diff --git a/scm-packaging/unix/pom.xml b/scm-packaging/unix/pom.xml index 4d77592d35..a03977fbf5 100644 --- a/scm-packaging/unix/pom.xml +++ b/scm-packaging/unix/pom.xml @@ -24,20 +24,19 @@ SOFTWARE. --> - + 4.0.0 sonia.scm.packaging scm-packaging - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT unix pom - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT diff --git a/scm-packaging/unix/src/main/assembly/scm-server-app.xml b/scm-packaging/unix/src/main/assembly/scm-server-app.xml index 1b8728fbc9..0521e69681 100644 --- a/scm-packaging/unix/src/main/assembly/scm-server-app.xml +++ b/scm-packaging/unix/src/main/assembly/scm-server-app.xml @@ -39,9 +39,23 @@ + + + + src/main/fs/conf + true + conf + + src/main/fs false + + conf/** + diff --git a/scm-packaging/unix/src/main/fs/conf/server-config.xml b/scm-packaging/unix/src/main/fs/conf/server-config.xml index 08814ccf68..8e01822c91 100644 --- a/scm-packaging/unix/src/main/fs/conf/server-config.xml +++ b/scm-packaging/unix/src/main/fs/conf/server-config.xml @@ -27,6 +27,14 @@ + + 16384 @@ -113,89 +121,5 @@ - - - - - - - - - - - - - - - - diff --git a/scm-packaging/windows/pom.xml b/scm-packaging/windows/pom.xml index ddccb57053..e0f0181d3a 100644 --- a/scm-packaging/windows/pom.xml +++ b/scm-packaging/windows/pom.xml @@ -32,12 +32,12 @@ sonia.scm.packaging scm-packaging - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT windows pom - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT diff --git a/scm-packaging/windows/src/main/assembly/scm-server-app.xml b/scm-packaging/windows/src/main/assembly/scm-server-app.xml index b83ab7b431..2062e53f68 100644 --- a/scm-packaging/windows/src/main/assembly/scm-server-app.xml +++ b/scm-packaging/windows/src/main/assembly/scm-server-app.xml @@ -39,12 +39,26 @@ + + + + src/main/fs/conf + true + conf + + src/main/fs false + + conf/** + - + target/windows false diff --git a/scm-packaging/windows/src/main/fs/conf/server-config.xml b/scm-packaging/windows/src/main/fs/conf/server-config.xml index 8aa4333bdc..bbcc515670 100644 --- a/scm-packaging/windows/src/main/fs/conf/server-config.xml +++ b/scm-packaging/windows/src/main/fs/conf/server-config.xml @@ -27,6 +27,14 @@ + + 16384 @@ -114,89 +122,5 @@ - - - - - - - - - - - - - - - - diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index ce690e3211..a407c38471 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -31,13 +31,13 @@ sonia.scm scm - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT sonia.scm.plugins scm-plugins pom - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-plugins @@ -59,7 +59,7 @@ sonia.scm scm-core - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT provided @@ -68,7 +68,7 @@ sonia.scm scm-annotation-processor - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT provided @@ -98,7 +98,7 @@ sonia.scm scm-test - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT test diff --git a/scm-plugins/scm-git-plugin/package.json b/scm-plugins/scm-git-plugin/package.json index b99fda05b3..4c8fbd8cc0 100644 --- a/scm-plugins/scm-git-plugin/package.json +++ b/scm-plugins/scm-git-plugin/package.json @@ -1,7 +1,7 @@ { "name": "@scm-manager/scm-git-plugin", "private": true, - "version": "2.3.0-SNAPSHOT", + "version": "2.3.0", "license": "MIT", "main": "./src/main/js/index.ts", "scripts": { @@ -20,6 +20,6 @@ }, "prettier": "@scm-manager/prettier-config", "dependencies": { - "@scm-manager/ui-plugins": "^2.3.0-SNAPSHOT" + "@scm-manager/ui-plugins": "^2.3.0" } } diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index 82361937ff..b184af3645 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -31,7 +31,7 @@ scm-plugins sonia.scm.plugins - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-git-plugin diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBranchCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBranchCommand.java index 82a62ef111..43bfb68578 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBranchCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBranchCommand.java @@ -30,6 +30,7 @@ import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.Ref; import sonia.scm.event.ScmEventBus; import sonia.scm.repository.Branch; +import sonia.scm.repository.BranchCreatedEvent; import sonia.scm.repository.GitUtil; import sonia.scm.repository.InternalRepositoryException; import sonia.scm.repository.PostReceiveRepositoryHookEvent; @@ -71,6 +72,8 @@ public class GitBranchCommand extends AbstractGitCommand implements BranchComman eventBus.post(new PreReceiveRepositoryHookEvent(hookEvent)); Ref ref = git.branchCreate().setStartPoint(request.getParentBranch()).setName(request.getNewBranch()).call(); eventBus.post(new PostReceiveRepositoryHookEvent(hookEvent)); + // Clear cache synchronously to avoid branch not found in invalid cache + eventBus.post(new BranchCreatedEvent(repository, request.getNewBranch())); return Branch.normalBranch(request.getNewBranch(), GitUtil.getId(ref.getObjectId())); } catch (GitAPIException | IOException ex) { throw new InternalRepositoryException(repository, "could not create branch " + request.getNewBranch(), ex); diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBranchCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBranchCommandTest.java index 020bde53c9..7338c447fb 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBranchCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBranchCommandTest.java @@ -32,6 +32,7 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.event.ScmEventBus; import sonia.scm.repository.Branch; +import sonia.scm.repository.BranchCreatedEvent; import sonia.scm.repository.PostReceiveRepositoryHookEvent; import sonia.scm.repository.PreReceiveRepositoryHookEvent; import sonia.scm.repository.api.BranchRequest; @@ -129,6 +130,7 @@ public class GitBranchCommandTest extends AbstractGitCommandTestBase { List events = captor.getAllValues(); assertThat(events.get(0)).isInstanceOf(PreReceiveRepositoryHookEvent.class); assertThat(events.get(1)).isInstanceOf(PostReceiveRepositoryHookEvent.class); + assertThat(events.get(2)).isInstanceOf(BranchCreatedEvent.class); PreReceiveRepositoryHookEvent event = (PreReceiveRepositoryHookEvent) events.get(0); assertThat(event.getContext().getBranchProvider().getCreatedOrModified()).containsExactly("new_branch"); diff --git a/scm-plugins/scm-hg-plugin/package.json b/scm-plugins/scm-hg-plugin/package.json index c543da952e..237ce626e3 100644 --- a/scm-plugins/scm-hg-plugin/package.json +++ b/scm-plugins/scm-hg-plugin/package.json @@ -1,7 +1,7 @@ { "name": "@scm-manager/scm-hg-plugin", "private": true, - "version": "2.3.0-SNAPSHOT", + "version": "2.3.0", "license": "MIT", "main": "./src/main/js/index.ts", "scripts": { @@ -19,6 +19,6 @@ }, "prettier": "@scm-manager/prettier-config", "dependencies": { - "@scm-manager/ui-plugins": "^2.3.0-SNAPSHOT" + "@scm-manager/ui-plugins": "^2.3.0" } } diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index 2ec909a4fd..ae491a1f04 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -31,7 +31,7 @@ sonia.scm.plugins scm-plugins - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-hg-plugin diff --git a/scm-plugins/scm-legacy-plugin/package.json b/scm-plugins/scm-legacy-plugin/package.json index 21b10bc873..4733ac70a7 100644 --- a/scm-plugins/scm-legacy-plugin/package.json +++ b/scm-plugins/scm-legacy-plugin/package.json @@ -1,7 +1,7 @@ { "name": "@scm-manager/scm-legacy-plugin", "private": true, - "version": "2.3.0-SNAPSHOT", + "version": "2.3.0", "license": "MIT", "main": "./src/main/js/index.tsx", "scripts": { @@ -19,6 +19,6 @@ }, "prettier": "@scm-manager/prettier-config", "dependencies": { - "@scm-manager/ui-plugins": "^2.3.0-SNAPSHOT" + "@scm-manager/ui-plugins": "^2.3.0" } } diff --git a/scm-plugins/scm-legacy-plugin/pom.xml b/scm-plugins/scm-legacy-plugin/pom.xml index 5f32cd25db..f1f62b66dc 100644 --- a/scm-plugins/scm-legacy-plugin/pom.xml +++ b/scm-plugins/scm-legacy-plugin/pom.xml @@ -29,12 +29,12 @@ sonia.scm.plugins scm-plugins - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-legacy-plugin Support migrated repository urls and v1 passwords - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT smp diff --git a/scm-plugins/scm-svn-plugin/package.json b/scm-plugins/scm-svn-plugin/package.json index 3b287ba4aa..ca3b81cfed 100644 --- a/scm-plugins/scm-svn-plugin/package.json +++ b/scm-plugins/scm-svn-plugin/package.json @@ -1,7 +1,7 @@ { "name": "@scm-manager/scm-svn-plugin", "private": true, - "version": "2.3.0-SNAPSHOT", + "version": "2.3.0", "license": "MIT", "main": "./src/main/js/index.ts", "scripts": { @@ -19,6 +19,6 @@ }, "prettier": "@scm-manager/prettier-config", "dependencies": { - "@scm-manager/ui-plugins": "^2.3.0-SNAPSHOT" + "@scm-manager/ui-plugins": "^2.3.0" } } diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index 26411a0289..28145f3dcb 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -31,7 +31,7 @@ scm-plugins sonia.scm.plugins - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-svn-plugin diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnModifyCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnModifyCommand.java index 57b7a3ad68..849d5619a5 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnModifyCommand.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnModifyCommand.java @@ -39,12 +39,13 @@ import sonia.scm.repository.work.WorkingCopy; import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.nio.file.Paths; public class SvnModifyCommand implements ModifyCommand { - private SvnContext context; - private SvnWorkingCopyFactory workingCopyFactory; - private Repository repository; + private final SvnContext context; + private final SvnWorkingCopyFactory workingCopyFactory; + private final Repository repository; SvnModifyCommand(SvnContext context, SvnWorkingCopyFactory workingCopyFactory) { this.context = context; @@ -57,6 +58,9 @@ public class SvnModifyCommand implements ModifyCommand { SVNClientManager clientManager = SVNClientManager.newInstance(); try (WorkingCopy workingCopy = workingCopyFactory.createWorkingCopy(context, null)) { File workingDirectory = workingCopy.getDirectory(); + if (request.isDefaultPath()) { + workingDirectory = Paths.get(workingDirectory.toString() + "/trunk").toFile(); + } modifyWorkingDirectory(request, clientManager, workingDirectory); return commitChanges(clientManager, workingDirectory, request.getCommitMessage()); } diff --git a/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnModifyCommandTest.java b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnModifyCommandTest.java index dbace87411..ef646dfce2 100644 --- a/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnModifyCommandTest.java +++ b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnModifyCommandTest.java @@ -101,6 +101,22 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { assertThat(new File(workingCopy.getWorkingRepository(), "Test123")).exists(); } + @Test + public void shouldAddNewFileInDefaultPath() throws IOException { + File testfile = temporaryFolder.newFile("Test123"); + + ModifyCommandRequest request = new ModifyCommandRequest(); + request.setDefaultPath(true); + request.addRequest(new ModifyCommandRequest.CreateFileRequest("Test123", testfile, false)); + request.setCommitMessage("this is great"); + request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); + + svnModifyCommand.execute(request); + + WorkingCopy workingCopy = workingCopyFactory.createWorkingCopy(context, null); + assertThat(new File(workingCopy.getWorkingRepository(), "trunk/Test123")).exists(); + } + @Test public void shouldThrowFileAlreadyExistsException() throws IOException { File testfile = temporaryFolder.newFile("a.txt"); diff --git a/scm-server/pom.xml b/scm-server/pom.xml index d8f5a9aad3..96c89ac660 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -31,12 +31,12 @@ scm sonia.scm - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT sonia.scm scm-server - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index 0444182fc3..c430ba59ba 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -31,12 +31,12 @@ scm sonia.scm - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT sonia.scm scm-test - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-test @@ -50,7 +50,7 @@ sonia.scm scm-core - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT diff --git a/scm-ui/pom.xml b/scm-ui/pom.xml index f52e9a4f21..ebdcb9dc1c 100644 --- a/scm-ui/pom.xml +++ b/scm-ui/pom.xml @@ -32,13 +32,13 @@ sonia.scm scm - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT sonia.scm scm-ui war - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-ui diff --git a/scm-ui/ui-components/package.json b/scm-ui/ui-components/package.json index 00c9133a3e..74dce43cd0 100644 --- a/scm-ui/ui-components/package.json +++ b/scm-ui/ui-components/package.json @@ -1,6 +1,6 @@ { "name": "@scm-manager/ui-components", - "version": "2.3.0-SNAPSHOT", + "version": "2.3.0", "description": "UI Components for SCM-Manager and its plugins", "main": "src/index.ts", "files": [ @@ -47,7 +47,7 @@ }, "dependencies": { "@scm-manager/ui-extensions": "^2.1.0", - "@scm-manager/ui-types": "^2.1.0", + "@scm-manager/ui-types": "^2.3.0", "classnames": "^2.2.6", "date-fns": "^2.4.1", "gitdiff-parser": "^0.1.2", diff --git a/scm-ui/ui-components/src/SyntaxHighlighter.stories.tsx b/scm-ui/ui-components/src/SyntaxHighlighter.stories.tsx index 305d8dc2c8..7f458e4784 100644 --- a/scm-ui/ui-components/src/SyntaxHighlighter.stories.tsx +++ b/scm-ui/ui-components/src/SyntaxHighlighter.stories.tsx @@ -55,4 +55,9 @@ storiesOf("SyntaxHighlighter", module) + )) + .add("Without line numbers", () => ( + + + )); diff --git a/scm-ui/ui-components/src/SyntaxHighlighter.tsx b/scm-ui/ui-components/src/SyntaxHighlighter.tsx index bcbf05d53d..a8a06ac29d 100644 --- a/scm-ui/ui-components/src/SyntaxHighlighter.tsx +++ b/scm-ui/ui-components/src/SyntaxHighlighter.tsx @@ -30,13 +30,15 @@ import { arduinoLight } from "react-syntax-highlighter/dist/cjs/styles/hljs"; type Props = { language?: string; value: string; + showLineNumbers?: boolean; }; const defaultLanguage = "text"; class SyntaxHighlighter extends React.Component { static defaultProps: Partial = { - language: defaultLanguage + language: defaultLanguage, + showLineNumbers: true }; getLanguage = () => { @@ -48,9 +50,10 @@ class SyntaxHighlighter extends React.Component { }; render() { + const { showLineNumbers } = this.props; const language = this.getLanguage(); return ( - + {this.props.value} ); diff --git a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap index 295104f72f..58725b1514 100644 --- a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap +++ b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap @@ -39474,6 +39474,22 @@ exports[`Storyshots MarkdownView Code without Lang 1`] = ` } > + + + 1 + + + @@ -40194,6 +40210,120 @@ Deserunt officia esse aliquip consectetur duis ut labore laborum commodo aliquip } } > + + + 1 + + + + 2 + + + + 3 + + + + 4 + + + + 5 + + + + 6 + + + + 7 + + + + 8 + + + + 9 + + + + 10 + + + + 11 + + + + 12 + + + + 13 + + + + 14 + + + + 15 + + + package main @@ -40466,6 +40596,176 @@ exports[`Storyshots MarkdownView Xml Code Block 1`] = ` } > + + + 1 + + + + 2 + + + + 3 + + + + 4 + + + + 5 + + + + 6 + + + + 7 + + + + 8 + + + + 9 + + + + 10 + + + + 11 + + + + 12 + + + + 13 + + + + 14 + + + + 15 + + + + 16 + + + + 17 + + + + 18 + + + + 19 + + + + 20 + + + + 21 + + + + 22 + + + + 23 + + + + + + 1 + + + + 2 + + + + 3 + + + + 4 + + + + 5 + + + + 6 + + + + 7 + + + + 8 + + + + 9 + + + + 10 + + + + 11 + + + + 12 + + + + 13 + + + + 14 + + + + 15 + + + + 16 + + + + 17 + + + + + + 1 + + + + 2 + + + + 3 + + + + 4 + + + + 5 + + + + 6 + + + + 7 + + + + 8 + + + + 9 + + + + 10 + + + + 11 + + + + 12 + + + + 13 + + + + 14 + + + + 15 + + + + 16 + + + + 17 + + + + 18 + + + + 19 + + + + 20 + + + + 21 + + + + 22 + + + + 23 + + + + 24 + + + + 25 + + + + 26 + + + + 27 + + + + 28 + + + + 29 + + + + 30 + + + + 31 + + + + + + 1 + + + + 2 + + + + 3 + + + + 4 + + + + 5 + + + + 6 + + + + 7 + + + + + + 1 + + + + 2 + + + + 3 + + + + 4 + + + + 5 + + + + 6 + + + + 7 + + + + 8 + + + + 9 + + + + 10 + + + + 11 + + + + 12 + + + + 13 + + + + 14 + + + + 15 + + + + 16 + + + + 17 + + + + 18 + + + + 19 + + + + 20 + + + + + +`; + +exports[`Storyshots SyntaxHighlighter Without line numbers 1`] = ` +
+
+    
+      
+        package
+      
+      
+         com.example;
+
+      
+      
+
+      
+        
+      
+      
+        import
+      
+      
+         java.io.IOException;
+
+      
+      
+        
+      
+      
+        import
+      
+      
+         java.io.OutputStream;
+
+      
+      
+        
+      
+      
+        import
+      
+      
+         java.net.InetSocketAddress;
+
+      
+      
+
+      
+        
+      
+      
+        import
+      
+      
+         com.sun.net.httpserver.HttpExchange;
+
+      
+      
+        
+      
+      
+        import
+      
+      
+         com.sun.net.httpserver.HttpHandler;
+
+      
+      
+        
+      
+      
+        import
+      
+      
+         com.sun.net.httpserver.HttpServer;
+
+      
+      
+
+      
+        
+      
+      
+        public
+      
+      
+         
+      
+      
+        class
+      
+      
+         
+      
+      
+        Test
+      
+      
+         
+      
+      
+        {
+
+      
+      
+
+      
+          
+      
+      
+        public
+      
+      
+         
+      
+      
+        static
+      
+      
+         
+      
+      
+        void
+      
+      
+         
+      
+      
+        main
+      
+      
+        (String[] args)
+      
+      
+         
+      
+      
+        throws
+      
+      
+         Exception 
+      
+      
+        {
+
+      
+      
+            HttpServer server = HttpServer.create(
+      
+      
+        new
+      
+      
+         InetSocketAddress(
+      
+      
+        8000
+      
+      
+        ), 
+      
+      
+        0
+      
+      
+        );
+
+      
+      
+            server.createContext(
+      
+      
+        "/test"
+      
+      
+        , 
+      
+      
+        new
+      
+      
+         MyHandler());
+
+      
+      
+            server.setExecutor(
+      
+      
+        null
+      
+      
+        ); 
+      
+      
+        // creates a default executor
+      
+      
+        
+
+      
+          server.start();
+
+        }
+
+      
+
+      
+          
+      
+      
+        static
+      
+      
+         
+      
+      
+        class
+      
+      
+         
+      
+      
+        MyHandler
+      
+      
+         
+      
+      
+        implements
+      
+      
+         
+      
+      
+        HttpHandler
+      
+      
+         
+      
+      
+        {
+
+      
+      
+            
+      
+      
+        @Override
+      
+      
+        
+
+      
+      
+            
+      
+      
+        public
+      
+      
+         
+      
+      
+        void
+      
+      
+         
+      
+      
+        handle
+      
+      
+        (HttpExchange t)
+      
+      
+         
+      
+      
+        throws
+      
+      
+         IOException 
+      
+      
+        {
+
+      
+      
+              String response = 
+      
+      
+        "This is the response"
+      
+      
+        ;
+
+      
+      
+              t.sendResponseHeaders(
+      
+      
+        200
+      
+      
+        , response.length());
+
+      
+            OutputStream os = t.getResponseBody();
+
+            os.write(response.getBytes());
+
+            os.close();
+
+          }
+
+        }
+
+      
+
+      }
+
+      
+
     
   
diff --git a/scm-ui/ui-plugins/package.json b/scm-ui/ui-plugins/package.json index d95c16d511..93b7836c88 100644 --- a/scm-ui/ui-plugins/package.json +++ b/scm-ui/ui-plugins/package.json @@ -1,12 +1,12 @@ { "name": "@scm-manager/ui-plugins", - "version": "2.3.0-SNAPSHOT", + "version": "2.3.0", "license": "MIT", "bin": { "ui-plugins": "./bin/ui-plugins.js" }, "dependencies": { - "@scm-manager/ui-components": "^2.3.0-SNAPSHOT", + "@scm-manager/ui-components": "^2.3.0", "@scm-manager/ui-extensions": "^2.1.0", "classnames": "^2.2.6", "query-string": "^5.0.1", @@ -25,7 +25,7 @@ "@scm-manager/tsconfig": "^2.1.0", "@scm-manager/ui-scripts": "^2.1.0", "@scm-manager/ui-tests": "^2.1.0", - "@scm-manager/ui-types": "^2.1.0", + "@scm-manager/ui-types": "^2.3.0", "@types/classnames": "^2.2.9", "@types/enzyme": "^3.10.3", "@types/fetch-mock": "^7.3.1", diff --git a/scm-ui/ui-styles/package.json b/scm-ui/ui-styles/package.json index 49256f8a26..8efa51cd75 100644 --- a/scm-ui/ui-styles/package.json +++ b/scm-ui/ui-styles/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@fortawesome/fontawesome-free": "^5.11.2", - "bulma": "^0.8.0", + "bulma": "^0.9.0", "bulma-popover": "^1.0.0", "bulma-tooltip": "^3.0.0", "react-diff-view": "^2.4.1" diff --git a/scm-ui/ui-types/package.json b/scm-ui/ui-types/package.json index 96d9a14a97..c021045369 100644 --- a/scm-ui/ui-types/package.json +++ b/scm-ui/ui-types/package.json @@ -1,6 +1,6 @@ { "name": "@scm-manager/ui-types", - "version": "2.1.0", + "version": "2.3.0", "description": "Flow types for SCM-Manager related Objects", "main": "src/index.ts", "files": [ diff --git a/scm-ui/ui-types/src/Plugin.ts b/scm-ui/ui-types/src/Plugin.ts index 66cb8b994f..635f277f9f 100644 --- a/scm-ui/ui-types/src/Plugin.ts +++ b/scm-ui/ui-types/src/Plugin.ts @@ -36,6 +36,7 @@ export type Plugin = { pending: boolean; markedForUninstall?: boolean; dependencies: string[]; + optionalDependencies: string[]; _links: Links; }; diff --git a/scm-ui/ui-webapp/package.json b/scm-ui/ui-webapp/package.json index 002f765ce8..1cc39be1bc 100644 --- a/scm-ui/ui-webapp/package.json +++ b/scm-ui/ui-webapp/package.json @@ -1,13 +1,13 @@ { "name": "@scm-manager/ui-webapp", - "version": "2.3.0-SNAPSHOT", + "version": "2.3.0", "private": true, "dependencies": { - "@scm-manager/ui-components": "^2.3.0-SNAPSHOT", + "@scm-manager/ui-components": "^2.3.0", "@scm-manager/ui-extensions": "^2.1.0", "classnames": "^2.2.5", "history": "^4.10.1", - "i18next": "^17.3.0", + "i18next": "^19.6.0", "i18next-browser-languagedetector": "^4.0.0", "i18next-fetch-backend": "^2.2.0", "memoize-one": "^5.0.4", diff --git a/scm-ui/ui-webapp/public/locales/de/admin.json b/scm-ui/ui-webapp/public/locales/de/admin.json index db096832eb..620228df0b 100644 --- a/scm-ui/ui-webapp/public/locales/de/admin.json +++ b/scm-ui/ui-webapp/public/locales/de/admin.json @@ -62,6 +62,7 @@ "currentVersion": "Installierte Version", "newVersion": "Neue Version", "dependencyNotification": "Mit diesem Plugin werden folgende Abhängigkeiten mit installiert bzw. aktualisiert, wenn sie noch nicht in der aktuellen Version vorhanden sind!", + "optionalDependencyNotification": "Mit diesem Plugin werden folgende optionale Abhängigkeiten mit aktualisiert, falls sie installiert sind!", "dependencies": "Abhängigkeiten", "installedNotification": "Das Plugin wurde erfolgreich installiert. Um Änderungen an der UI zu sehen, muss die Seite neu geladen werden:", "updatedNotification": "Das Plugin wurde erfolgreich aktualisiert. Um Änderungen an der UI zu sehen, muss die Seite neu geladen werden:", diff --git a/scm-ui/ui-webapp/public/locales/en/admin.json b/scm-ui/ui-webapp/public/locales/en/admin.json index 829aecf3d4..eae79e3a9c 100644 --- a/scm-ui/ui-webapp/public/locales/en/admin.json +++ b/scm-ui/ui-webapp/public/locales/en/admin.json @@ -62,6 +62,7 @@ "currentVersion": "Installed version", "newVersion": "New version", "dependencyNotification": "With this plugin, the following dependencies will be installed/updated if their latest versions are not installed yet!", + "optionalDependencyNotification": "With this plugin, the following optional dependencies will be updated if they are installed!", "dependencies": "Dependencies", "installedNotification": "Successfully installed plugin. You have to reload the page, to see ui changes:", "updatedNotification": "Successfully updated plugin. You have to reload the page, to see ui changes:", diff --git a/scm-ui/ui-webapp/src/admin/plugins/components/PluginModal.tsx b/scm-ui/ui-webapp/src/admin/plugins/components/PluginModal.tsx index 05ddf1f848..8a76a0d7e3 100644 --- a/scm-ui/ui-webapp/src/admin/plugins/components/PluginModal.tsx +++ b/scm-ui/ui-webapp/src/admin/plugins/components/PluginModal.tsx @@ -183,6 +183,27 @@ class PluginModal extends React.Component { return dependencies; } + renderOptionalDependencies() { + const { plugin, t } = this.props; + + let optionalDependencies = null; + if (plugin.optionalDependencies && plugin.optionalDependencies.length > 0) { + optionalDependencies = ( +
+ + {t("plugins.modal.optionalDependencyNotification")} +
    + {plugin.optionalDependencies.map((optionalDependency, index) => { + return
  • {optionalDependency}
  • ; + })} +
+
+
+ ); + } + return optionalDependencies; + } + renderNotifications = () => { const { t, pluginAction } = this.props; const { restart, error, success } = this.state; @@ -275,6 +296,7 @@ class PluginModal extends React.Component { )} {this.renderDependencies()} + {this.renderOptionalDependencies()}
diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 28bf55743f..faf066b4bb 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -32,13 +32,13 @@ sonia.scm scm - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT sonia.scm scm-webapp war - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT scm-webapp @@ -48,7 +48,7 @@ sonia.scm scm-annotation-processor - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT provided @@ -73,13 +73,13 @@ sonia.scm scm-core - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT sonia.scm scm-dao-xml - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT @@ -343,7 +343,7 @@ sonia.scm scm-test - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT test @@ -405,7 +405,7 @@ sonia.scm.plugins scm-git-plugin - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT tests test @@ -413,14 +413,14 @@ sonia.scm.plugins scm-git-plugin - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT test sonia.scm.plugins scm-hg-plugin - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT tests test @@ -428,14 +428,14 @@ sonia.scm.plugins scm-hg-plugin - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT test sonia.scm.plugins scm-svn-plugin - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT tests test @@ -443,7 +443,7 @@ sonia.scm.plugins scm-svn-plugin - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT test @@ -729,7 +729,7 @@ sonia.scm scm-ui - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT war diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PluginDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PluginDto.java index 4dce1e9e92..282b9860b3 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PluginDto.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PluginDto.java @@ -53,6 +53,7 @@ public class PluginDto extends HalRepresentation { private Boolean core; private Boolean markedForUninstall; private Set dependencies; + private Set optionalDependencies; public PluginDto(Links links) { add(links); diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PluginDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PluginDtoMapper.java index 1d71735278..0156a976ec 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PluginDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PluginDtoMapper.java @@ -68,6 +68,7 @@ public abstract class PluginDtoMapper { private void map(PluginDto dto, Plugin plugin) { dto.setDependencies(plugin.getDescriptor().getDependencies()); + dto.setOptionalDependencies(plugin.getDescriptor().getOptionalDependencies()); map(plugin.getDescriptor().getInformation(), dto); if (dto.getCategory() == null) { dto.setCategory("Miscellaneous"); diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginManager.java b/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginManager.java index ef1f4e6873..69fc876704 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginManager.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginManager.java @@ -253,21 +253,40 @@ public class DefaultPluginManager implements PluginManager { private void collectPluginsToInstallOrUpdate(List plugins, String name) { if (!isInstalledOrPending(name) || isUpdatable(name)) { - AvailablePlugin plugin = getAvailable(name).orElseThrow(() -> NotFoundException.notFound(entity(AvailablePlugin.class, name))); - - Set dependencies = plugin.getDescriptor().getDependencies(); - if (dependencies != null) { - for (String dependency : dependencies) { - collectPluginsToInstallOrUpdate(plugins, dependency); - } - } - - plugins.add(plugin); + collectDependentPlugins(plugins, name); } else { LOG.info("plugin {} is already installed or installation is pending, skipping installation", name); } } + private void collectOptionalPluginToInstallOrUpdate(List plugins, String name) { + if (isInstalledOrPending(name) && isUpdatable(name)) { + collectDependentPlugins(plugins, name); + } else { + LOG.info("optional plugin {} is not installed or not updatable", name); + } + } + + private void collectDependentPlugins(List plugins, String name) { + AvailablePlugin plugin = getAvailable(name).orElseThrow(() -> NotFoundException.notFound(entity(AvailablePlugin.class, name))); + + Set dependencies = plugin.getDescriptor().getDependencies(); + if (dependencies != null) { + for (String dependency : dependencies) { + collectPluginsToInstallOrUpdate(plugins, dependency); + } + } + + Set optionalDependencies = plugin.getDescriptor().getOptionalDependencies(); + if (dependencies != null) { + for (String optionalDependency : optionalDependencies) { + collectOptionalPluginToInstallOrUpdate(plugins, optionalDependency); + } + } + + plugins.add(plugin); + } + private boolean isInstalledOrPending(String name) { return getInstalled(name).isPresent() || getPending(name).isPresent(); } diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/PluginCenterDto.java b/scm-webapp/src/main/java/sonia/scm/plugin/PluginCenterDto.java index 223e02ad47..c034c98a56 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/PluginCenterDto.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/PluginCenterDto.java @@ -85,6 +85,9 @@ public final class PluginCenterDto implements Serializable { @XmlElement(name = "dependencies") private Set dependencies; + @XmlElement(name = "optionalDependencies") + private Set optionalDependencies; + @XmlElement(name = "_links") private Map links; } diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/PluginCenterDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/plugin/PluginCenterDtoMapper.java index 27d20d638a..5927592d0c 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/PluginCenterDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/PluginCenterDtoMapper.java @@ -43,7 +43,7 @@ public abstract class PluginCenterDtoMapper { for (PluginCenterDto.Plugin plugin : pluginCenterDto.getEmbedded().getPlugins()) { String url = plugin.getLinks().get("download").getHref(); AvailablePluginDescriptor descriptor = new AvailablePluginDescriptor( - map(plugin), map(plugin.getConditions()), plugin.getDependencies(), url, plugin.getSha256sum() + map(plugin), map(plugin.getConditions()), plugin.getDependencies(), plugin.getOptionalDependencies(), url, plugin.getSha256sum() ); plugins.add(new AvailablePlugin(descriptor)); } diff --git a/scm-webapp/src/main/java/sonia/scm/repository/RepositoryInitializer.java b/scm-webapp/src/main/java/sonia/scm/repository/RepositoryInitializer.java index ef44379d00..c8ca705a9a 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/RepositoryInitializer.java +++ b/scm-webapp/src/main/java/sonia/scm/repository/RepositoryInitializer.java @@ -73,7 +73,7 @@ public class RepositoryInitializer { } } - private class InitializerContextImpl implements RepositoryContentInitializer.InitializerContext { + private static class InitializerContextImpl implements RepositoryContentInitializer.InitializerContext { private final Repository repository; private final ModifyCommandBuilder builder; @@ -90,11 +90,11 @@ public class RepositoryInitializer { @Override public RepositoryContentInitializer.CreateFile create(String path) { - return new CreateFileImpl(this, builder.createFile(path).setOverwrite(true)); + return new CreateFileImpl(this, builder.useDefaultPath(true).createFile(path).setOverwrite(true)); } } - private class CreateFileImpl implements RepositoryContentInitializer.CreateFile { + private static class CreateFileImpl implements RepositoryContentInitializer.CreateFile { private final RepositoryContentInitializer.InitializerContext initializerContext; private final ModifyCommandBuilder.WithOverwriteFlagContentLoader contentLoader; diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PluginDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PluginDtoMapperTest.java index 7c3c3975c0..9a6b51db7a 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PluginDtoMapperTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PluginDtoMapperTest.java @@ -164,6 +164,15 @@ class PluginDtoMapperTest { assertThat(dto.getDependencies()).containsOnly("one", "two"); } + @Test + void shouldAppendOptionalDependencies() { + AvailablePlugin plugin = createAvailable(createPluginInformation()); + when(plugin.getDescriptor().getOptionalDependencies()).thenReturn(ImmutableSet.of("one", "two")); + + PluginDto dto = mapper.mapAvailable(plugin); + assertThat(dto.getOptionalDependencies()).containsOnly("one", "two"); + } + @Test void shouldAppendUninstallLink() { when(subject.isPermitted("plugin:write")).thenReturn(true); diff --git a/scm-webapp/src/test/java/sonia/scm/plugin/DefaultPluginManagerTest.java b/scm-webapp/src/test/java/sonia/scm/plugin/DefaultPluginManagerTest.java index b1b1db9efe..b16d010c5d 100644 --- a/scm-webapp/src/test/java/sonia/scm/plugin/DefaultPluginManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/plugin/DefaultPluginManagerTest.java @@ -260,6 +260,35 @@ class DefaultPluginManagerTest { verify(installer).install(review); } + @Test + void shouldUpdateAlreadyInstalledOptionalDependenciesWhenNewerVersionIsAvailable() { + AvailablePlugin review = createAvailable("scm-review-plugin"); + when(review.getDescriptor().getOptionalDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin")); + AvailablePlugin mail = createAvailable("scm-mail-plugin", "1.1.0"); + when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail)); + + InstalledPlugin installedMail = createInstalled("scm-mail-plugin", "1.0.0"); + when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(installedMail)); + + manager.install("scm-review-plugin", false); + + verify(installer).install(mail); + verify(installer).install(review); + } + + @Test + void shouldNotUpdateOptionalDependenciesWhenNewerVersionIsAvailableButItIsNotInstalled() { + AvailablePlugin review = createAvailable("scm-review-plugin"); + when(review.getDescriptor().getOptionalDependencies()).thenReturn(ImmutableSet.of("scm-mail-plugin")); + AvailablePlugin mail = createAvailable("scm-mail-plugin", "1.1.0"); + when(center.getAvailable()).thenReturn(ImmutableSet.of(review, mail)); + + manager.install("scm-review-plugin", false); + + verify(installer, never()).install(mail); + verify(installer).install(review); + } + @Test void shouldRollbackOnFailedInstallation() { AvailablePlugin review = createAvailable("scm-review-plugin"); diff --git a/scm-webapp/src/test/java/sonia/scm/plugin/PluginCenterDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/plugin/PluginCenterDtoMapperTest.java index 42ecf64da4..96ceccfb54 100644 --- a/scm-webapp/src/test/java/sonia/scm/plugin/PluginCenterDtoMapperTest.java +++ b/scm-webapp/src/test/java/sonia/scm/plugin/PluginCenterDtoMapperTest.java @@ -67,6 +67,7 @@ class PluginCenterDtoMapperTest { "555000444", new Condition(Collections.singletonList("linux"), "amd64","2.0.0"), ImmutableSet.of("scm-review-plugin"), + ImmutableSet.of(), ImmutableMap.of("download", new Link("http://download.hitchhiker.com")) ); @@ -101,6 +102,7 @@ class PluginCenterDtoMapperTest { "12345678aa", new Condition(Collections.singletonList("linux"), "amd64","2.0.0"), ImmutableSet.of("scm-review-plugin"), + ImmutableSet.of(), ImmutableMap.of("download", new Link("http://download.hitchhiker.com/review")) ); @@ -115,6 +117,7 @@ class PluginCenterDtoMapperTest { "555000444", new Condition(Collections.singletonList("linux"), "amd64","2.0.0"), ImmutableSet.of("scm-review-plugin"), + ImmutableSet.of(), ImmutableMap.of("download", new Link("http://download.hitchhiker.com/hitchhiker")) );