Skip to content
This repository was archived by the owner on Jan 20, 2023. It is now read-only.

Commit 92f5d80

Browse files
Add licence-header-plugin sample. (#30)
* Add licence-header-plugin sample. Signed-off-by: Oleksandr Andriienko <[email protected]> * Fix addressed chage. Simplify a bit code. Signed-off-by: Oleksandr Andriienko <[email protected]>
1 parent 0b35263 commit 92f5d80

File tree

7 files changed

+1694
-0
lines changed

7 files changed

+1694
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
dist/
2+
lib/
3+
node_modules/
4+
*.theia
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# licence-header-plugin
2+
licence-header-plugin example for che-theia. Plugin generates new MIT license file header on file edition in format:
3+
4+
```js
5+
/*
6+
* Copyright (c) 2019 Simon's cat. All rights reserved.
7+
* @license MIT
8+
*/
9+
10+
function meow() {
11+
console.log('Feed me');
12+
}
13+
```
14+
15+
# How to test it
16+
This plugin works with node projects with file extensions '.js', '.ts'. In the package.json should be declared licence type 'MIT' and author(optinal):
17+
```json
18+
{
19+
"name": "SimonEmulator",
20+
"version": "1.0.0",
21+
"description": "Let's feed Simon's cat",
22+
"main": "index.js",
23+
"scripts": {
24+
"test": "echo \"Info: no test specified\" && exit 1"
25+
},
26+
"author": "Simon's cat",
27+
"license": "MIT"
28+
}
29+
```
30+
31+
Open project in the che-theia and open any '.js' or '.ts' file. Change something in the file. Plugin analizes file content.
32+
In case if file doesn't contains MIT license header, than plugin generate it on the top of the file.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "licence-header-plugin",
3+
"publisher": "eclipse-che",
4+
"keywords": [
5+
"theia-plugin"
6+
],
7+
"version": "0.0.1",
8+
"license": "EPL-2.0",
9+
"files": [
10+
"src"
11+
],
12+
"devDependencies": {
13+
"@theia/plugin": "next",
14+
"@theia/plugin-packager": "latest",
15+
"rimraf": "2.6.2",
16+
"typescript-formatter": "7.2.2",
17+
"typescript": "2.9.2"
18+
},
19+
"scripts": {
20+
"prepare": "yarn run clean && yarn run build",
21+
"clean": "rimraf lib",
22+
"format-code": "tsfmt -r",
23+
"watch": "tsc -watch",
24+
"compile": "tsc",
25+
"build": "yarn run format-code && yarn run compile && theia:plugin pack"
26+
},
27+
"engines": {
28+
"theiaPlugin": "next"
29+
},
30+
"theiaPlugin": {
31+
"backend": "lib/licence-header-plugin-backend.js"
32+
}
33+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*********************************************************************
2+
* Copyright (c) 2019 Red Hat, Inc.
3+
*
4+
* This program and the accompanying materials are made
5+
* available under the terms of the Eclipse Public License 2.0
6+
* which is available at https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
**********************************************************************/
10+
11+
import * as theia from '@theia/plugin';
12+
import * as fs from 'fs';
13+
import * as path from 'path';
14+
export const YEARS_IDENTIFIER = '${Years}';
15+
export const AUTHORS_IDENTIFIER = '${Authors}';
16+
17+
export const MIT_LICENSE_HEADER_CONTENT = `/*\n* Copyright (c) ${YEARS_IDENTIFIER}${AUTHORS_IDENTIFIER}. All rights reserved.\n* @license MIT\n*/\n`;
18+
export const MIT_LICENSE_HEDER_REGEXP = new RegExp(/.*(Copyright \(c\) ).*(. All rights reserved.\n).*(@license MIT\n).*/);
19+
20+
export const PACKAGE_JSON = 'package.json';
21+
22+
export const SUPPORTED_EXTENSIONS = ['.js', '.ts'];
23+
export const SUPPORTED_LICENCE_HEADERS = ['MIT'];
24+
25+
export class LicenseHeader {
26+
27+
constructor(private readonly authors: string, private readonly licenseContent: string, private readonly licenceRegexp: RegExp) { }
28+
29+
getHeader(): string {
30+
const currentYear = new Date().getFullYear();
31+
const spaceAfterYear = this.authors ? ' ' : '';
32+
const header = this.licenseContent.replace(YEARS_IDENTIFIER, currentYear + spaceAfterYear).replace(AUTHORS_IDENTIFIER, this.authors || '');
33+
return header;
34+
}
35+
36+
getRegExpr(): RegExp {
37+
return this.licenceRegexp;
38+
}
39+
}
40+
41+
export function start(context: theia.PluginContext) {
42+
context.subscriptions.push(theia.workspace.onWillSaveTextDocument(fileSaveEvent => {
43+
const fileContentPromise = new Promise<void | theia.TextEdit[]>((resolve, reject) => {
44+
const document = fileSaveEvent.document;
45+
const fileExt = path.extname(document.uri.fsPath);
46+
if (!isSupportedValue(fileExt, SUPPORTED_EXTENSIONS)) {
47+
resolve([]);
48+
}
49+
const fileUri = document.uri;
50+
const workspaceFolder: theia.WorkspaceFolder | theia.Uri | undefined = theia.workspace.getWorkspaceFolder(fileUri);
51+
let workspaceFolderUri: theia.Uri | undefined;
52+
if (workspaceFolder) {
53+
workspaceFolderUri = workspaceFolder instanceof theia.Uri ? workspaceFolder : workspaceFolder.uri;
54+
}
55+
56+
if (workspaceFolderUri) {
57+
const packageJsonPath = path.resolve(workspaceFolderUri.fsPath, PACKAGE_JSON);
58+
if (fs.existsSync(packageJsonPath)) {
59+
const packageJson = require(packageJsonPath);
60+
61+
if (document && packageJson.license && isSupportedValue(packageJson.license, SUPPORTED_LICENCE_HEADERS)) {
62+
const fileText = document.getText();
63+
64+
const textEdits: theia.TextEdit[] = [];
65+
const mitLicenceHeader = new LicenseHeader(packageJson.author, MIT_LICENSE_HEADER_CONTENT, MIT_LICENSE_HEDER_REGEXP);
66+
67+
if (!mitLicenceHeader.getRegExpr().test(fileText)) {
68+
const licenceHeaderEdit = theia.TextEdit.insert(document.lineAt(0).range.start, mitLicenceHeader.getHeader());
69+
textEdits.push(licenceHeaderEdit);
70+
}
71+
resolve(textEdits);
72+
}
73+
}
74+
}
75+
resolve();
76+
});
77+
78+
fileSaveEvent.waitUntil(fileContentPromise);
79+
}));
80+
}
81+
82+
function isSupportedValue(item: string, supportedElems: string[]): boolean {
83+
return supportedElems.findIndex((supportedElem => supportedElem === item)) >= 0;
84+
}
85+
86+
export function stop() {
87+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"compilerOptions": {
3+
"strict": true,
4+
"experimentalDecorators": true,
5+
"noUnusedLocals": true,
6+
"emitDecoratorMetadata": true,
7+
"downlevelIteration": true,
8+
"module": "commonjs",
9+
"moduleResolution": "node",
10+
"target": "es5",
11+
"lib": [
12+
"es6",
13+
"webworker"
14+
],
15+
"sourceMap": true,
16+
"rootDir": "src",
17+
"outDir": "lib"
18+
},
19+
"include": [
20+
"src"
21+
]
22+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"baseIndentSize": 0,
3+
"newLineCharacter": "\n",
4+
"indentSize": 4,
5+
"tabSize": 4,
6+
"indentStyle": 4,
7+
"convertTabsToSpaces": true,
8+
"insertSpaceAfterCommaDelimiter": true,
9+
"insertSpaceAfterSemicolonInForStatements": true,
10+
"insertSpaceBeforeAndAfterBinaryOperators": true,
11+
"insertSpaceAfterKeywordsInControlFlowStatements": true,
12+
"insertSpaceAfterFunctionKeywordForAnonymousFunctions": false,
13+
"insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false,
14+
"insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false,
15+
"insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false,
16+
"placeOpenBraceOnNewLineForFunctions": false,
17+
"placeOpenBraceOnNewLineForControlBlocks": false
18+
}

0 commit comments

Comments
 (0)