Merge branch 'develop' into feature/verify_gpg_signatures

This commit is contained in:
Eduard Heimbuch
2020-07-28 12:36:15 +02:00
100 changed files with 2329 additions and 1247 deletions

View File

@@ -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

View File

@@ -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)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 KiB

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -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.

View File

@@ -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.

View File

@@ -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)

View File

@@ -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;
}
```
<!--
TODO: does this set X-Forwarded Headers?
-->
## 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
<Location /scm>
Order allow,deny
Allow from all
Order allow,deny
Allow from all
</Location>
```
- **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
<!--
TODO: do we need it
-->
NOTE: This file is found in the installation directory, not the user\'s
home directory.
Uncomment following line:
```xml
<Set name="forwarded">true</Set>
```
Example:
```xml
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<Set name="host">
<SystemProperty name="jetty.host" />
</Set>
<Set name="port">
<SystemProperty name="jetty.port" default="8080"/>
</Set>
<!-- for mod_proxy -->
<Set name="forwarded">true</Set>
</New>
</Arg>
</Call>
```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 }
```

View File

@@ -1,117 +0,0 @@
---
title: SCM-Server SSL
---
<!--
TODO: Update
Node: https://ssl-config.mozilla.org/#server=jetty&version=9.4.28&config=intermediate&guideline=5.4
-->
**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 <scm>
(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
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
<Arg>
<!--
Exclude SSLv3 to avoid POODLE vulnerability.
See https://groups.google.com/d/msg/scmmanager/sX_Ydy-wAPA/-Dvs5i7RHtQJ
-->
<New class="org.eclipse.jetty.http.ssl.SslContextFactory">
<Set name="excludeProtocols">
<Array type="java.lang.String">
<Item>SSLv2Hello</Item>
<Item>SSLv3</Item>
</Array>
</Set>
</New>
</Arg>
<Set name="Port">8181</Set>
<Set name="maxIdleTime">30000</Set>
<Set name="keystore"><SystemProperty name="basedir" default="." />/conf/keystore.jks</Set>
<Set name="password">*password*</Set>
<Set name="keyPassword">*password*</Set>
<Set name="truststore"><SystemProperty name="basedir" default="." />/conf/keystore.jks</Set>
<Set name="trustPassword">*password*</Set>
</New>
</Arg>
</Call>
```
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)

View File

@@ -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
<!-- ssl configuration start -->
<New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory$Server">
<!--
path to your keystore, it can be a java keystore or in the pkcs12 format
-->
<Set name="KeyStorePath">
<SystemProperty name="basedir" default="."/>/conf/keystore.pkcs12
</Set>
<!--
use pkcs12 or jks for java keystore
-->
<Set name="KeyStoreType">PKCS12</Set>
<!--
the password of you keystore
-->
<Set name="KeyStorePassword">secret</Set>
<!--
For a more up to date list of ciphers and protocols, have a look at the mozilla ssl configurator:
https://ssl-config.mozilla.org/#server=jetty&version=9.4.28&config=intermediate&guideline=5.4
-->
<!-- TLS 1.3 requires Java 11 or higher -->
<Set name="IncludeProtocols">
<Array type="String">
<Item>TLSv1.2</Item>
<Item>TLSv1.3</Item>
</Array>
</Set>
<Set name="IncludeCipherSuites">
<Array type="String">
<Item>TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384</Item>
<Item>TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384</Item>
<Item>TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256</Item>
<Item>TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256</Item>
<Item>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256</Item>
<Item>TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256</Item>
<Item>TLS_DHE_RSA_WITH_AES_256_GCM_SHA384</Item>
<Item>TLS_DHE_RSA_WITH_AES_128_GCM_SHA256</Item>
</Array>
</Set>
<Set name="useCipherSuitesOrder">
<Property name="jetty.sslContext.useCipherSuitesOrder" default="false" />
</Set>
</New>
<New id="sslHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<Arg>
<Ref refid="httpConfig"/>
</Arg>
<Call name="addCustomizer">
<Arg>
<New class="org.eclipse.jetty.server.SecureRequestCustomizer">
<Arg name="sniRequired" type="boolean"><Property name="jetty.ssl.sniRequired" default="false"/></Arg>
<Arg name="sniHostCheck" type="boolean"><Property name="jetty.ssl.sniHostCheck" default="true"/></Arg>
<Arg name="stsMaxAgeSeconds" type="int"><Property name="jetty.ssl.stsMaxAgeSeconds" default="-1"/></Arg>
<Arg name="stsIncludeSubdomains" type="boolean"><Property name="jetty.ssl.stsIncludeSubdomains" default="false"/></Arg>
</New>
</Arg>
</Call>
</New>
<Call name="addConnector">
<Arg>
<New id="sslConnector" class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server">
<Ref refid="ScmServer" />
</Arg>
<Arg name="factories">
<Array type="org.eclipse.jetty.server.ConnectionFactory">
<Item>
<New class="org.eclipse.jetty.server.SslConnectionFactory">
<Arg name="next">http/1.1</Arg>
<Arg name="sslContextFactory">
<Ref refid="sslContextFactory"/>
</Arg>
</New>
</Item>
<Item>
<New class="org.eclipse.jetty.server.HttpConnectionFactory">
<Arg name="config">
<Ref refid="sslHttpConfig" />
</Arg>
</New>
</Item>
</Array>
</Arg>
<!--
Address to listen 0.0.0.0 means on every interface
-->
<Set name="host">
<SystemProperty name="jetty.host" default="0.0.0.0" />
</Set>
<!--
Port for the https connector
-->
<Set name="port">
<Property name="jetty.ssl.port" default="8443" />
</Set>
</New>
</Arg>
</Call>
<!-- ssl configuration end -->
```
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**).

View File

@@ -16,7 +16,7 @@
entries:
- /administration/basedirectory/
- /administration/logging/
- /administration/scm-server-ssl/
- /administration/scm-server/
- /administration/reverse-proxies/
- section: Development

View File

@@ -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)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 KiB

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 KiB

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 74 KiB

View File

@@ -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.

View File

@@ -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.

View File

@@ -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)

View File

@@ -5,5 +5,5 @@
],
"npmClient": "yarn",
"useWorkspaces": true,
"version": "2.3.0-SNAPSHOT"
"version": "2.3.0"
}

View File

@@ -32,7 +32,7 @@
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<packaging>pom</packaging>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<description>
The easiest way to share your Git, Mercurial
and Subversion repositories.
@@ -580,7 +580,7 @@
<plugin>
<groupId>sonia.scm.maven</groupId>
<artifactId>smp-maven-plugin</artifactId>
<version>1.0.0</version>
<version>1.1.0</version>
</plugin>
<plugin>
@@ -915,7 +915,7 @@
<jaxrs.version>2.1.1</jaxrs.version>
<resteasy.version>4.5.5.Final</resteasy.version>
<jersey-client.version>1.19.4</jersey-client.version>
<jackson.version>2.11.0</jackson.version>
<jackson.version>2.11.1</jackson.version>
<guice.version>4.2.3</guice.version>
<jaxb.version>2.3.3</jaxb.version>
<hibernate-validator.version>6.1.5.Final</hibernate-validator.version>

View File

@@ -31,12 +31,12 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-annotation-processor</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<name>scm-annotation-processor</name>
<dependencies>
@@ -46,7 +46,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-annotations</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</dependency>
<!-- rest api -->

View File

@@ -31,11 +31,11 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<artifactId>scm-annotations</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<name>scm-annotations</name>
<dependencies>

View File

@@ -31,11 +31,11 @@
<parent>
<artifactId>scm</artifactId>
<groupId>sonia.scm</groupId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<artifactId>scm-core</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<name>scm-core</name>
<dependencies>
@@ -54,7 +54,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-annotations</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</dependency>
<dependency>
@@ -222,28 +222,12 @@
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-jexl</artifactId>
<version>2.1.1</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- annotation processor -->
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-annotation-processor</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>

View File

@@ -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))

View File

@@ -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<String> dependencies;
private final Set<String> 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<String> dependencies, String url, String checksum) {
this(information, condition, dependencies, emptySet(), url, checksum);
}
public AvailablePluginDescriptor(PluginInformation information, PluginCondition condition, Set<String> dependencies, Set<String> 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<String> getDependencies() {
return dependencies;
}
@Override
public Set<String> getOptionalDependencies() {
return optionalDependencies;
}
}

View File

@@ -191,6 +191,7 @@ public final class InstalledPluginDescriptor extends ScmModule implements Plugin
*
* @since 2.0.0
*/
@Override
public Set<String> getOptionalDependencies() {
if (optionalDependencies == null)
{

View File

@@ -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<String> getDependencies();
default Set<String> getOptionalDependencies() {
return emptySet();
}
}

View File

@@ -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;
}

View File

@@ -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}.

View File

@@ -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<Cache<?, ?>> 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())

View File

@@ -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;
}

View File

@@ -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<String, Object> 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;
}
}

View File

@@ -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));
}
}

View File

@@ -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<String> list;
public EncodedStringList(List<String> list) {
this.list = list;
}
@Override
public String toString() {
return Joiner.on(',').join(Encoder.encode(list));
}
public List<String> getList() {
return list;
}
}

View File

@@ -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<String> encode(List<String> values) {
return Lists.transform(values, Encoder::encode);
}
}

View File

@@ -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());
}
}

View File

@@ -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()));
}
}

View File

@@ -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();
}
}

View File

@@ -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);

View File

@@ -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<String, Object> 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<String, Object> 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");
}
}

View File

@@ -31,11 +31,11 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<artifactId>scm-dao-xml</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<name>scm-dao-xml</name>
<dependencies>
@@ -50,7 +50,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</dependency>
<!-- test -->
@@ -58,7 +58,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>

View File

@@ -31,40 +31,40 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-it</artifactId>
<!-- we need type war, because the jetty plugin does not work with jar or pom -->
<packaging>war</packaging>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<name>scm-it</name>
<dependencies>
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-git-plugin</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-git-plugin</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
@@ -72,14 +72,14 @@
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-hg-plugin</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-hg-plugin</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
@@ -87,14 +87,14 @@
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-svn-plugin</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-svn-plugin</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>

View File

@@ -32,12 +32,12 @@
<parent>
<groupId>sonia.scm.packaging</groupId>
<artifactId>scm-packaging</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<artifactId>deb</artifactId>
<packaging>deb</packaging>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<description>Packaging for Debian/Ubuntu</description>
<name>deb</name>
@@ -46,7 +46,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-server</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</dependency>
</dependencies>
@@ -54,6 +54,30 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/deb/etc/scm</outputDirectory>
<resources>
<resource>
<directory>src/main/fs/etc/scm</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
@@ -135,7 +159,7 @@
<data>
<type>file</type>
<src>src/main/fs/etc/scm/logging.xml</src>
<src>${project.build.directory}/deb/etc/scm/logging.xml</src>
<dst>/etc/scm/logging.xml</dst>
<conffile>true</conffile>
<mapper>
@@ -148,7 +172,7 @@
<data>
<type>file</type>
<src>src/main/fs/etc/scm/server-config.xml</src>
<src>${project.build.directory}/deb/etc/scm/server-config.xml</src>
<dst>/etc/scm/server-config.xml</dst>
<conffile>true</conffile>
<mapper>

View File

@@ -27,6 +27,14 @@
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="ScmServer" class="org.eclipse.jetty.server.Server">
<!--
This default configuration should match 90% of the use cases,
if you have to change something ensure you know what you are doing.
For further information on configuration scm-server have a look at:
https://www.scm-manager.org/docs/${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.x/en/administration/scm-server/
-->
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<!-- increase header size for mercurial -->
<Set name="requestHeaderSize">16384</Set>
@@ -110,88 +118,4 @@
</New>
</Set>
<!-- TODO fix for jetty 9.2.x -->
<!-- request logging -->
<!--
<Ref id="RequestLog">
<Set name="requestLog">
<New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
<Arg><SystemProperty name="basedir" default="."/>/var/log/yyyy_mm_dd.request.log</Arg>
<Set name="retainDays">90</Set>
<Set name="append">true</Set>
<Set name="extended">false</Set>
<Set name="LogTimeZone">GMT</Set>
</New>
</Set>
</Ref>
-->
<!-- mod_proxy_ajp or mod_jk -->
<!--
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.ajp.Ajp13SocketConnector">
<Set name="port">8009</Set>
</New>
</Arg>
</Call>
-->
<!-- SSL-Connector -->
<!--
Documentation for the SSL-Connector:
http://wiki.eclipse.org/Jetty/Reference/SSL_Connectors
-->
<!--
Besure SSLv3 protocol is excluded to avoid POODLE vulnerability.
See https://groups.google.com/d/msg/scmmanager/sX_Ydy-wAPA/-Dvs5i7RHtQJ
-->
<!--
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
<Arg>
<New class="org.eclipse.jetty.http.ssl.SslContextFactory">
<Set name="excludeProtocols">
<Array type="java.lang.String">
<Item>SSLv2Hello</Item>
<Item>SSLv3</Item>
</Array>
</Set>
</New>
</Arg>
<Set name="Port">8181</Set>
<Set name="maxIdleTime">30000</Set>
<Set name="requestHeaderSize">16384</Set>
<Set name="keystore"><SystemProperty name="basedir" default="." />/conf/keystore.jks</Set>
<Set name="password">OBF:xxx</Set>
<Set name="keyPassword">OBF:xxx</Set>
<Set name="truststore"><SystemProperty name="basedir" default="." />/conf/keystore.jks</Set>
<Set name="trustPassword">OBF:xxx</Set>
</New>
</Arg>
</Call>
-->
<!-- JMX support -->
<!--
<Call id="MBeanServer" class="java.lang.management.ManagementFactory"
name="getPlatformMBeanServer" />
<New id="MBeanContainer" class="org.eclipse.jetty.jmx.MBeanContainer">
<Arg>
<Ref id="MBeanServer" />
</Arg>
</New>
<Get id="Container" name="container">
<Call name="addEventListener">
<Arg>
<Ref id="MBeanContainer" />
</Arg>
</Call>
</Get>
-->
</Configure>

View File

@@ -32,12 +32,12 @@
<parent>
<groupId>sonia.scm.packaging</groupId>
<artifactId>scm-packaging</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<artifactId>docker</artifactId>
<packaging>pom</packaging>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<dependencies>
@@ -113,6 +113,16 @@
<resource>
<directory>src/main/fs</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/scm/*</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/fs</directory>
<filtering>true</filtering>
<includes>
<include>**/scm/*</include>
</includes>
</resource>
</resources>
</configuration>

View File

@@ -27,6 +27,14 @@
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="ScmServer" class="org.eclipse.jetty.server.Server">
<!--
This default configuration should match 90% of the use cases,
if you have to change something ensure you know what you are doing.
For further information on configuration scm-server have a look at:
https://www.scm-manager.org/docs/${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.x/en/administration/scm-server/
-->
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<!-- increase header size for mercurial -->
<Set name="requestHeaderSize">16384</Set>
@@ -110,88 +118,4 @@
</New>
</Set>
<!-- TODO fix for jetty 9.2.x -->
<!-- request logging -->
<!--
<Ref id="RequestLog">
<Set name="requestLog">
<New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
<Arg><SystemProperty name="basedir" default="."/>/var/log/yyyy_mm_dd.request.log</Arg>
<Set name="retainDays">90</Set>
<Set name="append">true</Set>
<Set name="extended">false</Set>
<Set name="LogTimeZone">GMT</Set>
</New>
</Set>
</Ref>
-->
<!-- mod_proxy_ajp or mod_jk -->
<!--
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.ajp.Ajp13SocketConnector">
<Set name="port">8009</Set>
</New>
</Arg>
</Call>
-->
<!-- SSL-Connector -->
<!--
Documentation for the SSL-Connector:
http://wiki.eclipse.org/Jetty/Reference/SSL_Connectors
-->
<!--
Besure SSLv3 protocol is excluded to avoid POODLE vulnerability.
See https://groups.google.com/d/msg/scmmanager/sX_Ydy-wAPA/-Dvs5i7RHtQJ
-->
<!--
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
<Arg>
<New class="org.eclipse.jetty.http.ssl.SslContextFactory">
<Set name="excludeProtocols">
<Array type="java.lang.String">
<Item>SSLv2Hello</Item>
<Item>SSLv3</Item>
</Array>
</Set>
</New>
</Arg>
<Set name="Port">8181</Set>
<Set name="maxIdleTime">30000</Set>
<Set name="requestHeaderSize">16384</Set>
<Set name="keystore"><SystemProperty name="basedir" default="." />/conf/keystore.jks</Set>
<Set name="password">OBF:xxx</Set>
<Set name="keyPassword">OBF:xxx</Set>
<Set name="truststore"><SystemProperty name="basedir" default="." />/conf/keystore.jks</Set>
<Set name="trustPassword">OBF:xxx</Set>
</New>
</Arg>
</Call>
-->
<!-- JMX support -->
<!--
<Call id="MBeanServer" class="java.lang.management.ManagementFactory"
name="getPlatformMBeanServer" />
<New id="MBeanContainer" class="org.eclipse.jetty.jmx.MBeanContainer">
<Arg>
<Ref id="MBeanServer" />
</Arg>
</New>
<Get id="Container" name="container">
<Call name="addEventListener">
<Arg>
<Ref id="MBeanContainer" />
</Arg>
</Call>
</Get>
-->
</Configure>

View File

@@ -32,12 +32,12 @@
<parent>
<groupId>sonia.scm.packaging</groupId>
<artifactId>scm-packaging</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<artifactId>helm</artifactId>
<packaging>helm</packaging>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<properties>
<helm.version>3.2.1</helm.version>

View File

@@ -31,19 +31,37 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.packaging</groupId>
<artifactId>scm-packaging</artifactId>
<packaging>pom</packaging>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<properties>
<deployment.serverId>packages.scm-manager.org</deployment.serverId>
<deployment.target>https://packages.scm-manager.org</deployment.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>parse-version</id>
<goals>
<goal>parse-version</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>packaging</id>

View File

@@ -32,12 +32,12 @@
<parent>
<groupId>sonia.scm.packaging</groupId>
<artifactId>scm-packaging</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<artifactId>release-yaml</artifactId>
<packaging>pom</packaging>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<build>
<plugins>

View File

@@ -32,12 +32,12 @@
<parent>
<groupId>sonia.scm.packaging</groupId>
<artifactId>scm-packaging</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<artifactId>rpm</artifactId>
<packaging>rpm</packaging>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<description>Packaging for RedHat/Centos/Fedora</description>
<name>rpm</name>
@@ -52,7 +52,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-server</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</dependency>
</dependencies>
@@ -60,6 +60,30 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/rpm/etc/scm</outputDirectory>
<resources>
<resource>
<directory>src/main/fs/etc/scm</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
@@ -172,7 +196,7 @@
<entry>
<name>/etc/scm/logging.xml</name>
<file>src/main/fs/etc/scm/logging.xml</file>
<file>${project.build.directory}/rpm/etc/scm/logging.xml</file>
<user>root</user>
<group>scm</group>
<mode>0640</mode>
@@ -181,7 +205,7 @@
<entry>
<name>/etc/scm/server-config.xml</name>
<file>src/main/fs/etc/scm/server-config.xml</file>
<file>${project.build.directory}/rpm/etc/scm/server-config.xml</file>
<user>root</user>
<group>scm</group>
<mode>0640</mode>

View File

@@ -27,6 +27,14 @@
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="ScmServer" class="org.eclipse.jetty.server.Server">
<!--
This default configuration should match 90% of the use cases,
if you have to change something ensure you know what you are doing.
For further information on configuration scm-server have a look at:
https://www.scm-manager.org/docs/${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.x/en/administration/scm-server/
-->
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<!-- increase header size for mercurial -->
<Set name="requestHeaderSize">16384</Set>
@@ -109,89 +117,5 @@
</Set>
</New>
</Set>
<!-- TODO fix for jetty 9.2.x -->
<!-- request logging -->
<!--
<Ref id="RequestLog">
<Set name="requestLog">
<New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
<Arg><SystemProperty name="basedir" default="."/>/var/log/yyyy_mm_dd.request.log</Arg>
<Set name="retainDays">90</Set>
<Set name="append">true</Set>
<Set name="extended">false</Set>
<Set name="LogTimeZone">GMT</Set>
</New>
</Set>
</Ref>
-->
<!-- mod_proxy_ajp or mod_jk -->
<!--
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.ajp.Ajp13SocketConnector">
<Set name="port">8009</Set>
</New>
</Arg>
</Call>
-->
<!-- SSL-Connector -->
<!--
Documentation for the SSL-Connector:
http://wiki.eclipse.org/Jetty/Reference/SSL_Connectors
-->
<!--
Besure SSLv3 protocol is excluded to avoid POODLE vulnerability.
See https://groups.google.com/d/msg/scmmanager/sX_Ydy-wAPA/-Dvs5i7RHtQJ
-->
<!--
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
<Arg>
<New class="org.eclipse.jetty.http.ssl.SslContextFactory">
<Set name="excludeProtocols">
<Array type="java.lang.String">
<Item>SSLv2Hello</Item>
<Item>SSLv3</Item>
</Array>
</Set>
</New>
</Arg>
<Set name="Port">8181</Set>
<Set name="maxIdleTime">30000</Set>
<Set name="requestHeaderSize">16384</Set>
<Set name="keystore"><SystemProperty name="basedir" default="." />/conf/keystore.jks</Set>
<Set name="password">OBF:xxx</Set>
<Set name="keyPassword">OBF:xxx</Set>
<Set name="truststore"><SystemProperty name="basedir" default="." />/conf/keystore.jks</Set>
<Set name="trustPassword">OBF:xxx</Set>
</New>
</Arg>
</Call>
-->
<!-- JMX support -->
<!--
<Call id="MBeanServer" class="java.lang.management.ManagementFactory"
name="getPlatformMBeanServer" />
<New id="MBeanContainer" class="org.eclipse.jetty.jmx.MBeanContainer">
<Arg>
<Ref id="MBeanServer" />
</Arg>
</New>
<Get id="Container" name="container">
<Call name="addEventListener">
<Arg>
<Ref id="MBeanContainer" />
</Arg>
</Call>
</Get>
-->
</Configure>

View File

@@ -24,20 +24,19 @@
SOFTWARE.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>sonia.scm.packaging</groupId>
<artifactId>scm-packaging</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<artifactId>unix</artifactId>
<packaging>pom</packaging>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<dependencies>

View File

@@ -39,9 +39,23 @@
<fileSets>
<!--
we have to filter server-config.xml and logging.xml,
in order to add the correct link to the documentation
-->
<fileSet>
<directory>src/main/fs/conf</directory>
<filtered>true</filtered>
<outputDirectory>conf</outputDirectory>
</fileSet>
<fileSet>
<directory>src/main/fs</directory>
<filtered>false</filtered>
<excludes>
<exclude>conf/**</exclude>
</excludes>
<outputDirectory></outputDirectory>
</fileSet>

View File

@@ -27,6 +27,14 @@
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="ScmServer" class="org.eclipse.jetty.server.Server">
<!--
This default configuration should match 90% of the use cases,
if you have to change something ensure you know what you are doing.
For further information on configuration scm-server have a look at:
https://www.scm-manager.org/docs/${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.x/en/administration/scm-server/
-->
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<!-- increase header size for mercurial -->
<Set name="requestHeaderSize">16384</Set>
@@ -113,89 +121,5 @@
</Set>
</New>
</Set>
<!-- TODO fix for jetty 9.2.x -->
<!-- request logging -->
<!--
<Ref id="RequestLog">
<Set name="requestLog">
<New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
<Arg><SystemProperty name="basedir" default="."/>/var/log/yyyy_mm_dd.request.log</Arg>
<Set name="retainDays">90</Set>
<Set name="append">true</Set>
<Set name="extended">false</Set>
<Set name="LogTimeZone">GMT</Set>
</New>
</Set>
</Ref>
-->
<!-- mod_proxy_ajp or mod_jk -->
<!--
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.ajp.Ajp13SocketConnector">
<Set name="port">8009</Set>
</New>
</Arg>
</Call>
-->
<!-- SSL-Connector -->
<!--
Documentation for the SSL-Connector:
http://wiki.eclipse.org/Jetty/Reference/SSL_Connectors
-->
<!--
Besure SSLv3 protocol is excluded to avoid POODLE vulnerability.
See https://groups.google.com/d/msg/scmmanager/sX_Ydy-wAPA/-Dvs5i7RHtQJ
-->
<!--
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
<Arg>
<New class="org.eclipse.jetty.http.ssl.SslContextFactory">
<Set name="excludeProtocols">
<Array type="java.lang.String">
<Item>SSLv2Hello</Item>
<Item>SSLv3</Item>
</Array>
</Set>
</New>
</Arg>
<Set name="Port">8181</Set>
<Set name="maxIdleTime">30000</Set>
<Set name="requestHeaderSize">16384</Set>
<Set name="keystore"><SystemProperty name="basedir" default="." />/conf/keystore.jks</Set>
<Set name="password">OBF:xxx</Set>
<Set name="keyPassword">OBF:xxx</Set>
<Set name="truststore"><SystemProperty name="basedir" default="." />/conf/keystore.jks</Set>
<Set name="trustPassword">OBF:xxx</Set>
</New>
</Arg>
</Call>
-->
<!-- JMX support -->
<!--
<Call id="MBeanServer" class="java.lang.management.ManagementFactory"
name="getPlatformMBeanServer" />
<New id="MBeanContainer" class="org.eclipse.jetty.jmx.MBeanContainer">
<Arg>
<Ref id="MBeanServer" />
</Arg>
</New>
<Get id="Container" name="container">
<Call name="addEventListener">
<Arg>
<Ref id="MBeanContainer" />
</Arg>
</Call>
</Get>
-->
</Configure>

View File

@@ -32,12 +32,12 @@
<parent>
<groupId>sonia.scm.packaging</groupId>
<artifactId>scm-packaging</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<artifactId>windows</artifactId>
<packaging>pom</packaging>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<dependencies>

View File

@@ -39,12 +39,26 @@
<fileSets>
<!--
we have to filter server-config.xml and logging.xml,
in order to add the correct link to the documentation
-->
<fileSet>
<directory>src/main/fs/conf</directory>
<filtered>true</filtered>
<outputDirectory>conf</outputDirectory>
</fileSet>
<fileSet>
<directory>src/main/fs</directory>
<filtered>false</filtered>
<excludes>
<exclude>conf/**</exclude>
</excludes>
<outputDirectory></outputDirectory>
</fileSet>
<fileSet>
<directory>target/windows</directory>
<filtered>false</filtered>

View File

@@ -27,6 +27,14 @@
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="ScmServer" class="org.eclipse.jetty.server.Server">
<!--
This default configuration should match 90% of the use cases,
if you have to change something ensure you know what you are doing.
For further information on configuration scm-server have a look at:
https://www.scm-manager.org/docs/${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.x/en/administration/scm-server/
-->
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<!-- increase header size for mercurial -->
<Set name="requestHeaderSize">16384</Set>
@@ -114,89 +122,5 @@
</Set>
</New>
</Set>
<!-- TODO fix for jetty 9.2.x -->
<!-- request logging -->
<!--
<Ref id="RequestLog">
<Set name="requestLog">
<New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
<Arg><SystemProperty name="basedir" default="."/>/var/log/yyyy_mm_dd.request.log</Arg>
<Set name="retainDays">90</Set>
<Set name="append">true</Set>
<Set name="extended">false</Set>
<Set name="LogTimeZone">GMT</Set>
</New>
</Set>
</Ref>
-->
<!-- mod_proxy_ajp or mod_jk -->
<!--
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.ajp.Ajp13SocketConnector">
<Set name="port">8009</Set>
</New>
</Arg>
</Call>
-->
<!-- SSL-Connector -->
<!--
Documentation for the SSL-Connector:
http://wiki.eclipse.org/Jetty/Reference/SSL_Connectors
-->
<!--
Besure SSLv3 protocol is excluded to avoid POODLE vulnerability.
See https://groups.google.com/d/msg/scmmanager/sX_Ydy-wAPA/-Dvs5i7RHtQJ
-->
<!--
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
<Arg>
<New class="org.eclipse.jetty.http.ssl.SslContextFactory">
<Set name="excludeProtocols">
<Array type="java.lang.String">
<Item>SSLv2Hello</Item>
<Item>SSLv3</Item>
</Array>
</Set>
</New>
</Arg>
<Set name="Port">8181</Set>
<Set name="maxIdleTime">30000</Set>
<Set name="requestHeaderSize">16384</Set>
<Set name="keystore"><SystemProperty name="basedir" default="." />/conf/keystore.jks</Set>
<Set name="password">OBF:xxx</Set>
<Set name="keyPassword">OBF:xxx</Set>
<Set name="truststore"><SystemProperty name="basedir" default="." />/conf/keystore.jks</Set>
<Set name="trustPassword">OBF:xxx</Set>
</New>
</Arg>
</Call>
-->
<!-- JMX support -->
<!--
<Call id="MBeanServer" class="java.lang.management.ManagementFactory"
name="getPlatformMBeanServer" />
<New id="MBeanContainer" class="org.eclipse.jetty.jmx.MBeanContainer">
<Arg>
<Ref id="MBeanServer" />
</Arg>
</New>
<Get id="Container" name="container">
<Call name="addEventListener">
<Arg>
<Ref id="MBeanContainer" />
</Arg>
</Call>
</Get>
-->
</Configure>

View File

@@ -31,13 +31,13 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-plugins</artifactId>
<packaging>pom</packaging>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<name>scm-plugins</name>
<modules>
@@ -59,7 +59,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
@@ -68,7 +68,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-annotation-processor</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
@@ -98,7 +98,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>

View File

@@ -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"
}
}

View File

@@ -31,7 +31,7 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<artifactId>scm-git-plugin</artifactId>

View File

@@ -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);

View File

@@ -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<Object> 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");

View File

@@ -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"
}
}

View File

@@ -31,7 +31,7 @@
<parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-plugins</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<artifactId>scm-hg-plugin</artifactId>

View File

@@ -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"
}
}

View File

@@ -29,12 +29,12 @@
<parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-plugins</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<artifactId>scm-legacy-plugin</artifactId>
<description>Support migrated repository urls and v1 passwords</description>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<packaging>smp</packaging>
<dependencies>

View File

@@ -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"
}
}

View File

@@ -31,7 +31,7 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<artifactId>scm-svn-plugin</artifactId>

View File

@@ -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<File, File> 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());
}

View File

@@ -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<File, File> 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");

View File

@@ -31,12 +31,12 @@
<parent>
<artifactId>scm</artifactId>
<groupId>sonia.scm</groupId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-server</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<name>scm-server</name>
<packaging>jar</packaging>

View File

@@ -31,12 +31,12 @@
<parent>
<artifactId>scm</artifactId>
<groupId>sonia.scm</groupId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<name>scm-test</name>
<dependencies>
@@ -50,7 +50,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</dependency>
<dependency>

View File

@@ -32,13 +32,13 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-ui</artifactId>
<packaging>war</packaging>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<name>scm-ui</name>
<properties>

View File

@@ -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",

View File

@@ -55,4 +55,9 @@ storiesOf("SyntaxHighlighter", module)
<Spacing>
<SyntaxHighlighter language="python" value={PyHttpServer} />
</Spacing>
))
.add("Without line numbers", () => (
<Spacing>
<SyntaxHighlighter language="java" value={JavaHttpServer} showLineNumbers={false} />
</Spacing>
));

View File

@@ -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<Props> {
static defaultProps: Partial<Props> = {
language: defaultLanguage
language: defaultLanguage,
showLineNumbers: true
};
getLanguage = () => {
@@ -48,9 +50,10 @@ class SyntaxHighlighter extends React.Component<Props> {
};
render() {
const { showLineNumbers } = this.props;
const language = this.getLanguage();
return (
<ReactSyntaxHighlighter showLineNumbers={false} language={language} style={arduinoLight}>
<ReactSyntaxHighlighter showLineNumbers={showLineNumbers} language={language} style={arduinoLight}>
{this.props.value}
</ReactSyntaxHighlighter>
);

File diff suppressed because it is too large Load Diff

View File

@@ -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",

View File

@@ -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"

View File

@@ -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": [

View File

@@ -36,6 +36,7 @@ export type Plugin = {
pending: boolean;
markedForUninstall?: boolean;
dependencies: string[];
optionalDependencies: string[];
_links: Links;
};

View File

@@ -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",

View File

@@ -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:",

View File

@@ -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:",

View File

@@ -183,6 +183,27 @@ class PluginModal extends React.Component<Props, State> {
return dependencies;
}
renderOptionalDependencies() {
const { plugin, t } = this.props;
let optionalDependencies = null;
if (plugin.optionalDependencies && plugin.optionalDependencies.length > 0) {
optionalDependencies = (
<div className="media">
<Notification type="warning">
<strong>{t("plugins.modal.optionalDependencyNotification")}</strong>
<ul>
{plugin.optionalDependencies.map((optionalDependency, index) => {
return <li key={index}>{optionalDependency}</li>;
})}
</ul>
</Notification>
</div>
);
}
return optionalDependencies;
}
renderNotifications = () => {
const { t, pluginAction } = this.props;
const { restart, error, success } = this.state;
@@ -275,6 +296,7 @@ class PluginModal extends React.Component<Props, State> {
</div>
)}
{this.renderDependencies()}
{this.renderOptionalDependencies()}
</div>
</div>
<div className="media">

View File

@@ -32,13 +32,13 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-webapp</artifactId>
<packaging>war</packaging>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<name>scm-webapp</name>
<dependencies>
@@ -48,7 +48,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-annotation-processor</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
@@ -73,13 +73,13 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-dao-xml</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
</dependency>
<!-- security -->
@@ -343,7 +343,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<scope>test</scope>
<exclusions>
<exclusion>
@@ -405,7 +405,7 @@
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-git-plugin</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
@@ -413,14 +413,14 @@
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-git-plugin</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-hg-plugin</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
@@ -428,14 +428,14 @@
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-hg-plugin</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-svn-plugin</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
@@ -443,7 +443,7 @@
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-svn-plugin</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
@@ -729,7 +729,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-ui</artifactId>
<version>2.3.0-SNAPSHOT</version>
<version>2.4.0-SNAPSHOT</version>
<type>war</type>
</dependency>

View File

@@ -53,6 +53,7 @@ public class PluginDto extends HalRepresentation {
private Boolean core;
private Boolean markedForUninstall;
private Set<String> dependencies;
private Set<String> optionalDependencies;
public PluginDto(Links links) {
add(links);

View File

@@ -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");

View File

@@ -253,21 +253,40 @@ public class DefaultPluginManager implements PluginManager {
private void collectPluginsToInstallOrUpdate(List<AvailablePlugin> plugins, String name) {
if (!isInstalledOrPending(name) || isUpdatable(name)) {
AvailablePlugin plugin = getAvailable(name).orElseThrow(() -> NotFoundException.notFound(entity(AvailablePlugin.class, name)));
Set<String> 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<AvailablePlugin> 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<AvailablePlugin> plugins, String name) {
AvailablePlugin plugin = getAvailable(name).orElseThrow(() -> NotFoundException.notFound(entity(AvailablePlugin.class, name)));
Set<String> dependencies = plugin.getDescriptor().getDependencies();
if (dependencies != null) {
for (String dependency : dependencies) {
collectPluginsToInstallOrUpdate(plugins, dependency);
}
}
Set<String> 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();
}

View File

@@ -85,6 +85,9 @@ public final class PluginCenterDto implements Serializable {
@XmlElement(name = "dependencies")
private Set<String> dependencies;
@XmlElement(name = "optionalDependencies")
private Set<String> optionalDependencies;
@XmlElement(name = "_links")
private Map<String, Link> links;
}

View File

@@ -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));
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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");

View File

@@ -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"))
);