Correct migration of old documentation

This commit is contained in:
Florian Scholdei
2020-03-31 17:28:30 +02:00
parent ac66e6097e
commit fad91d5511
66 changed files with 2362 additions and 1931 deletions

View File

@@ -1,3 +1,3 @@
# API and concepts changes from SCM-Manger v1 to v2
TODO document api and concept changes while we're migrating plugins
*TODO:* document api and concept changes while we're migrating plugins

View File

@@ -8,59 +8,50 @@ A react component is updated without any changes in the props or states.
### Fix
Use the [why-did-you-update](Link https://github.com/maicki/why-did-you-update) library to analyze the causes of the updates.
Use the [why-did-you-update](https://github.com/maicki/why-did-you-update) library to analyze the causes of the updates.
A common cause is the definition of[ new functions in render()](Link https://github.com/maicki/why-did-you-update#changes-are-in-functions-only).
A common cause is the definition of [new functions in render()](https://github.com/maicki/why-did-you-update#changes-are-in-functions-only).
### Example
```
#!javascript
```javascript
class Main extends React.Component<Props> {
render() {
const { authenticated, links } = this.props;
const redirectUrlFactory = binder.getExtension("main.redirect", this.props);
....
...
const ActivityRoute = ({ authenticated, links }: RouteProps) => {
return (
<ProtectedRoute
path="/activity"
component={() => <Activity activityUrl={links.activity.href} />}
authenticated={authenticated && links.activity.href}
/>
);
};
const ActivityRoute = ({ authenticated, links }: RouteProps) => {
return (
<ProtectedRoute
path="/activity"
component={() => <Activity activityUrl={links.activity.href} />}
authenticated={authenticated && links.activity.href}
/>
);
};
}
}
binder.bind("main.route", ActivityRoute);
```
the definition of the Component like this:
```javascript
component={() => <Activity activityUrl={links.activity.href} />}
```
#!javascript
component={() => <Activity activityUrl=links.activity.href} />}
```
triggers a re-render because:
```
#!javascript
() => <Activity activityUrl=links.activity.href} /> !== () => <Activity activityUrl=links.activity.href} />
```javascript
() => <Activity activityUrl={links.activity.href} /> !== () => <Activity activityUrl={links.activity.href} />
```
You can avoid it by binding this function in advance and then reusing it on all renders
```
#!javascript
```javascript
class ActivityRoute extends React.Component<Props> {
constructor(props: Props) {
super(props);
@@ -85,4 +76,4 @@ class ActivityRoute extends React.Component<Props> {
}
binder.bind("main.route", ActivityRoute);
```
```

View File

@@ -1,6 +1,6 @@
[TOC]
# Descision Table
# Lombok #
### Lombok
[Project Lombok](https://projectlombok.org/) provides an easy way to generate java beans with
@@ -26,11 +26,11 @@ The following lombok annotations will be used for DTOs:
will be present. Because this one is necessary for deserialization, this one has to be created
explicitly when the all-args constructor is declared)
# /repo/ & /repos/ as URI prefixes #
### /repo/ & /repos/ as URI prefixes
The URI-format for accessing a repository, be it with a browser, or cloning/pulling via git/hg/svn, is defined to be `/repo/:namespace/:name`. The decision was made to allow users to choose namespaces as they please. If there would not be a prefix, some namespaces (e.g. `user`, `users`) would have to be reserved, since the names are already in use by SCM Manager itself. The `/repos` URI linked to a list of repositories, as well as operations such as creating a repositoriy (`/repos/create`).
# Error handling
### Error handling
In v1 error handling was somewhat diverse. Some checks were made explicitly in the web resource classes leading
to direct responses, some were made using exceptions and matching exception mappers.
@@ -53,7 +53,7 @@ in runtime exceptions like `RepositoryException` and will lead to internal serve
For simple objects like users and groups we don't think that we will need more exceptions.
# Logging
### Logging
Logging can be cucial when it comes to identify bugs in test or production environments. At implementation time one cannot foresee all possible error cases and therefore cannot determine with full certanty what informations will be needed and what can be neglected. Logging only crucial errors leaves the developer with no idea what events might have lead to the error. On the other hand logging too much will overburden the log, making it harder to handle and maybe hiding interesting steps.
@@ -67,7 +67,7 @@ Therefore it is best practice to be able to select the detail level of informati
As a default the log level for SCM-Manager is INFO, so that by default all logs with the levels ERROR, WARN and INFO are stored. Finer levels can be enabled manually.
## Log levels to use
### Log levels to use
We have agreed to apply to the following guidelines regarding log levels:
@@ -87,4 +87,4 @@ We have agreed to apply to the following guidelines regarding log levels:
- concurrent modifications
- validation errors
- TRACE should be used for normal steps that might be of interest, like
- calling functions
- calling functions

View File

@@ -74,11 +74,7 @@ The following extension points are provided for the frontend:
**example:**
```
#!javascript
```javascript
let MarkdownFactory = (renderContext) => {
let Heading= (props) => {
@@ -89,20 +85,13 @@ let MarkdownFactory = (renderContext) => {
return {heading : Heading};
};
binder.bind("markdown-renderer-factory", MarkdownFactory);
```
```
#!javascript
```javascript
<MarkdownView
renderContext={{pullRequest, repository}}
className="content"
content={pullRequest.description}
/>
```
```

View File

@@ -1,3 +1,5 @@
# Known Issues
## Asnychronous PreReceiveRepositoryHooks do not work with subversion
The following example will fail to log the changesets.
@@ -26,7 +28,6 @@ public class DemoHook {
}
}
```
This is because of the transaction management of subversion. The scm-manager subversion provider becomes a transaction id for the changes of the current push, but the transaction has finished before scm-manager can resolve the incoming commit. To solve the issue, we could use a synchronous subscription instead e.g.:
@@ -55,5 +56,4 @@ public class DemoHook {
}
}
```
```

View File

@@ -1,6 +1,6 @@
# Migrate an v1 plugin
Before starting, make sure to read the [[v2/Plugin Development|Plugin Development]]
Before starting, make sure to read the [Plugin Development](Plugin%20Development.md)
**NOTE**: until there is no release the current version of scm-manager has to be cloned and build on the machine
of the plugin developer.
@@ -25,7 +25,6 @@ To migrate an existing SCM-Manager 1.x Plugin, you have to do the following step
* remove the sonia.scm.maven:scm-maven-plugin from the pom
* remove servlet-api from the list of dependencies (not always the case)
```diff
diff -r a988f4cfb7ab pom.xml
--- a/pom.xml Thu Dec 10 20:32:26 2015 +0100
@@ -124,7 +123,7 @@ diff -r a988f4cfb7ab src/main/resources/META-INF/scm/plugin.xml
### Java sources (src/main/java)
* try to compile the sources: `mvn compile`
* fix problems (See [[v2/API changes|API changes]])
* fix problems (See [API changes](API%20changes.md))
* Remove XML accept headers from REST Resource classes -> SCMMv2 supports JSON only
* Migrate REST Resources (e.g. `v2`, add to Index Resource, Update Links) - See core plugins Git, Hg, Svn, e.g. [`GitConfigResource`](https://bitbucket.org/sdorra/scm-manager/src/3d5a24c177f33c14a7c08f19e124be03b1a877ba/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/api/v2/resources/GitConfigResource.java)
@@ -132,6 +131,7 @@ diff -r a988f4cfb7ab src/main/resources/META-INF/scm/plugin.xml
* remove all SCM-Manager 1.x ui code from resource directory (src/main/resources)
* create package.json with the following content (replace name-of-plugin with the name of your plugin):
```json
{
"name": "@scm-manager/name-of-plugin",
@@ -151,6 +151,7 @@ diff -r a988f4cfb7ab src/main/resources/META-INF/scm/plugin.xml
}
}
```
* run `mvn process-resources` to install the required JavaScript libraries
* run `yarn run ui-bundler init` to create frontend configuration files (TODO add maven goal/phase)
* create new ui at `src/main/js` (for JavaScript code) and `src/main/webapp` (for static files) (TODO more help)
@@ -161,12 +162,12 @@ Some more hints:
* For Configuration UIs use [`ConfigurationBinder`](https://bitbucket.org/sdorra/scm-manager/src/c888128358712ab1f5f34ff593e1cf6854b06c08/scm-ui-components/packages/ui-components/src/config/ConfigurationBinder.js) - See core plugins Git, Hg, Svn, e.g. [scm-git-plugin/index.js](https://bitbucket.org/sdorra/scm-manager/src/6d64a380a37db63c95eccbfbf18e4500c9224d32/scm-plugins/scm-git-plugin/src/main/js/index.js).
Note that `readOnly` property checks if update link is returned by REST resource
* Don't forget [i18n](https://bitbucket.org/sdorra/scm-manager/wiki/v2/i18n%20for%20Plugins)
* If you need to add extension points to core SCMM, you can link your local development instance into smp-maven-plugin, see [scm-review-plugin/pom.xml](https://bitbucket.org/scm-manager/scm-review-plugin/src/0ea74634830ef4865afacf714de009302e26353d/pom.xml#lines-72)
* Don't forget [i18n for Plugins](i18n%20for%20Plugins.md)
* If you need to add extension points to core SCMM, you can link your local development instance into smp-maven-plugin, see [scm-review-plugin/pom.xml](https://github.com/scm-manager/scm-review-plugin/commit/0ea74634830ef4865afacf714de009302e26353d#diff-600376dffeb79835ede4a0b285078036R72)
# Further reading
* [scm-manager/ui-extensions README](https://bitbucket.org/scm-manager/ui-extensions/src/master/README.md) - Extension Points within SCM-Manager
* [scm-manager/ui-components](https://bitbucket.org/sdorra/scm-manager/src/6d64a380a37db63c95eccbfbf18e4500c9224d32/scm-ui-components/) - Reusable UI components within SCM-Manager
* [smp-maven-plugin](https://bitbucket.org/scm-manager/smp-maven-plugin/src/default/) - Plugin that facilitates efficient plugin development for SCMM
* [scm-manager/ui-extensions README](../../scm-ui/ui-extensions/README.md) - Extension Points within SCM-Manager
* [scm-manager/ui-components](https://bitbucket.org/sdorra/scm-manager/src/6d64a380a37db63c95eccbfbf18e4500c9224d32/scm-ui-components/) - Reusable UI components within SCM-Manager
* [smp-maven-plugin](https://bitbucket.org/scm-manager/smp-maven-plugin/src/default/) - Plugin that facilitates efficient plugin development for SCMM
* [ui-bundler](https://bitbucket.org/scm-manager/ui-bundler/src/master/) - Bundles the UI Resources for plugins

View File

@@ -1,8 +1,8 @@
# Permission Concept
This documents describes a concept for a fine-grained permission managing via the SCMMv2 UI.
[TOC]
# Requirements
## Requirements
* Provide at least the features of SCMMv1 including the scm-groupmanager and scm-userrepo plugins.
* In addition, the permissions on repositories should be more fine-grained, for example a user that does not have the
@@ -10,11 +10,11 @@ This documents describes a concept for a fine-grained permission managing via th
* An ideal solution would be generic. That is, not implementing explicit features such as the groupmanager or userrepo.
SCMMv2 already evaluates fine-grained permissions, so why not allow our users to assign them?
# Technical Foundations
## Technical Foundations
## Status Quo SCMv1
### Status Quo SCMv1
[SCMMv1 's permissions](../Permissions) are only related to Repositories:
[SCMMv1 's permissions](../Permissions.md) are only related to Repositories:
* Users can either have the Permission READ, WRITER or OWNER
* globally (for all repositories) or
@@ -28,7 +28,7 @@ Some more permission-related features are added by plugins:
* [scm-groupmanager-plugin](https://bitbucket.org/triologygmbh/scm-groupmanager-plugin/): Allows users to administer groups
* [scm-userrepo-plugin](https://bitbucket.org/sdorra/scm-userrepo-plugin/): Allows users to create repositories
## SCMMv2 Permission fundamentals
### SCMMv2 Permission fundamentals
SCMMv2 introduces much more fine-grained permission checks under the hood.
In the code permissions for all kinds of operations are designed as follows:
@@ -44,7 +44,7 @@ In addition, there are permissions that do not relate to an item, which are call
The challenge solved by this document is to provide a concept that allows SCMMv2 users to manage these permissions.
That is, to assign those permissions to users and groups via the UI or REST API.
## SCMMv2 implementation details
### SCMMv2 implementation details
This is not a core part of the concept but might be interesting when implementing it.
@@ -82,7 +82,7 @@ When a user logs in, all different kinds of permissions (`*` if admin, permissio
from groups, some additional technical permissions such as `autocomplete`, etc.) are collected and added to the Shiro
subject in the `DefaultAuthorizationCollector` class.
## SCMMv2 Core permissions
### SCMMv2 Core permissions
Here are some more examples of permissions existing in SCMMv2 core, at the time of writing.
Look for `@StaticPermissions` and note that there the annotation also declares defaults for `permissions` and `globalPermissions`.
@@ -105,25 +105,25 @@ Look for `@StaticPermissions` and note that there the annotation also declares d
* Permissions: read, modify, delete, healthCheck, pull, push, permissionRead, permissionWrite
* Items are the technical ID of dynamically added repositories
# Repository and global permissions
## Repository and global permissions
In order to fulfill the requirements, this concept describes
* how to extend the existing repository permissions to be more fine-grained
* a new dialog to assign global permissions on user or group level
# UI / UX
## UI / UX
## Global permissions
### Global permissions
The global permission component can be reached from **either user and groups** components navigations. The following mockup
shows this in the user component:
![Permissions-mockup-user](Permissions-mockup-user.jpg).
![Permissions-mockup-user](Permissions-mockup-user.jpg)
The layout of the permission component UI could look like this:
![Permissions-mockup-global-permissions](Permissions-mockup-global-permissions.jpg).
![Permissions-mockup-global-permissions](Permissions-mockup-global-permissions.jpg)
The UI
* queries all available global permissions from the REST API (shiro strings),
@@ -131,7 +131,7 @@ The UI
* displays descriptions as tooltips,
* and queries all user/group permissions to populate the check boxes.
## Repository permissions
### Repository permissions
The repository permission are already implemented and can be reached via Repositories | Permissions. Right now, it
allows for assigning the roles READ, WRITE, OWNER as in SCMMv1 (see above). Internally they are mapped to shiro
@@ -139,9 +139,9 @@ permissions (see `PermissionType`).
The UI is extended like so:
![Permissions-mockup-repository-permissions](Permissions-mockup-repository-permissions.jpg).
![Permissions-mockup-repository-permissions](Permissions-mockup-repository-permissions.jpg)
### Existing repository dialog
#### Existing repository dialog
* queries all available repository permissions (shiro strings) and roles from the REST API,
* queries all user/group permissions of the repository (shiro strings) and aggregates them to roles to populate the
@@ -149,25 +149,25 @@ The UI is extended like so:
* Note that the permissions are always stored as shiro strings not roles.
* A new `Advanced` button per user or group entry opens a modal dialog
### New modal dialog
#### New modal dialog
* The modal dialog shows all available repository permissions (shiro strings)
* via the shiro string the display name and descriptions are found (see i18n),
* displays descriptions as tooltips,
* the individual user/group permission of the repo are used to populate the check boxes
# REST API
## REST API
Note that the examples here are not specified in HAL/HATEOAS for brevity.
## Global permissions
### Global permissions
Assigning global permissions must be implemented for **either user and groups**!
Both use the same available permissions.
The following shows user as an example.
### Available global permissions
#### Available global permissions
* URL: `/globalPermissions`
* HTTP Method: GET
@@ -189,7 +189,7 @@ The following shows user as an example.
}
```
### Assigned global permissions
#### Assigned global permissions
* URL: `/users/{id}/permissions/`
* HTTP Method: GET/PUT
@@ -211,9 +211,9 @@ The following shows user as an example.
}
```
## Repository permissions
### Repository permissions
### Available repository permissions
#### Available repository permissions
* URL: `/repositoryPermissions` (similar to `/repositoryTypes`)
* HTTP Method: GET
@@ -235,7 +235,7 @@ The following shows user as an example.
}
```
### Assigned repository permissions
#### Assigned repository permissions
Already implemented in `PermissionRootResource`. Needs to be adpated from roles (`WRITE`) to shiro permissions
(`repository:read:42`).
@@ -272,7 +272,7 @@ Note that
* On PUT, the REST API needs to **validate** that each entry in `permissions` does not contain `:`!
Otherwise we might allow for "permission injection", allowing to set permissions on other or all repositories.
# Java API
## Java API
The biggest technical challenges for this concept are the questions:
@@ -287,13 +287,13 @@ Where each questions needs to be answered for
permissions.
## Global permissions
### Global permissions
In order to implement this for global permissions an existing mechanism of SCM-Manager can be used:
The `SecuritySystem`, implemented by the `DefaultSecuritySystem`.
### List available permissions
#### List available permissions
The `DefaultSecuritySystem` reads all `permissions.xml` files from classpath, which also works for plugins (see
[Proof Of Concept](https://bitbucket.org/sdorra/scm-manager/commits/4ed74bf266106c48db77d21558452b0c968884cb?at=feature/global_permissions#chg-scm-plugins/scm-git-plugin/src/main/resources/META-INF/scm/permissions.xml)).
@@ -308,7 +308,7 @@ For SCMMv2 we could extend this mechanism by
The annotations should be extended to support a list of permissions that are not written to `permissions.xml`
(e.g. `user:autocomplete`)
### Assign permissions
#### Assign permissions
The `SecuritySystem` also provides means to assign, store and load permissions to users or groups using Shiro string
permissions like so:
@@ -323,23 +323,23 @@ log.info("All permissions: {}", securitySystem.getAllPermissions()); // Contains
See also the [Proof Of Concept](https://bitbucket.org/sdorra/scm-manager/src/4a88315d8f3ce0ad9a7c428da1081fb7e4967fe3/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GlobalPermissionPocResource.java?at=feature/global_permissions).
### Evaluating permissions
#### Evaluating permissions
The evaluation of permissions assigned via the `SecuritySystem` is already implemented in the
`DefaultAuthorizationCollector`.
### Dynamically add new items to available permissions
#### Dynamically add new items to available permissions
Adding items (e.g. new users) dynamically during runtime is not implemented by the `SecuritySystem` and in order to
keep this simple we do not plan to support it, yet. See considered alternatives.
## Repository Permissions
### Repository Permissions
For repository permissions we need to implement a new mechanism for discovering available permissions .
Assigning is already implemented (on role level, e.g. `WRITE`), which needs to be adapted to shiro permission level
(e.g. `repository:read:42`).
### List available permissions
#### List available permissions
We need to implement a new mechanism for discovering available permssions. Let's call it `RepositoryPermissionResolver`.
It can work similar to the `DefaultSecuritySystem` (see global permissions). It reads all `repository-permissions.xml`
@@ -362,22 +362,22 @@ This obsoletes the `PermissionType` enum.
</permissions>
```
### Assign permissions
#### Assign permissions
This is already implemented in `RepositoryManager`s. Needs to be adapted from roles (`WRITE`) to shiro permissions
(`repository:read:42`).
### Evaluating permissions
#### Evaluating permissions
Same here: Already implemented in `DefaultAuthorizationCollector`. Needs to be adapted from roles to shiro permissions.
## The Admin flag/role
### The Admin flag/role
In addition to the fine-grained permission management described in this concept, we could just keep the admin flag
(or role) that add the permission `*` to a user.
It's already implemented and a well-known concept from SCMMv1.
## Permission for managing permissions
### Permission for managing permissions
Once permissions can be managed, an additional permission is necessary that answers the question: Who is allowed to
manage permissions?
@@ -391,11 +391,11 @@ and write. That is,
* `permission:read`
* `permission:write`
# i18n
## i18n
Internationalization can be handled using the following conventions:
* All permission i18n are described in `plugins.json` (also for core), see [i18n for Plugins](i18n for Plugins)
* All permission i18n are described in `plugins.json` (also for core), see [i18n for Plugins](i18n%20for%20Plugins.md)
* That way the UI for users and groups can find all the translation in the same file
* Convention for i18n keys: `permissions.<shiro-String>`, containing `displayName` and `description` each.
@@ -412,7 +412,7 @@ Example:
}
```
# Group Manager Plugin
## Group Manager Plugin
One shortcoming of limiting the global permission concept to verbs (not items) is that the functionality of the
`scm-groupmanager-plugin` is not included.
@@ -432,7 +432,7 @@ The following needs to be implemented:
* For storing the permission, make use of the `SecuritySystem` to set the `group:*:<id>` permissions.
# Considered alternatives
## Considered alternatives
This chapter documents some other approaches that were considered but rejected and the reasons for rejecting them.
@@ -450,7 +450,7 @@ This chapter documents some other approaches that were considered but rejected a
of userrepo or groupmanager plugins. Those could still be implemented separately. Still, as SCMMv2 provides a
mechanism for evaluate permissions on the fine-grained `subject:verb:item` level, why not allow our users to make use of it?
# Implemented Permissions
## Implemented Permissions
This chapter documents the permissions implemented in SCM-Manager core and a lot of plugins that can be assigned to users and groups
using the GUI/API.
@@ -458,10 +458,10 @@ Be aware, that this is only a snapshot and may not track each change in a plugin
for a concrete version of the core or a plugin, take a look at the corresponding `permissions.xml`, `repository-permissions.xml` and
`plugins.json` files.
## Global Permissions
### Global Permissions
| plugin | permission | description |
|-|-|-|
|--------|------------|-------------|
| core | `repository:read,pull:*` | read all repositories |
| core | `repository:read,pull,push:*` | write all repositories |
| core | `repository:*` | own all repositories |
@@ -501,10 +501,10 @@ for a concrete version of the core or a plugin, take a look at the corresponding
| ssh | `user:readAuthorizedKeys:*` | read authorization keys for all users |
| ssh | `user:readAuthorizedKeys,writeAuthorizedKeys:*` | configure authorization keys for all users |
## Repository Permissions
### Repository Permissions
| plugin | verb | description |
|-|-|-|
|--------|------|-------------|
| core | `read` | read metadata of repository |
| core | `modify` | modify metadata of repository |
| core | `delete` | delete repository |
@@ -530,13 +530,13 @@ for a concrete version of the core or a plugin, take a look at the corresponding
| branchwp | `branchwp` | administer write protected paths for repository |
| webhook | `webhook` | administer web hools for repository |
## Repository Roles
### Repository Roles
The verbs for roles are merged internally, so that a resulting role will have all verbs specified by any plugin.
Mind that a `OWNER` has overall permissions, including all possible permissions for all plugins.
| plugin | role | verbs |
|-|-|-|
|--------|------|-------|
| core | `READ` | `read`, `pull` |
| core | `WRITE` | `read`, `pull`, `push` |
| core | `OWNER` | `*` |

View File

@@ -69,8 +69,8 @@ In order to extend the ui the plugin requires a `package.json` in the project ro
```
The `main` field of the `package.json` describes the main entry point of the plugin.
The file specified at `main` should use the `binder` from the [@scm-manager/ui-extensions](https://bitbucket.org/scm-manager/ui-extensions) in oder to bind its extensions.
For more information of extensions, binder and extension points, please have a look at the [readme](https://bitbucket.org/scm-manager/ui-extensions/src/master/README.md) of [@scm-manager/ui-extensions](https://bitbucket.org/scm-manager/ui-extensions).
The file specified at `main` should use the `binder` from the [@scm-manager/ui-extensions](../../scm-ui/ui-extensions) in oder to bind its extensions.
For more information of extensions, binder and extension points, please have a look at the [README.md](../../scm-ui/ui-extensions/README.md) of @scm-manager/ui-extensions.
If the plugins gets build (`mvn package` or `mvn install`), the [buildfrontend-maven-plugin](https://github.com/sdorra/buildfrontend-maven-plugin), will call the `build` script of `package.json`.
The build script triggers the `plugin` command of the [@scm-manager/ui-bundler](https://bitbucket.org/scm-manager/ui-bundler).

View File

@@ -1,13 +1,13 @@
# SCM-Manager v2 Test Cases
Describes the expected behaviour for SCMM v2 REST Resources using manual tests.
[TOC]
# Test Cases
The following states general test cases per HTTP Method and en expected return code as well as exemplary curl calls.
Resource-specifics are stated
## GET
## Test Cases
### GET
- Collection Resource (e.g. `/users`)
- Without parameters -> 200
@@ -23,13 +23,13 @@ Resource-specifics are stated
- Unknown field (e.g. `?fields=nam`) returns empty object
- without permission (individual and collection (TODO)) -> 401
## POST
### POST
- not existing -> 204
- existing -> 409
- without permission -> 401
## PUT
### PUT
- existing -> 204
- lastModified is updated
@@ -43,44 +43,37 @@ Resource-specifics are stated
- creationDate, lastModified --> 200 is liberally ignored
- Additional unmodifiable fields per resource, see examples
## DELETE
### DELETE
- existing -> 204
- not existing -> 204
- without permission -> 401
# Exemplary calls & Resource specific test cases
## Exemplary calls & Resource specific test cases
In order to extend those tests to other Resources, have a look at the rest docs. Note that the Content Type is specific to each resource as well.
After calling `mvn -pl scm-webapp compile -P doc` the docs are available at `scm-webapp/target/restdocs/index.html`.
### Users
## Users
#### GET
### GET
#### Collections
```
#!bash
##### Collections
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/users?sortBy=admin&desc=true"
```
#### Individual
```
#!bash
##### Individual
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/users/scmadmin?fields=name,_links"
```
### POST
```
#!bash
#### POST
```bash
curl -vu scmadmin:scmadmin --data '{
"properties": null,
"active": true,
@@ -96,14 +89,12 @@ curl -vu scmadmin:scmadmin --data '{
--header "Content-Type: application/vnd.scmm-user+json;v=2" http://localhost:8081/scm/api/v2/users/
```
### PUT
#### PUT
- Change unmodifiable fields
- type? -> can be overwritten right now
```
#!bash
```bash
curl -X PUT -vu scmadmin:scmadmin --data '{
"properties": null,
"active": true,
@@ -119,40 +110,31 @@ curl -X PUT -vu scmadmin:scmadmin --data '{
--header "Content-Type: application/vnd.scmm-user+json;v=2" http://localhost:8081/scm/api/v2/users/xyz
```
### DELETE
```
#!bash
#### DELETE
```bash
curl -X DELETE -vu scmadmin:scmadmin http://localhost:8081/scm/api/v2/users/xyz
```
### Groups
#### GET
## Groups
### GET
#### Collections
```
#!bash
##### Collections
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/groups/?sortBy=name&desc=true"
```
#### Individual
##### Individual
```
#!bash
```bash
curl -vu scmadmin:scmadmin http://localhost:8081/scm/api/v2/groups/firstGroup
```
### POST
#### POST
```
#!bash
```bash
curl -vu scmadmin:scmadmin --data '{
"creationDate": "2018-06-28T07:42:45.281Z",
"lastModified": "2018-06-28T07:42:45.281Z",
@@ -169,14 +151,11 @@ curl -vu scmadmin:scmadmin --data '{
}
}' \
--header "Content-Type: application/vnd.scmm-group+json" http://localhost:8081/scm/api/v2/groups/
```
### PUT
```
#!bash
#### PUT
```bash
curl -X PUT -vu scmadmin:scmadmin --data '{
"creationDate": "2018-06-28T07:42:45.281Z",
"lastModified": "2018-06-28T07:42:45.281Z",
@@ -195,40 +174,31 @@ curl -X PUT -vu scmadmin:scmadmin --data '{
--header "Content-Type: application/vnd.scmm-group+json" http://localhost:8081/scm/api/v2/groups/firstGroup
```
### DELETE
```
#!bash
#### DELETE
```bash
curl -X DELETE -vu scmadmin:scmadmin http://localhost:8081/scm/api/v2/groups/firstGroup
```
### Repositories
## Repositories
#### GET
### GET
#### Collections
```
#!bash
##### Collections
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositories/?sortBy=name&pageSize=1&desc=true"
```
#### Individual
##### Individual
```
#!bash
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositories/42/arepo"
```
### POST
```
#!bash
#### POST
```bash
curl -vu scmadmin:scmadmin --data '{
"contact": "a@con.tact",
"creationDate": "2018-07-11T08:54:44.569Z",
@@ -236,17 +206,14 @@ curl -vu scmadmin:scmadmin --data '{
"name": "arepo",
"type": "git"
}' --header "Content-Type: application/vnd.scmm-repository+json" http://localhost:8081/scm/api/v2/repositories
```
### PUT
#### PUT
- Change unmodifiable fields
- type? -> Leads to 500 right now
```
#!bash
```bash
curl -X PUT -vu scmadmin:scmadmin --data '{
"contact": "anoter@con.tact",
"creationDate": "2017-04-11T08:54:45.569Z",
@@ -258,20 +225,17 @@ curl -X PUT -vu scmadmin:scmadmin --data '{
}' --header "Content-Type: application/vnd.scmm-repository+json" http://localhost:8081/scm/api/v2/repositories/42/arepo
```
### DELETE
```
#!bash
#### DELETE
```bash
curl -X DELETE -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositories/42/anSVNRepo"
```
## Repository Permissions
### Repository Permissions
In this test we do not only test the REST endpoints themselves, but also the effect of the different permissions.
### Prerequisites
#### Prerequisites
For these tests we assume that you have created
@@ -280,21 +244,17 @@ For these tests we assume that you have created
If your entities have other ids, change them according to your data.
### GET
#### GET
This request should return an empty list of permissions:
```
#!bash
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositories/scmadmin/git/permissions/"
```
### POST / READ permission
```
#!bash
#### POST / READ permission
```bash
curl -X POST -vu scmadmin:scmadmin --data '{
"name": "user", "type":"READ"
}' --header "Content-Type: application/vnd.scmm-permission+json"
@@ -303,17 +263,13 @@ curl -X POST -vu scmadmin:scmadmin --data '{
After this, you should be able to `GET` the repository with the user `user`:
```
#!bash
```bash
curl -vu user:user "http://localhost:8081/scm/api/v2/repositories/scmadmin/git/permissions/"
```
Trying to change the repository using `PUT` with the user `user` should result in `403`:
```
#!bash
```bash
curl -vu user:user -X PUT --data '{
"contact": "zaphod.beeblebrox@hitchhiker.com",
"namespace":"scmadmin",
@@ -326,25 +282,19 @@ curl -vu user:user -X PUT --data '{
Reading the permissions of the repository with the user `user` should result in `403`:
```
#!bash
```bash
curl -vu user:user "http://localhost:8081/scm/api/v2/repositories/scmadmin/git/permissions/"
```
The user should be able to `clone` the repository:
```
#!bash
```bash
git clone http://owner@localhost:8081/scm/git/scmadmin/git
```
The user should *not* be able to `push` to the repository:
```
#!bash
```bash
cd git
touch a
git add a
@@ -352,13 +302,11 @@ git commit -m a
git push
```
### PUT / WRITE permission
#### PUT / WRITE permission
It should be possible to change the permission for a specific user:
```
#!bash
```bash
curl -X PUT -vu scmadmin:scmadmin --data '{
"name": "user",
"type":"WRITE"
@@ -367,18 +315,14 @@ curl -X PUT -vu scmadmin:scmadmin --data '{
After this the user `user` should now be able to `push` the repository created and modified beforehand.
```
#!bash
```bash
cd git
git push
```
### OWNER permission
```
#!bash
#### OWNER permission
```bash
curl -X PUT -vu scmadmin:scmadmin --data '{
"name": "user",
"type":"OWNER"
@@ -387,68 +331,57 @@ curl -X PUT -vu scmadmin:scmadmin --data '{
After this, the user should be able to `GET` the permissions:
```
#!bash
```bash
curl -vu user:user "http://localhost:8081/scm/api/v2/repositories/scmadmin/git/permissions/"
```
Additionally, the user should be able to change permissions:
```
#!bash
```bash
curl -X PUT -vu scmadmin:scmadmin --data '{
"name": "user",
"type":"OWNER"
}' --header "Content-Type: application/vnd.scmm-permission+json" "http://localhost:8081/scm/api/v2/repositories/scmadmin/git/permissions/user"
```
### DELETE
#### DELETE
Finally, a user with the role `OWNER` should be able to delete permissions:
```
#!bash
```bash
curl -X DELETE -vu user:user "http://localhost:8081/scm/api/v2/repositories/scmadmin/git/permissions/user"
```
## Branches
### Branches
* In advance: POST repo.
* Clone Repo, add Branches
### GET
#### GET
#### Collections
##### Collections
```
#!bash
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositories/scmadmin/arepo/branches"
```
#### Individual
##### Individual
```
#!bash
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositories/scmadmin/arepo/branches/master"
```
## Configuration
### Configuration
### GET
#### GET
```
#!bash
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/config"
```
### PUT
```
#!bash
#### PUT
```bash
curl -X PUT -vu scmadmin:scmadmin --data '{
"proxyPassword": "pw",
"proxyPort": 8082,
@@ -473,19 +406,17 @@ curl -X PUT -vu scmadmin:scmadmin --data '{
}' --header "Content-Type: application/vnd.scmm-config+json" http://localhost:8081/scm/api/v2/config
```
## Git Plugin Configuration
### Git Plugin Configuration
### GET
#### GET
```
#!bash
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/config/git"
```
### PUT
#### PUT
```
#!bash
```bash
curl -X PUT -vu scmadmin:scmadmin --data '{
"gcExpression": "0 0 14-6 ? * FRI-MON",
"repositoryDirectory": "new",
@@ -493,19 +424,17 @@ curl -X PUT -vu scmadmin:scmadmin --data '{
}' --header "Content-Type: application/vnd.scmm-gitConfig+json" http://localhost:8081/scm/api/v2/config/git
```
## Hg Plugin Configuration
### Hg Plugin Configuration
### GET
#### GET
```
#!bash
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/config/hg"
```
### PUT
#### PUT
```
#!bash
```bash
curl -X PUT -vu scmadmin:scmadmin --data '{
"repositoryDirectory": "new",
"disabled": true,
@@ -516,22 +445,19 @@ curl -X PUT -vu scmadmin:scmadmin --data '{
"useOptimizedBytecode": true,
"showRevisionInId": true
}' --header "Content-Type: application/vnd.scmm-hgConfig+json" http://localhost:8081/scm/api/v2/config/hg
```
### Auto Config
#### Auto Config
#### Default
##### Default
```
#!bash
```bash
curl -v -X PUT -u scmadmin:scmadmin "http://localhost:8081/scm/api/v2/config/hg/auto-configuration"
```
#### Specific config
##### Specific config
```
#!bash
```bash
curl -v -X PUT -u scmadmin:scmadmin --data '{
"repositoryDirectory": "new",
"disabled": true,
@@ -544,113 +470,96 @@ curl -v -X PUT -u scmadmin:scmadmin --data '{
}' --header "Content-Type: application/vnd.scmm-hgConfig+json" "http://localhost:8081/scm/api/v2/config/hg/auto-configuration"
```
### Installations
#### Installations
#### Hg
##### Hg
```
#!bash
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/config/hg/installations/hg"
```
#### Python
##### Python
```
#!bash
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/config/hg/installations/python"
```
### Packages
#### Packages
##### GET
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/config/hg/packages"
```
##### PUT
See [here](https://download.scm-manager.org/pkg/mercurial/packages.xml) for available packages. Will only work on Windows!
```bash
curl -X PUT -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/config/hg/packages/4338c4_x64"
```
### Svn Plugin Configuration
#### GET
```
#!bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/config/hg/packages"
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/config/svn"
```
#### PUT
See [here](https://download.scm-manager.org/pkg/mercurial/packages.xml) for available packages. Will only work on Windows!
```
#!bash
curl -X PUT -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/config/hg/packages/4338c4_x64"
```
## Svn Plugin Configuration
### GET
```
#!bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/config/svn"
```
### PUT
```
#!bash
```bash
curl -X PUT -vu scmadmin:scmadmin --data '{
"repositoryDirectory": "new",
"disabled": true,
"enabledGZip": true,
"compatibility": "PRE15"
}' --header "Content-Type: application/vnd.scmm-svnConfig+json" http://localhost:8081/scm/api/v2/config/svn
```
## Repository Types
### Repository Types
### GET
#### GET
#### Collections
```
#!bash
##### Collections
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repository-types"
```
#### Individual
```
#!bash
##### Individual
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repository-types/hg"
```
## Tags
### Tags
### GET
#### GET
Pre-conditions: the git repository "HeartOfGold-git" exists and contains tags example v1.0 and v1.1
#### Collections
```
#!bash
##### Collections
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositories/scmadmin/HeartOfGold-git/tags/"
```
#### Individual
##### Individual
```
#!bash
```bash
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositories/scmadmin/HeartOfGold-git/tags/v1.1"
```
## Content
### Content
### git
#### git
#### Prepare
##### Prepare
```
#!bash
```bash
curl -vu scmadmin:scmadmin --data '{
"contact": "a@con.tact",
"creationDate": "2018-07-11T08:54:44.569Z",
@@ -669,10 +578,10 @@ git add .
git commit -m 'Msg'
git push
```
#### Query and assert
```
#!bash
##### Query and assert
```bash
# Assert Content type text plain
curl -X HEAD -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositories/scmadmin/arepo/content/$(git rev-parse HEAD)/b.txt" 2>&1 | grep Content-Type
# Assert file content "bbb"
@@ -689,12 +598,11 @@ curl -X HEAD -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositorie
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositories/scmadmin/arepo/content/$(git rev-parse HEAD)/RestActionResult.java"
```
### hg
#### hg
#### Prepare
##### Prepare
```
#!bash
```bash
curl -vu scmadmin:scmadmin --data '{
"contact": "a@con.tact",
"creationDate": "2018-07-11T08:54:44.569Z",
@@ -713,11 +621,9 @@ hg commit -m 'msg'
hg push
```
#### Query and assert
```
#!bash
##### Query and assert
```bash
# Assert Content type text plain
curl -X HEAD -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositories/scmadmin/hgrepo/content/$(hg identify --id)/b.txt" 2>&1 | grep Content-Type
# Assert file content "bbb"
@@ -734,12 +640,11 @@ curl -X HEAD -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositorie
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositories/scmadmin/hgrepo/content/$(hg identify --id)/RestActionResult.java"
```
### svn
#### svn
#### Prepare
##### Prepare
```
#!bash
```bash
curl -vu scmadmin:scmadmin --data '{
"contact": "a@con.tact",
"creationDate": "2018-07-11T08:54:44.569Z",
@@ -757,10 +662,9 @@ svn add ./*
svn commit --non-interactive --no-auth-cache --username scmadmin --password scmadmin -m 'msg'
```
#### Query and assert
##### Query and assert
```
#!bash
```bash
REVISION=$(svn --non-interactive --no-auth-cache --username scmadmin --password scmadmin info -r 'HEAD' --show-item revision | xargs echo -n)
# Assert Content type text plain
curl -X HEAD -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositories/scmadmin/svnrepo/content/${REVISION}/b.txt" 2>&1 | grep Content-Type
@@ -778,14 +682,13 @@ curl -X HEAD -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositorie
curl -vu scmadmin:scmadmin "http://localhost:8081/scm/api/v2/repositories/scmadmin/svnrepo/content/${REVISION}/RestActionResult.java"
```
## Access Token
### Access Token
### Admin
#### Admin
#### Output all links of index resource
##### Output all links of index resource
```
#!bash
```bash
TOKEN=$(curl -s 'http://localhost:8081/scm/api/v2/auth/access_token' -H 'content-type: application/json' --data '{
"cookie": false,
"grant_type": "password",
@@ -795,12 +698,11 @@ TOKEN=$(curl -s 'http://localhost:8081/scm/api/v2/auth/access_token' -H 'content
curl -s http://localhost:8081/scm/api/v2/ -H "Authorization: Bearer ${TOKEN}" | jq
```
#### Output only "config" and default logged in links
##### Output only "config" and default logged in links
default logged in links = self, uiPlugins, me, logout
```
#!bash
```bash
TOKEN=$(curl -s 'http://localhost:8081/scm/api/v2/auth/access_token' -H 'content-type: application/json' --data '{
"cookie": false,
"grant_type": "password",
@@ -813,13 +715,11 @@ TOKEN=$(curl -s 'http://localhost:8081/scm/api/v2/auth/access_token' -H 'content
curl -s http://localhost:8081/scm/api/v2/ -H "Authorization: Bearer ${TOKEN}" | jq
```
### non-Admin
#### non-Admin
Create non-admin user
```
#!bash
```bash
curl -vu scmadmin:scmadmin --data '{
"active": true,
"admin": false,
@@ -832,12 +732,11 @@ curl -vu scmadmin:scmadmin --data '{
--header "Content-Type: application/vnd.scmm-user+json;v=2" http://localhost:8081/scm/api/v2/users/
```
#### Standard permissions of a logged in user without additional permissions
##### Standard permissions of a logged in user without additional permissions
Standard links of a logged in user = self, uiPlugins, me, logout, autocomplete, repositories
```
#!bash
```bash
TOKEN=$(curl -s 'http://localhost:8081/scm/api/v2/auth/access_token' -H 'content-type: application/json' --data '{
"cookie": false,
"grant_type": "password",
@@ -847,14 +746,12 @@ TOKEN=$(curl -s 'http://localhost:8081/scm/api/v2/auth/access_token' -H 'content
curl -s http://localhost:8081/scm/api/v2/ -H "Authorization: Bearer ${TOKEN}" | jq
```
#### Scope requests permission the user doesn't have
##### Scope requests permission the user doesn't have
This should not retrun `configuration` links, even though this scope was requested, because the user does not have the configuration permission. Otherwise this would be a major security flaw!
Compare to admin tests above.
```
#!bash
```bash
TOKEN=$(curl -s 'http://localhost:8081/scm/api/v2/auth/access_token' -H 'content-type: application/json' --data '{
"cookie": false,
"grant_type": "password",
@@ -865,4 +762,4 @@ TOKEN=$(curl -s 'http://localhost:8081/scm/api/v2/auth/access_token' -H 'content
]
}')
curl -s http://localhost:8081/scm/api/v2/ -H "Authorization: Bearer ${TOKEN}" | jq
```
```

View File

@@ -2,12 +2,12 @@
Use this as a kind of a checklist whenever you develop something in the UI of SCM-Manager 2.x., regardless whether you are developing core features or plugins.
| | Don't forget to |
|-|-|
| | Don't forget to |
|---|-----------------|
| ☐ | use imports with `@scm-manager`, eg. `@scm-manager/ui-components` |
| ☐ | let buttons have whitespace |
| ☐ | update german translation |
| ☐ | add help icons to input components |
| ☐ | not use colors directly, but refer to `is-primary` or `is-warning` |
| ☐ | make sure your view works on mobile devices |
| ☐ | document extension points here: https://bitbucket.org/sdorra/scm-manager/wiki/v2/Extension-Points |
| ☐ | document [extension points in wiki](Extension-Points.md) |

View File

@@ -46,7 +46,7 @@ Here are some example error cases:
In SCM-Manager we make heavy use of Java `Exception`s, not only for technical exceptions in the program flow like reading corrupt file systems, but also for "user errors" like illegal values or requests for missing data.
These exceptions are handled by JEE [`ExceptionMapper`](https://docs.oracle.com/javaee/7/api/javax/ws/rs/ext/ExceptionMapper.html)s. Doing so, it is possible to concentrate on implementing the "happy path" without the need to explicitly handle error cases everywhere (for example you do not have to check whether got `null` as a result). Nonetheless we still had to decide whether to use checked or unchecked exceptions. We have chosen to use unchecked exceptions due to the following reasons:
These exceptions are handled by JEE [`ExceptionMapper`](https://docs.oracle.com/javaee/7/api/javax/ws/rs/ext/ExceptionMapper.html) s. Doing so, it is possible to concentrate on implementing the "happy path" without the need to explicitly handle error cases everywhere (for example you do not have to check whether got `null` as a result). Nonetheless we still had to decide whether to use checked or unchecked exceptions. We have chosen to use unchecked exceptions due to the following reasons:
- Checked exceptions would have had to be declared everywhere.
- A checked exception can somehow trigger a "I have to handle this though I don't know how" feeling that would be wrong, because we do have mappers for these exceptions.
@@ -117,7 +117,7 @@ To be able to retrace errors a proper logging is indispensible. So we decided to
SCM-Manager uses [http status codes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) to identify types of errors (and successes, that is) and doing so provides a first hint, what may have gone wrong:
| Status code | Principal error cause |
|-|-|
|-------------|-----------------------|
| 200 | No error, everything is fine |
| 201 | The item has been created without an error |
| 204 | The request has been processed without an error |
@@ -133,7 +133,7 @@ SCM-Manager uses [http status codes](https://en.wikipedia.org/wiki/List_of_HTTP_
Whenever possible, an error response contains useful details about the error in a simple json format. These information are _not_ translated, so this is the responsibility of the frontend.
| key | content | availability |
|-|-|-|
|-----|---------|--------------|
| transactionId | A unique id to link your request to log messages | always |
| errorCode | A code that can be used for translated error messages. To prevent the usage of the same codes in different exceptions we decided to use generated ids. | always |
| context | (repo/key, branch/key, ...) | optional |
@@ -184,5 +184,5 @@ Basically we have to differentiate between errors the user can handle ("user err
While creating this concepts we tried to adhere to best practices considering APIs of Twitter, Facebook, Bing, Spotify and others, as summarized in the following articles:
* https://apigee.com/about/blog/technology/restful-api-design-what-about-errors
* https://nordicapis.com/best-practices-api-error-handling/
* [RESTful API Design: What About Errors? (Apigee)](https://apigee.com/about/blog/technology/restful-api-design-what-about-errors)
* [Best Practices for API Error Handling (Nordic APIS)](https://nordicapis.com/best-practices-api-error-handling/)

View File

@@ -1,22 +1,31 @@
# i18n for Plugins
How to internationalize your own plugin
---------------------------------------
### Create the plugins.json file
The translation file for plugins should be stored in the resources path
locales/{lang}/plugins.json
locales/*{lang}*/plugins.json
All translation keys are parts of a \*\*unique root key\*\*. It is
recommended to \*\*use the maven artifactId of the plugin as root
key\*\* to avoid conflicts with other plugin. All translation files
All translation keys are parts of a **unique root key**. It is
recommended to **use the maven artifactId of the plugin as root
key** to avoid conflicts with other plugin. All translation files
would be collected and merged to a single file containing all
translations. Therefore it is \*\*necessary to use a unique root key\*\*
translations. Therefore it is **necessary to use a unique root key**
for the translations.
//\*\*example:\*\*//
***Example:***
the translation file of the svn plugin is stored in
locales/en/plugins.json
```json
{
"scm-svn-plugin": {
"information": {
"checkout" : "Checkout repository"
}
}
}
```
### Usage in the own React components
@@ -26,10 +35,25 @@ The following steps are needed to use react-i18next in the own
components
- import react-i18next
```javascript
import { translate } from "react-i18next";
```
- declare the translation method as property
- declare the translation method `t: string => string` as property
```javascript
type Props = {
t: string => string
}
```
- wrap the react component with the translate method and give the json
translation file name \"plugins\"
```javascript
export default translate("plugins")(MyPluginComponent);
```
- use the translation keys like this:
```javascript
const { t } = this.props;
<h3>{t("scm-svn-plugin.information.checkout")}</h3>
```

View File

@@ -33,39 +33,43 @@
* Languages & Frameworks / Javascript
* JavaScript language version: Flow
* Flow package or executable: .../scm-ui/node_modules/flow-bin
* Flow package or executable: .../node_modules/flow-bin
* Languages & Frameworks / Javascript / Code Quality Tools / ESLint
* Enable
* ESLint package: .../scm-ui/node_modules/eslint
* ESLint package: .../node_modules/eslint
* -OR- Automatic ESLint configuration
* Languages & Frameworks / Javascript / Prettier
* Prettier package: .../scm-ui/node_modules/prettier
* Prettier package: .../node_modules/prettier
* Tools / File Watchers
* Add Prettier
* Deselect: Track only root files
* Scope: Current File
* Program: $ProjectFileDir$/scm-ui/node_modules/.bin/prettier
* Working Directory: $ProjectFileDir$/scm-ui
* Program: $ProjectFileDir$/node_modules/.bin/prettier
* Working Directory: $ProjectFileDir$
* Run Configurations / Edit Configuration
* Templates / Jest
* Jest package: .../scm-ui/node_modules/jest
* Jest package: .../node_modules/jest
* Jest options: --config node_modules/@scm-manager/ui-bundler/src/jest.ide.config.js
* Run Configurations / Edit Configuration
* Add npm
* Name: run-frontend
* package-json: .../scm-ui/package.json
* package-json: .../package.json
* Command: run
* Scripts: start
* Scripts: serve
## Both
### Plugins
* EditorConfig
### Settings
* Editor / Copyright / Copyright Profiles
* Add Profile
* Name: SCM-MIT

View File

@@ -8,7 +8,7 @@ Also it is a good guide line to adapt Postel's law: *Be conservative in what you
## Java
Please mind the [EditorConfig](https://editorconfig.org/) file `.editorconf` in the root of the SCM-Manager and the [configuration guide](intellij-idea-configuration) for IntelliJ IDEA. There are plugins for a lot of IDEs and text editors.
Please mind the [EditorConfig](https://editorconfig.org/) file `.editorconf` in the root of the SCM-Manager and the [configuration guide](intellij-idea-configuration.md) for IntelliJ IDEA. There are plugins for a lot of IDEs and text editors.
- Indentation with 2 spaces and no tabs (we have kept this rule from 1.x)
- Order of members:
@@ -24,4 +24,5 @@ Please mind the [EditorConfig](https://editorconfig.org/) file `.editorconf` in
- Though we will not define a maximum line length, you should break lines when they go beyond 120 characters or so.
## JavaScript
Take a look at our styleguide using `yarn serve` in ui-styles directory.
Take a look at our styleguide using `yarn serve` in [ui-styles](scm-ui/ui-styles) directory.