Skip to content
This repository was archived by the owner on Mar 19, 2019. It is now read-only.

Commit 8f7b8da

Browse files
authored
Merge pull request #28 from atomist-rugs/issue23
Add editor to make an existing project a basic generator
2 parents 1a6a632 + 59df92b commit 8f7b8da

File tree

5 files changed

+315
-1
lines changed

5 files changed

+315
-1
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright © 2017 Atomist, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { EditProject } from '@atomist/rug/operations/ProjectEditor'
18+
import { Project, File } from '@atomist/rug/model/Core'
19+
import { Pattern } from '@atomist/rug/operations/RugOperation'
20+
import { Editor, Parameter, Tags } from '@atomist/rug/operations/Decorators'
21+
import { PathExpression, PathExpressionEngine, TreeNode, Match } from '@atomist/rug/tree/PathExpression'
22+
import { addAssertionsForAllFilesInProject } from './ProjectToGeneratorOperations'
23+
24+
@Editor("ConvertExistingProjectToGenerator", "convert existing project to a Rug archive with a basic Generator")
25+
@Tags("rug", "atomist")
26+
class ConvertExistingProjectToGenerator implements EditProject {
27+
28+
@Parameter({
29+
displayName: "Rug Archive Name",
30+
description: "name of your new Rug Archive, typically the same as the repo name",
31+
pattern: Pattern.project_name,
32+
validInput: "a valid GitHub repo name containing only alphanumeric, ., -, and _ characters",
33+
minLength: 1,
34+
maxLength: 100
35+
})
36+
archive_name: string;
37+
38+
@Parameter({
39+
displayName: "Rug Archive Group ID",
40+
description: "Maven group identifier, often used to provide a namespace for your rugs, e.g., company-rugs, typically the GitHub owner",
41+
pattern: Pattern.group_id,
42+
validInput: "a valid Maven group ID, which starts with a letter, -, or _ and contains only alphanumeric, -, and _ characters and may having leading period separated identifiers starting with letters or underscores and containing only alphanumeric and _ characters",
43+
minLength: 1,
44+
maxLength: 100
45+
})
46+
group_id: string;
47+
48+
@Parameter({
49+
displayName: "Rug Archive Version",
50+
description: "initial version of the project, e.g., 1.2.3",
51+
pattern: Pattern.semantic_version,
52+
validInput: "a valid semantic version, http://semver.org",
53+
minLength: 1,
54+
maxLength: 100,
55+
required: false,
56+
})
57+
version: string = "0.1.0";
58+
59+
@Parameter({
60+
displayName: "Generator Name",
61+
description: "name of generator to add to Rug archive project",
62+
pattern: "^[A-Z][A-Za-z0-9]*$",
63+
validInput: "a valid generator name starting with a capital letter and consisting of alphanumeric characters from one to 100 characters long",
64+
minLength: 1,
65+
maxLength: 100
66+
})
67+
generator_name: string;
68+
69+
@Parameter({
70+
displayName: "Generator Description",
71+
description: "description of generator to add to Rug archive project",
72+
pattern: Pattern.any,
73+
validInput: "a string between one and 100 characters",
74+
minLength: 1,
75+
maxLength: 100
76+
})
77+
description: string
78+
79+
edit(project: Project) {
80+
if (project.fileExists(".atomist/manifest.yml")) {
81+
return;
82+
}
83+
project.editWith("ConvertExistingProjectToRugArchive", this);
84+
project.editWith("AddTypeScript", {})
85+
project.editWith("AddTypeScriptGenerator", this)
86+
87+
addAssertionsForAllFilesInProject(project, this.generator_name)
88+
}
89+
}
90+
91+
export const convertExistingProjectToGenerator = new ConvertExistingProjectToGenerator()
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright © 2017 Atomist, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { Project, File } from '@atomist/rug/model/Core'
18+
import { PathExpression, PathExpressionEngine } from '@atomist/rug/tree/PathExpression'
19+
20+
export function addAssertionsForAllFilesInProject(project: Project, generatorName: string): void {
21+
let originalTestAssertionsString = "then\n fileExists \"README.md\""
22+
23+
let testAssertionsString = project.files().reduce(function (acc, file) {
24+
if (notACommonPeripheralArtifact(file)) {
25+
if (acc === "then") {
26+
acc += "\n ";
27+
} else {
28+
acc += "\n and ";
29+
}
30+
acc += `fileExists "${file.path()}"`;
31+
}
32+
return acc;
33+
}, "then")
34+
35+
let eng: PathExpressionEngine = project.context().pathExpressionEngine();
36+
let testPathExpression = new PathExpression<Project, File>("/*[@name='.atomist']/tests/*[@name='" + generatorName + ".rt']");
37+
let testFile: File = eng.scalar(project, testPathExpression);
38+
testFile.replace(originalTestAssertionsString, testAssertionsString)
39+
}
40+
41+
function notACommonPeripheralArtifact(file: File): boolean {
42+
return (file.path().search("node_modules") < 0) &&
43+
(file.path().search(".idea") < 0) &&
44+
(file.path().search("target") < 0) &&
45+
(file.path().search(".atomist") < 0)
46+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
* Copyright © 2017 Atomist, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
scenario ConvertExistingProjectToGenerator should add Rug archive files and default generator
18+
19+
let archive_name = "my-rug-archive"
20+
let group_id = "my-rug-group"
21+
let version = "0.0.1"
22+
let manifest = ".atomist/manifest.yml"
23+
let generator_name = "MyNewGenerator"
24+
let description = "Description of MyNewGenerator"
25+
26+
given
27+
Empty
28+
29+
when
30+
ConvertExistingProjectToGenerator
31+
32+
then
33+
fileExists manifest
34+
and fileContains manifest { 'artifact: "' + archive_name + '"' }
35+
and fileContains manifest { 'group: "' + group_id + '"' }
36+
and fileContains manifest version
37+
and fileExists ".atomist/package.json"
38+
and fileContains ".atomist/package.json" '"@atomist/rug"'
39+
and fileContains ".atomist/package.json" '"0.12.0"'
40+
and fileExists ".atomist/tsconfig.json"
41+
and fileContains ".atomist/tsconfig.json" "suppressImplicitAnyIndexErrors"
42+
and fileExists ".atomist/.gitignore"
43+
and fileContains ".atomist/.gitignore" "node_modules"
44+
and directoryExists ".atomist/node_modules/@atomist/rug"
45+
and fileExists ".atomist/node_modules/@atomist/rug/model/Core.ts"
46+
and fileExists ".atomist/editors/MyNewGenerator.ts"
47+
and fileContains ".atomist/editors/MyNewGenerator.ts" '@Generator("MyNewGenerator"'
48+
and fileContains ".atomist/editors/MyNewGenerator.ts" "class MyNewGenerator"
49+
and fileContains ".atomist/editors/MyNewGenerator.ts" "new MyNewGenerator()"
50+
and { !result.fileContains(".atomist/editors/MyNewGenerator.ts", "TypeScriptGenerator") }
51+
and { !result.fileContains(".atomist/editors/MyNewGenerator.ts", "@DESCRIPTION@") }
52+
and { !result.fileContains(".atomist/editors/MyNewGenerator.ts", "typeScriptGenerator") }
53+
and fileExists ".atomist/tests/MyNewGenerator.rt"
54+
and fileContains ".atomist/tests/MyNewGenerator.rt" "scenario MyNewGenerator"
55+
and { !result.fileContains(".atomist/tests/MyNewGenerator.rt", "TypeScriptGenerator") }
56+
57+
58+
scenario ConvertExistingProjectToGenerator should add appropriate generator tests assertions
59+
60+
let archive_name = "my-rug-archive"
61+
let group_id = "my-rug-group"
62+
let version = "0.0.1"
63+
let manifest = ".atomist/manifest.yml"
64+
let generator_name = "MyNewGenerator"
65+
let description = "Description of MyNewGenerator"
66+
67+
given
68+
"README.md" = "Beulah"
69+
"CHANGELOG.md" = "Handsome Western States"
70+
"LICENSE" = "When Your Heartstrings Break"
71+
"configure" = "The Coast Is Never Clear"
72+
73+
when
74+
ConvertExistingProjectToGenerator
75+
76+
then
77+
fileExists manifest
78+
and fileContains manifest { 'artifact: "' + archive_name + '"' }
79+
and fileContains manifest { 'group: "' + group_id + '"' }
80+
and fileContains manifest version
81+
and fileExists ".atomist/package.json"
82+
and fileContains ".atomist/package.json" '"@atomist/rug"'
83+
and fileContains ".atomist/package.json" '"0.12.0"'
84+
and fileExists ".atomist/tsconfig.json"
85+
and fileContains ".atomist/tsconfig.json" "suppressImplicitAnyIndexErrors"
86+
and fileExists ".atomist/.gitignore"
87+
and fileContains ".atomist/.gitignore" "node_modules"
88+
and directoryExists ".atomist/node_modules/@atomist/rug"
89+
and fileExists ".atomist/node_modules/@atomist/rug/model/Core.ts"
90+
and fileExists ".atomist/editors/MyNewGenerator.ts"
91+
and fileContains ".atomist/editors/MyNewGenerator.ts" '@Generator("MyNewGenerator"'
92+
and fileContains ".atomist/editors/MyNewGenerator.ts" "class MyNewGenerator"
93+
and fileContains ".atomist/editors/MyNewGenerator.ts" "new MyNewGenerator()"
94+
and { !result.fileContains(".atomist/editors/MyNewGenerator.ts", "TypeScriptGenerator") }
95+
and { !result.fileContains(".atomist/editors/MyNewGenerator.ts", "@DESCRIPTION@") }
96+
and { !result.fileContains(".atomist/editors/MyNewGenerator.ts", "typeScriptGenerator") }
97+
and fileExists ".atomist/tests/MyNewGenerator.rt"
98+
and fileContains ".atomist/tests/MyNewGenerator.rt" "scenario MyNewGenerator"
99+
and { !result.fileContains(".atomist/tests/MyNewGenerator.rt", "TypeScriptGenerator") }
100+
and fileContains ".atomist/tests/MyNewGenerator.rt" 'fileExists "README.md"'
101+
and fileContains ".atomist/tests/MyNewGenerator.rt" 'fileExists "CHANGELOG.md"'
102+
and fileContains ".atomist/tests/MyNewGenerator.rt" 'fileExists "LICENSE"'
103+
and fileContains ".atomist/tests/MyNewGenerator.rt" 'fileExists "configure"'
104+
105+
106+
scenario ConvertExistingProjectToGenerator should make no change if project already contains a manifest
107+
108+
let archive_name = "my-rug-archive"
109+
let group_id = "my-rug-group"
110+
let version = "0.0.1"
111+
let generator_name = "MyNewGenerator"
112+
let description = "Description of MyNewGenerator"
113+
114+
given
115+
ArchiveRoot
116+
117+
when
118+
ConvertExistingProjectToGenerator
119+
120+
then
121+
NoChange

CHANGELOG.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10-
[Unreleased]: https://github.com/atomist-rugs/rug-editors/compare/0.12.0...HEAD
10+
[Unreleased]: https://github.com/atomist-rugs/rug-editors/compare/0.13.0...HEAD
11+
12+
## [0.13.0] - 2017-03-03
13+
14+
[0.13.0]: https://github.com/atomist-rugs/rug-editors/compare/0.12.0...0.13.0
15+
16+
One-step generator release
17+
18+
### Added
19+
20+
- `ConvertExistingProjectToGenerator` editor
1121

1222
## [0.12.0] - 2017-03-01
1323

README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,52 @@ $ rug edit atomist-rugs:rug-editors:AddTypeScriptHandler \
219219
This will add the file `.atomist/handlers/MyNewHandler.ts` to the
220220
project.
221221

222+
### ConvertExistingProjectToGenerator
223+
224+
The ConvertExistingProjectToGenerator editor creates a valid Rug
225+
generator from the current project. It does not make sense to run
226+
this more than once on a project.
227+
228+
#### Prerequisites
229+
230+
Before running this editor, you must have the following prerequisites
231+
satisfied.
232+
233+
* A source code repository for a "model" project that does not have
234+
a `.atomist/manifest.yml`
235+
236+
#### Parameters
237+
238+
To run this editor, you must supply the following parameters.
239+
240+
Name | Required | Default | Description
241+
-----|----------|---------|------------
242+
`archive_name` | Yes | | Name of the new Rug archive, typically the same as the repo name
243+
`group_id` | Yes | | Maven group ID, e.g., "company-rugs", typically the GitHub owner of the repo
244+
`version` | No | 0.1.0 | [Semantic version][semver] of the project.
245+
`generator_name` | Yes | | A valid Rug generator name between 1-100 characters, starting with a capital letter, and containing only alphanumeric characters
246+
`description` | Yes | | A description of the generator being added
247+
248+
#### Running
249+
250+
Run it as follows:
251+
252+
```
253+
$ cd project/directory
254+
$ rug edit atomist-rugs:rug-editors:ConvertExistingProjectToGenerator \
255+
archive_name=my-new-archive \
256+
group_id=my-rugs \
257+
version=2.71.828 \
258+
generator_name=MyNewGenerator \
259+
description="This is my newest generator."
260+
```
261+
262+
This will create a `.atomist` directory to the root of the project.
263+
The `.atomist` directory will have valid `manifest.yml` and
264+
`package.json` files, the generator script in
265+
`editors/MyNewGenerator.ts`, and its test in
266+
`tests/MyNewGenerator.rt`.
267+
222268
### ConvertExistingProjectToRugArchive
223269

224270
The ConvertExistingProjectToRugArchive editor creates a valid Rug

0 commit comments

Comments
 (0)