Merge pull request #12 from spotify/mob/add-plugin-architecture
Improve plugin template and add plugin generator
This commit is contained in:
@@ -8,6 +8,33 @@ Backstage is an open platform for building developer portals.
|
||||
|
||||
## Getting started
|
||||
|
||||
## Plugins
|
||||
|
||||
### Creating a Plugin
|
||||
|
||||
Run the following:
|
||||
|
||||
```bash
|
||||
$ ./tools/cookiecutter/init.sh frontend/packages/plugins/_template --output-dir frontend/packages/plugins
|
||||
```
|
||||
|
||||
This will generate a plugin in the `frontend/packages/plugins` folder. It is important to note you will still need to include the plugin in your `frontend/packages/app` in the `package.json`. You will then be able to import it as follows:
|
||||
|
||||
```bash
|
||||
$ ./tools/cookiecutter/init.sh frontend/packages/plugins/_template --output-dir frontend/packages/plugins
|
||||
plugin_name [example-plugin]: github-api
|
||||
|
||||
$ vim frontend/packages/app/package.json
|
||||
# Add the following line to your package.json
|
||||
# Note all plugins are prefixed with "plugin-" by default with a version number of "0.0.0"
|
||||
# "@backstage/plugin-github-api": "0.0.0",
|
||||
|
||||
$ vim frontend/packages/app/src/App.tsx
|
||||
# Add the following line to import your generated component
|
||||
# import { ExampleComponent } from '@backstage/plugin-github-api';
|
||||
# <ExampleComponent />
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
## License
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugin_name": "example-plugin"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def validate(name, regex, error_message):
|
||||
if not re.match(regex, name):
|
||||
print(error_message % name)
|
||||
|
||||
# exits with status 1 to indicate failure
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
validate('{{ cookiecutter.plugin_name }}',
|
||||
r'^[a-z-]+$', 'ERROR: %s is not a valid plugin name! Only lowercase letters and hyphens are valid (Examples: my-amazing-plugin, myamazingplugin).')
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from './plugin';
|
||||
@@ -1,7 +0,0 @@
|
||||
import plugin from './plugin';
|
||||
|
||||
describe('plugin-1', () => {
|
||||
it('should export plugin', () => {
|
||||
expect(plugin.id).toBe('change-me-id');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
Welcome to your {{cookiecutter.plugin_name}} plugin!
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@backstage/__CHANGE_ME__",
|
||||
"name": "@backstage/plugin-{{ cookiecutter.plugin_name }}",
|
||||
"version": "0.0.0",
|
||||
"main": "src/index.ts",
|
||||
"main:src": "src/index.ts",
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import ExampleComponent from './ExampleComponent';
|
||||
|
||||
describe('ExampleComponent', () => {
|
||||
it('should render', () => {
|
||||
const rendered = render(<ExampleComponent />);
|
||||
expect(rendered.getByText('Hello!')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import React, { FC } from 'react';
|
||||
import Button from '@material-ui/core/Button';
|
||||
|
||||
const ExampleComponent: FC<{}> = () => {
|
||||
return (
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => window.location.reload()}
|
||||
>
|
||||
Hello!
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
export default ExampleComponent;
|
||||
+1
@@ -0,0 +1 @@
|
||||
export { default } from './ExampleComponent';
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default } from './plugin';
|
||||
export { default as ExampleComponent } from './components/ExampleComponent';
|
||||
@@ -0,0 +1,7 @@
|
||||
import plugin from './plugin';
|
||||
|
||||
describe('{{ cookiecutter.plugin_name }}', () => {
|
||||
it('should export plugin', () => {
|
||||
expect(plugin.id).toBe('{{ cookiecutter.plugin_name }}');
|
||||
});
|
||||
});
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { createPlugin } from '@backstage/core';
|
||||
|
||||
export default createPlugin({
|
||||
id: 'change-me-id',
|
||||
id: '{{ cookiecutter.plugin_name }}',
|
||||
});
|
||||
@@ -0,0 +1,3 @@
|
||||
FROM python:3.8-slim
|
||||
RUN pip install cookiecutter==1.7.0 --index-url https://pypi.python.org/simple
|
||||
ENTRYPOINT [ "cookiecutter" ]
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# Build the container
|
||||
docker build $(pwd)/tools/cookiecutter -t backstage/tools/cookiecutter --quiet
|
||||
|
||||
# Run cookiecutter with our arguments
|
||||
COOKIECUTTER_FLAGS=${@:-""}
|
||||
docker run -it -v $(pwd):/app -w /app backstage/tools/cookiecutter $COOKIECUTTER_FLAGS
|
||||
Reference in New Issue
Block a user