Establish preliminary structure for documentation

This commit is contained in:
Konstantin Schaper
2020-05-06 19:56:34 +02:00
parent daeb8b7cbb
commit 8b2d9d1d95
34 changed files with 366 additions and 21 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

View File

@@ -0,0 +1,7 @@
---
title: Create a new plugin
---
There is a service which is able to create a skeleton for a new plugin:
https://create-plugin.scm-manager.org/

View File

@@ -0,0 +1,27 @@
---
title: Create a plugin
subtitle: Create a plugin from Maven Archetype
displayToc: true
---
# Requirements
Be sure you have installed the following software:
* [Java 8](https://java.com/de/download/)
* [Apache Maven](http://maven.apache.org/)
# Create the plugin structure
Use the scm-manager plugin [archetype](https://maven.apache.org/guides/introduction/introduction-to-archetypes.html)
to create the plugin structure.
```bash
mvn archetype:...
```
Answer the questions of the archetype.
# Implement your plugin
... draw the rest of the owl

View File

@@ -0,0 +1,99 @@
---
title: Extension Points
---
The following extension points are provided for the frontend:
### admin.navigation
### admin.route
### admin.setting
### changeset.description
### changeset.right
### changesets.author.suffix
### group.navigation
### group.route
### group.setting
### main.route
- Add a new Route to the main Route (scm/)
- Props: authenticated?: boolean, links: Links
### plugins.plugin-avatar
### primary-navigation
### primary-navigation.first-menu
- A placeholder for the first navigation menu.
- A PrimaryNavigationLink Component can be used here
- Actually this Extension Point is used from the Activity Plugin to display the activities at the first Main Navigation menu.
### primary-navigation.logout
### profile.route
### profile.setting
### repo-config.route
### repos.branch-details.information
### repos.content.metadata
- Location: At meta data view for file
- can be used to render additional meta data line
- Props: file: string, repository: Repository, revision: string
### repos.create.namespace
### repos.sources.content.actionbar
### repository.navigation
### repository.navigation.topLevel
### repositoryRole.role-details.information
### repository.setting
### repos.repository-avatar
- Location: At each repository in repository overview
- can be used to add avatar for each repository (e.g., to mark repository type)
### repos.repository-details.information
- Location: At bottom of a single repository view
- can be used to show detailed information about the repository (how to clone, e.g.)
### repos.sources.view
### roles.route
### user.route
### user.setting
# Deprecated
### changeset.avatar-factory
- Location: At every changeset (detailed view as well as changeset overview)
- can be used to add avatar (such as gravatar) for each changeset
- expects a function: `(Changeset) => void`
### repos.sources.view
- Location: At sources viewer
- can be used to render a special source that is not an image or a source code
### main.redirect
- Extension Point for a link factory that provide the Redirect Link
- Actually used from the activity plugin: binder.bind("main.redirect", () => "/activity");
### markdown-renderer-factory
- A Factory function to create markdown [renderer](https://github.com/rexxars/react-markdown#node-types)
- The factory function will be called with a renderContext parameter of type Object. this parameter is given as a prop for the MarkdownView component.
**example:**
```javascript
let MarkdownFactory = (renderContext) => {
let Heading= (props) => {
return React.createElement(`h${props.level}`,
props['data-sourcepos'] ? {'data-sourcepos': props['data-sourcepos']} : {},
props.children);
};
return {heading : Heading};
};
binder.bind("markdown-renderer-factory", MarkdownFactory);
```
```javascript
<MarkdownView
renderContext={{pullRequest, repository}}
className="content"
content={pullRequest.description}
/>
```

View File

@@ -0,0 +1,41 @@
---
title: Plugin Creation
---
### Software Requirements
- JDK 1.7 or higher
([download](http://www.oracle.com/technetwork/java/index.html))
- Maven 3 or higher ([download](http://maven.apache.org/))
### Create plugin
```bash
mvn archetype:generate\
-DarchetypeGroupId=sonia.scm.maven\
-DarchetypeArtifactId=scm-plugin-archetype\
-DarchetypeVersion=1.60\
-DarchetypeRepository=http://maven.scm-manager.org/nexus/content/groups/public/
```
### Test the plugin
```bash
mvn scmp:run
```
### Samples
- [Hello World](https://bitbucket.org/sdorra/scm-manager/src/1.x/scm-samples/scm-sample-hello/)
- [Authentication Plugin](https://bitbucket.org/sdorra/scm-manager/src/1.x/scm-samples/scm-sample-auth/)
### Further reading
- [Injection framework - Google Guice](http://code.google.com/p/google-guice/)
- [Restful WebService - Jersey](http://jersey.java.net/nonav/documentation/latest/user-guide.html)
- [ XML transformation - JAXB](http://jaxb.java.net/guide/)
- [User interface - Ext JS](http://www.sencha.com/products/extjs3/)
### Questions/Help
If you have questions or you need help, please write to the mailing
list: <https://groups.google.com/forum/#!forum/scmmanager>

View File

@@ -0,0 +1,80 @@
---
title: 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
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**
for the translations.
***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
SCM-Manager use react-i18next to render translations.
#### Functional components
The following steps are needed to use react-i18next in the own
functional components:
- import react-i18next
```javascript
import { useTranslation } from "react-i18next";
```
- use the translation keys like this:
```javascript
const [t] = useTranslation("plugins");
...
<h3>{t("scm-svn-plugin.information.checkout")}</h3>
```
#### Class components
The following steps are needed to use react-i18next in the own
class components:
- import react-i18next
```javascript
import { WithTranslation, withTranslation } from "react-i18next";
```
- declare the translation method `t: string => string` as property
```javascript
type Props = WithTranslation & {
***your props***
}
```
- wrap the react component with the translate method and give the json
translation file name \"plugins\"
```javascript
export default withTranslation("plugins")(MyPluginComponent);
```
- use the translation keys like this:
```javascript
const { t } = this.props;
<h3>{t("scm-svn-plugin.information.checkout")}</h3>
```

View File

@@ -0,0 +1,121 @@
---
title: I18n
subtitle: Howto do internationalization
displayToc: false
---
SCM-Manager uses [react-i18next](https://react.i18next.com) for internationalization.
The keys for the translation are stored in json files called `plugins.json` at `src/main/resources/locales/`,
followed by a folder for each language (e.g.: en for English, de for German).
The keys should be prefixed with the name of the plugin to avoid collisions e.g.:
`.../locales/en/plugins.json`:
```json
{
"scm-sample-plugin": {
"title": "Sample Title"
}
}
```
`.../locales/de/plugins.json`:
```json
{
"scm-sample-plugin": {
"title": "Beispiel Titel"
}
}
```
The translations keys can now be used with in the frontend.
**Function Component**:
```tsx
import React from "react";
// import hook from react-i18next library
import { useTranslation } from "react-i18next";
const Title = () => {
// use hook to obtain translate function for the namespace plugins
const { t } = useTranslation("plugins");
// use translate function to translate key scm-sample-plugin.title
return <p>{t("scm-sample-plugin.title")}</p>;
};
export default Title;
```
**Class Component**:
```tsx
import React from "react";
// import higher order component and types for out Props
import { WithTranslation, withTranslation } from "react-i18next";
// extend our props with WithTranslation
type Props = WithTranslation & {};
class Title extends React.Component<Props> {
render() {
// get translate function from props
const { t } = this.props;
// use translate function to translate key scm-sample-plugin.title
return <p>{t("scm-sample-plugin.title")}</p>;
}
};
// wrap our component with withTranslation for the namespace plugins
export default withTranslation("plugins")(Title);
```
If it is required to replace values in the content the `Trans` component can be used.
To achieve this goal we have to add placeholders to our translations e.g.:
`.../locales/en/plugins.json`:
```json
{
"scm-sample-plugin": {
"title": "Sample Title",
"greetings": "<0/> at <1/>"
}
}
```
`.../locales/de/plugins.json`:
```json
{
"scm-sample-plugin": {
"title": "Beispiel Titel",
"greetings": "<0/> um <1/>"
}
}
```
Now we can use the `Trans` component, not we have to specified the namespace with in the key:
```tsx
<Trans
i18nKey="plugins:scm-sample-plugin.greetings"
values={["Bob", new Date().toString()]}
/>
```
We can also replace the placeholders with react components:
```tsx
import {DateFromNow} from "@scm-manager/ui-components";
...
<Trans
i18nKey="plugins:scm-sample-plugin.greetings"
components={[
<p>"Bob"</p>,
<DateFromNow date={new Date()} />
]}
/>
```

View File

@@ -0,0 +1,72 @@
---
title: Plugin Descriptor
---
The plugin descriptor contains informations and instructions for the
scm-manager to integrate the plugin. The descriptor is located at
META-INF/scm/plugin.xml in the package of a plugin.
| Element | Description | Multiple |
| --- | --- | --- |
| plugin | Root element of the plugin descriptor | |
| plugin/condition | Plugin condifitions | |
| plugin/condition/arch | Processor architecture (x86/amd64) | |
| plugin/condition/min-version | Minimum version of SCM-Manager | |
| plugin/condition/os | Operation System | |
| plugin/condition/os/name | Name of the Operating System | X |
| plugin/information | Contains informations of the plugin for the plugin backend | |
| plugin/information/artifactId | Maven artifact id | |
| plugin/information/author | The Author of the plugin | |
| plugin/information/category | Category of the plugin | |
| plugin/information/description | Description of the plugin | |
| plugin/information/groupId | Maven group id | |
| plugin/information/name | Name of the plugin | |
| plugin/information/screenshots | Contains screenshots of the plugin | |
| plugin/information/screenshots/screenshot | Single screenshot of the plugin | X |
| plugin/information/url | The url of the plugin homepage | |
| plugin/information/version | The current version of the plugin | |
| plugin/information/wiki | The url of a wiki page | |
| plugin/packages | Java packages which are being searched for extensions | |
| plugin/packages/package | Single Java packages which is being searched for extensions | X |
| plugin/resources | Contains resources for the web interface (stylesheets and JavaScript files) | |
| plugin/resources/script | JavaScript file for the web interface | X |
| plugin/resources/stylesheet | Stylesheet for the web interface | X |
Example of the plugin descriptor:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<!--
Informations for the plugin backend.
The elements groupId, artifactId, name, version and url
are automatically added from the pom.xml by a maven plugin (since 1.5).
-->
<information>
<author>Sebastian Sdorra</author>
</information>
<!--
pluigin requires SCM-Manager version 1.7
-->
<conditions>
<min-version>1.7</min-version>
</conditions>
<!--
register package for plugin extension finder
-->
<packages>
<package>sonia.scm.jenkins</package>
</packages>
<!--
register javascript file
-->
<resources>
<script>/sonia/scm/sonia.jenkins.js</script>
</resources>
</plugin>
```

View File

@@ -0,0 +1,129 @@
---
title: SCM-Manager v2 Plugin Development
---
## Build and testing
The plugin can be compiled and packaged with the normal maven lifecycle:
* clean - `mvn clean` - removes the target directory, can be combined with other phases
* compile - `mvn compile` - compiles Java code and creates the ui bundle
* test - `mvn test` - executes test for Java and JavaScript
* install - `mvn install` - installs the plugin (smp and jar) in the local maven repository
* package - `mvn package` - creates the final plugin bundle (smp package) in the target folder
* deploy - `mvn deploy` - deploys the plugin (smp and jar) to the configured remote repository
For the development and testing the `serve` lifecycle of the plugin can be used:
* run - `mvn run` - starts scm-manager with the plugin pre installed.
If the plugin was started with `mvn run`, the default browser of the os should be automatically opened.
If the browser does not start automatically, start it manually and go to [http://localhost:8081/scm](http://localhost:8081/scm).
In this mode each change to web files (src/main/js or src/main/webapp), should trigger a reload of the browser with the made changes.
If you compile a class (e.g.: with your IDE from src/main/java to target/classes),
the SCM-Manager context will restart automatically. So you can see your changes without restarting the server.
## Directory & File structure
A quick look at the files and directories you'll see in a SCM-Manager project.
.
├── node_modules/
├── src/
| ├── main/
| | ├── java/
| | ├── js/
| | └── resources/
| ├── test/
| | ├── java/
| | └── resources/
| └── target/
├── .editorconfig
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── package.json
├── pom.xml
├── README.md
├── tsconfig.json
└── yarn.lock
1. **`node_modules/`**: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed.
2. **`src/`**: This directory will contain all of the code related to what you see or not. `src` is a convention for “source code”.
1. **`main/`**
1. **`java/`**: This directory contain the Java code.
2. **`js/`**: This directory contains the TypeScript code for the web ui, inclusive unit tests: suffixed with `.test.ts` or `.test.tsx`
3. **`resources/`**: This directory contains the the classpath resources.
2. **`test/`**
1. **`java/`**: This directory contains the Java unit tests.
3. **`resources/`**: This directory contains classpath resources for unit tests.
3. **`target/`**: This is the build directory.
3. **`.editorconfig`**: This is a configuration file for your editor using [EditorConfig](https://editorconfig.org/). The file specifies a style that IDEs use for code.
4. **`.gitignore`**: This file tells git which files it should not track / not maintain a version history for.
5. **`CHANGELOG.md`**: All notable changes to this project will be documented in this file.
6. **`LICENSE`**: This project is licensed under the MIT license.
7. **`package.json`**: Here you can find the dependency/build configuration and dependencies for the frontend.
8. **`pom.xml`**: Maven configuration, which also includes things like metadata.
9. **`README.md`**: This file, containing useful reference information about the project.
10. **`tsconfig.json`** This is the typescript configuration file.
11. **`yarn.lock`**: This is the ui dependency configuration.
## UI Extensions
Plugins are able to extend or modify the ui of SCM-Manager.
In order to extend the ui the plugin requires a `package.json` in the project root e.g:
```json
{
"name": "@scm-manager/scm-readme-plugin",
"main": "src/main/js/index.tsx",
"scripts": {
"build" : "ui-scripts plugin",
"watch" : "ui-scripts plugin-watch",
"test" : "jest",
"postinstall" : "ui-plugins postinstall"
},
"dependencies": {
"@scm-manager/ui-plugins" : "2.0.0-rc7"
}
}
```
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](../../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 [@scm-manager/ui-scripts](../../scm-ui/ui-scripts).
The `ui-scripts` will do the following steps:
* traverses the import statements of the script specified at `main`
* transpiles TypeScript to es5
* creates a single bundle
* stores the bundle in the final smp package
At runtime the plugins are loaded by PluginLoader. The PluginLoader is a React component, which does the following steps:
* fetches plugin metadata (name and registered bundles) from the rest service
* fetches each bundle of every plugin
* executes each bundle
* starts the rest of the application
## Static web resources
A plugin can also store static files in the `src/main/webapp` directory.
All files of the webapp directory can be resolved relative to the root of the application e.g. the file
`src/main/webapp/images/logo.jpg` of a plugin can be resolved at `http://localhost:8081/scm/images/logo.jpg`
assuming SCM-Manager is running at `http://localhost:8081/scm`.

View File

@@ -0,0 +1,42 @@
---
title: Publish
subtitle: Publish your Plugin
---
If you want to share your plugin with SCM-Manager users, you can publish it to the SCM-Manager Plugin Center by following the steps below.
* Create a Mercurial or Git repository for your plugin
* Develop your plugin as described in [Create a plugin](/docs/create)
* Fork the [Plugin Center Repository](https://bitbucket.org/scm-manager/plugin-center)
* Create a folder with the name of your plugin under the `src/plugins` directory
* Put a `index.md` which starts with frontmatter metadata, which describes your plugin e.g.:
```yaml
---
name: scm-cas-plugin
displayName: CAS
description: CAS Authentication plugin for version 2.x of SCM-Manager
category: authentication
author: Cloudogu GmbH
---
```
* Document your plugin with [markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) below the frontmatter header
* Commit your work and open a pull request. Put the url to your plugin repository into the description of the pull request.
After you have opened the pull request.
We will do a few steps to integrate your plugin into the plugin center:
* We will create a fork of your plugin under the [SCM-Manager Team](https://bitbucket.org/scm-manager/) and give your account write permissions
* After that we will create a Jenkins job for your plugin on [oss.cloudogu.com](https://oss.cloudogu.com/jenkins/job/scm-manager/job/scm-manager-bitbucket/)
* At the end we will accept your pull request
From now on you can work with the repository in the [SCM-Manager Team](https://bitbucket.org/scm-manager/).
Every time you release your plugin (push a tag to the repository) the Jenkins job will build your plugin and release it to the plugin center.
# Architecture
The following picture shows the architecture of the involved systems.
![Architecture](architecture.jpg "Plugin Center Architecture")

View File

@@ -0,0 +1,30 @@
---
title: Style Guide
---
Starting with version 2 of SCM-Manager we have decided to change the code style and conform to more common rules. Furthermore we abandon the rule, that everything needs to have a javadoc description. Nonetheless we have decided against a "big bang" adaption of the new rule, because this would have lead to enourmous problems for merges from 1.x to 2.x.
So whenever touching 1.x code you have to make the decision, whether it is appropriate to migrate some of the code you touch to the new style. Always keep in mind, that even slight changes may be dangerous becaus old code might not have a good test coverage.
Also it is a good guide line to adapt Postel's law: *Be conservative in what you do, be liberal in what you accept from others.* So do not be the wise guy changing everything that does not fit to the rules below just because.
## Java
Please mind the [EditorConfig](https://editorconfig.org/) file `.editorconfig` in the root of the SCM-Manager and the [configuration guide](docs/en/intellij-idea-configuration.mdation.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:
- public static fields
- private static fields
- public instant fields
- private instant fields
- constructors
- methods
- No "star imports", that is no `import java.util.*`
- One empty line between functions
- No separate lines for opening curly braces
- 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](scm-ui/ui-styles) directory.