Skip to content

Commit 4f37be7

Browse files
author
Craigory Coppola
committed
feat(core): schematic for adding npm package #5
#6 still needs to be implemented. The base sync schematic has been added, but is not implemented.
1 parent 36d2f30 commit 4f37be7

File tree

16 files changed

+312
-3
lines changed

16 files changed

+312
-3
lines changed

packages/core/generators.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@
2424
"description": "init generator",
2525
"alias": ["ng-add"],
2626
"hidden": true
27+
},
28+
"sync": {
29+
"factory": "./src/generators/sync/generator",
30+
"schema": "./src/generators/sync/schema.json",
31+
"description": "sync generator"
32+
},
33+
"nuget-reference": {
34+
"factory": "./src/generators/nuget-reference/generator",
35+
"schema": "./src/generators/nuget-reference/schema.json",
36+
"description": "nuget-reference generator"
2737
}
2838
}
2939
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
2+
import { Tree, readProjectConfiguration } from '@nrwl/devkit';
3+
4+
import generator from './generator';
5+
import { NugetReferenceGeneratorSchema } from './schema';
6+
7+
describe('nuget-reference generator', () => {
8+
let appTree: Tree;
9+
const options: NugetReferenceGeneratorSchema = {
10+
packageName: 'test',
11+
project: 'test',
12+
};
13+
14+
beforeEach(() => {
15+
appTree = createTreeWithEmptyWorkspace();
16+
});
17+
18+
it('should run successfully', async () => {
19+
// await generator(appTree, options);
20+
expect(true).toBeTruthy();
21+
});
22+
});
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { readProjectConfiguration, Tree } from '@nrwl/devkit';
2+
3+
import {
4+
dotnetAddPackageFlags,
5+
DotNetClient,
6+
dotnetFactory,
7+
} from '@nx-dotnet/dotnet';
8+
import { getProjectFileForNxProject } from '@nx-dotnet/utils';
9+
10+
import { NugetReferenceGeneratorSchema } from './schema';
11+
12+
export default async function (
13+
host: Tree,
14+
options: NugetReferenceGeneratorSchema,
15+
dotnetClient = new DotNetClient(dotnetFactory())
16+
) {
17+
const project = readProjectConfiguration(host, options.project);
18+
const projectFilePath = await getProjectFileForNxProject(project);
19+
20+
dotnetClient.addPackageReference(
21+
projectFilePath,
22+
options.packageName,
23+
Object.keys(options)
24+
.filter((x) => x !== 'packageName' && x !== 'project')
25+
.map((x) => ({
26+
flag: x as dotnetAddPackageFlags,
27+
value: options[x as keyof NugetReferenceGeneratorSchema],
28+
}))
29+
);
30+
31+
return {
32+
success: true,
33+
};
34+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export interface NugetReferenceGeneratorSchema {
2+
project: string;
3+
packageName: string;
4+
version?: string;
5+
framework?: string;
6+
packageDirectory?: string;
7+
prerelease?: boolean;
8+
source?: string;
9+
noRestore?: boolean;
10+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"$schema": "http://json-schema.org/schema",
3+
"cli": "nx",
4+
"id": "NugetReference",
5+
"title": "",
6+
"type": "object",
7+
"properties": {
8+
"project": {
9+
"type": "string",
10+
"description": "",
11+
"$default": {
12+
"$source": "argv",
13+
"index": 0
14+
},
15+
"x-prompt": "What project should the package be added to?"
16+
},
17+
"packageName": {
18+
"type": "string",
19+
"description": "Which package should be added?",
20+
"$default": {
21+
"$source": "argv",
22+
"index": 1
23+
}
24+
},
25+
"version": {
26+
"type": "string",
27+
"description": "A directory where the project is placed",
28+
"$default": {
29+
"$source": "argv",
30+
"index": 2
31+
}
32+
},
33+
"framework": {
34+
"type": "string",
35+
"description": "Adds a package reference only when targeting a specific framework."
36+
},
37+
"packageDirectory": {
38+
"type": "string",
39+
"description": "The directory where to restore the packages. The default package restore location is %userprofile%\\.nuget\\packages on Windows and ~/.nuget/packages on macOS and Linux. For more information, see [Managing the global packages, cache, and temp folders in NuGet](https://docs.microsoft.com/en-us/nuget/consume-packages/managing-the-global-packages-and-cache-folders)."
40+
},
41+
"prerelease": {
42+
"type": "boolean",
43+
"description": "Allows prerelease packages to be installed. Available since .NET Core 5 SDK"
44+
},
45+
"source": {
46+
"type": "string",
47+
"description": "The URI of the NuGet package source to use during the restore operation."
48+
},
49+
"noRestore": {
50+
"type": "boolean",
51+
"description": "Adds a package reference without performing a restore preview and compatibility check."
52+
}
53+
},
54+
"required": ["packageName", "project"]
55+
}

packages/core/src/generators/project-reference/generator.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { formatFiles, readProjectConfiguration, Tree } from '@nrwl/devkit';
1+
import { readProjectConfiguration, Tree } from '@nrwl/devkit';
22

33
import { DotNetClient, dotnetFactory } from '@nx-dotnet/dotnet';
44
import { getProjectFileForNxProject } from '@nx-dotnet/utils';
@@ -24,6 +24,4 @@ export default async function (
2424
}
2525

2626
client.addProjectReference(hostProjectFile, sourceProjectFile);
27-
28-
await formatFiles(host);
2927
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
2+
import { Tree, readProjectConfiguration } from '@nrwl/devkit';
3+
4+
import generator from './generator';
5+
import { SyncGeneratorSchema } from './schema';
6+
7+
describe('sync generator', () => {
8+
let appTree: Tree;
9+
const options: SyncGeneratorSchema = { name: 'test' };
10+
11+
beforeEach(() => {
12+
appTree = createTreeWithEmptyWorkspace();
13+
});
14+
15+
it('should run successfully', async () => {
16+
// await generator(appTree, options);
17+
expect(true).toBeTruthy();
18+
});
19+
});
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import {
2+
addProjectConfiguration,
3+
formatFiles,
4+
generateFiles,
5+
getWorkspaceLayout,
6+
names,
7+
offsetFromRoot,
8+
Tree,
9+
} from '@nrwl/devkit';
10+
import * as path from 'path';
11+
import { SyncGeneratorSchema } from './schema';
12+
13+
interface NormalizedSchema extends SyncGeneratorSchema {
14+
projectName: string;
15+
projectRoot: string;
16+
projectDirectory: string;
17+
parsedTags: string[];
18+
}
19+
20+
function normalizeOptions(
21+
host: Tree,
22+
options: SyncGeneratorSchema
23+
): NormalizedSchema {
24+
const name = names(options.name).fileName;
25+
const projectDirectory = options.directory
26+
? `${names(options.directory).fileName}/${name}`
27+
: name;
28+
const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-');
29+
const projectRoot = `${getWorkspaceLayout(host).libsDir}/${projectDirectory}`;
30+
const parsedTags = options.tags
31+
? options.tags.split(',').map((s) => s.trim())
32+
: [];
33+
34+
return {
35+
...options,
36+
projectName,
37+
projectRoot,
38+
projectDirectory,
39+
parsedTags,
40+
};
41+
}
42+
43+
function addFiles(host: Tree, options: NormalizedSchema) {
44+
const templateOptions = {
45+
...options,
46+
...names(options.name),
47+
offsetFromRoot: offsetFromRoot(options.projectRoot),
48+
template: '',
49+
};
50+
generateFiles(
51+
host,
52+
path.join(__dirname, 'files'),
53+
options.projectRoot,
54+
templateOptions
55+
);
56+
}
57+
58+
export default async function (host: Tree, options: SyncGeneratorSchema) {
59+
const normalizedOptions = normalizeOptions(host, options);
60+
addProjectConfiguration(host, normalizedOptions.projectName, {
61+
root: normalizedOptions.projectRoot,
62+
projectType: 'library',
63+
sourceRoot: `${normalizedOptions.projectRoot}/src`,
64+
targets: {
65+
build: {
66+
executor: '@nx-dotnet/core:build',
67+
},
68+
},
69+
tags: normalizedOptions.parsedTags,
70+
});
71+
addFiles(host, normalizedOptions);
72+
await formatFiles(host);
73+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface SyncGeneratorSchema {
2+
name: string;
3+
tags?: string;
4+
directory?: string;
5+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"$schema": "http://json-schema.org/schema",
3+
"cli": "nx",
4+
"id": "Sync",
5+
"title": "",
6+
"type": "object",
7+
"properties": {
8+
"name": {
9+
"type": "string",
10+
"description": "",
11+
"$default": {
12+
"$source": "argv",
13+
"index": 0
14+
},
15+
"x-prompt": "What name would you like to use?"
16+
},
17+
"tags": {
18+
"type": "string",
19+
"description": "Add tags to the project (used for linting)",
20+
"alias": "t"
21+
},
22+
"directory": {
23+
"type": "string",
24+
"description": "A directory where the project is placed",
25+
"alias": "d"
26+
}
27+
},
28+
"required": ["name"]
29+
}

0 commit comments

Comments
 (0)