Skip to content

Commit bf046c7

Browse files
authored
feat(compildconfig): support multiple projects (#229)
* feat(compildconfig): support multiple projects This Pr adds the `--project` option to Scully. This makes it possible to support multiple projects in 1 cli app BREAKING CHANGE: The `scully.config.js` is now named `scully.projectName.config.js` You need to manually update the name. * Delete scully.scullyDocs.config.jsconfi accidentially commited * docs(mutliproject): added docs and better erros for multiproject * feat(configfile): add configFile optiona back in
1 parent 641ca23 commit bf046c7

File tree

7 files changed

+200
-35
lines changed

7 files changed

+200
-35
lines changed

docs/scully-cmd-line.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Scully command line options
2+
3+
Scully has the following options available:
4+
5+
- [Scully command line options](#scully-command-line-options)
6+
- [serve](#serve)
7+
- [showBrowser](#showbrowser)
8+
- [configFile](#configfile)
9+
- [project](#project)
10+
11+
## serve
12+
13+
```bash
14+
npx scully serve
15+
```
16+
17+
this starts the scully server helper on its own. You can use this to inspect the result from Scully, or to speed up the scully proccess a bit. it does not _build_ the project, it only serves the angular build files, and the scully result files.
18+
19+
## showBrowser
20+
21+
```bash
22+
npx scully --showBrowser
23+
```
24+
25+
Alias `--sb`. This will show the chromium browser that is rendering your application. Can be used to diagnose some issues
26+
27+
## configFile
28+
29+
```bash
30+
npx scully --configFile someName
31+
```
32+
33+
Alias `--cf`. loads a different config file. if used at the same time as `--project` the project flag takes precedence.
34+
35+
## project
36+
37+
```bash
38+
npx scully --project someName
39+
```
40+
41+
Alias `--pr`. This enables you to select a different project. Scully by default uses the project that is the default project of the Angular CLI. When you want to run for another project, you can use this option, or use the Angular CLI to set another default project.

docs/scully.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Visit one of the following topics:
1717
- [Pre-requisites](pre-requisites.md)
1818
- [Getting Started](getting-started.md)
1919
- [Scully Configuration](scully-configuration.md)
20+
- [Scully command line options](./scully-cmd-line.md)
2021
- [Adding Blog Support](blog.md)
2122
- [Working with Plugins](plugins.md)
2223
- [Polyfills](polyfills.md)

scully.sampleBlog.config.js

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/** load the plugin */
2+
require('./extraPlugin/extra-plugin.js');
3+
require('./extraPlugin/tocPlugin');
4+
require('./extraPlugin/voidPlugin');
5+
6+
exports.config = {
7+
/** projectRoot is mandatory! */
8+
projectRoot: './projects/sampleBlog/src/app',
9+
/** outDir is where the static distribution files end up */
10+
outDir: './dist/static',
11+
// hostName: '0.0.0.0',
12+
extraRoutes: [''],
13+
routes: {
14+
'/demo/:id': {
15+
type: 'extra',
16+
numberOfPages: 5,
17+
},
18+
'/home/:topLevel': {
19+
type: 'extra',
20+
data: [
21+
{title: 'All routes in application', data: 'all'},
22+
{title: 'Unpublished routes in application', data: 'unpublished'},
23+
{title: 'Toplevel routes in application', data: ''},
24+
],
25+
},
26+
'/user/:userId': {
27+
// Type is mandatory
28+
type: 'json',
29+
/**
30+
* Every parameter in the route must exist here
31+
*/
32+
userId: {
33+
url: 'https://jsonplaceholder.typicode.com/users',
34+
property: 'id',
35+
},
36+
},
37+
'/nouser/:userId/:friendCode': {
38+
// Type is mandatory
39+
type: 'json',
40+
/**
41+
* Every parameter in the route must exist here
42+
*/
43+
userId: {
44+
url: 'https://jsonplaceholder.typicode.com/users',
45+
property: 'id',
46+
},
47+
friendCode: {
48+
/** users are their own friend in this sample ;) */
49+
url: 'https://jsonplaceholder.typicode.com/users?userId=${userId}',
50+
property: 'id',
51+
},
52+
},
53+
'/todos/:todoId': {
54+
// Type is mandatory
55+
type: 'json',
56+
/**
57+
* Every parameter in the route must exist here
58+
*/
59+
todoId: {
60+
url: 'https://jsonplaceholder.typicode.com/todos',
61+
property: 'id',
62+
/**
63+
* Headers can be sent optionally
64+
*/
65+
headers: {
66+
'API-KEY': '0123456789',
67+
},
68+
},
69+
},
70+
'/nouser/:userId/:posts/:comments': {
71+
// Type is mandatory
72+
type: 'json',
73+
/**
74+
* Every parameter in the route must exist here
75+
*/
76+
userId: {
77+
url: 'https://jsonplaceholder.typicode.com/users',
78+
property: 'id',
79+
},
80+
posts: {
81+
url: 'https://jsonplaceholder.typicode.com/posts?userId=${userId}',
82+
property: 'id',
83+
},
84+
comments: {
85+
url: 'https://jsonplaceholder.typicode.com/comments?postId=${posts}',
86+
property: 'id',
87+
},
88+
},
89+
'/blog/:slug': {
90+
type: 'contentFolder',
91+
postRenderers: ['toc'],
92+
slug: {
93+
folder: './blog',
94+
},
95+
},
96+
'/**': {
97+
type: 'void',
98+
},
99+
},
100+
};

scully/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@scullyio/scully",
3-
"version": "0.0.60",
3+
"version": "0.0.61",
44
"description": "Scully CLI",
55
"repository": {
66
"type": "GIT",
@@ -10,7 +10,9 @@
1010
"scully": "./scully.js"
1111
},
1212
"main": "/index.js",
13-
"scripts": {},
13+
"scripts": {
14+
"postinstall": "npx scully killServer"
15+
},
1416
"dependencies": {
1517
"asciidoctor.js": "^1.5.9",
1618
"chalk": "2.4.2",

scully/utils/compileConfig.ts

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,62 @@
1-
import {pathExists} from 'fs-extra';
1+
import {pathExists, readFileSync} from 'fs-extra';
22
import {join} from 'path';
33
import * as yargs from 'yargs';
4-
import {ScullyConfig} from '..';
5-
import {angularRoot, scullyConfig} from './config';
6-
import {logWarn, yellow} from './log';
4+
import {findAngularJsonPath} from './findAngularJsonPath';
5+
import {ScullyConfig} from './interfacesandenums';
6+
import {logError, logWarn, yellow} from './log';
77

8-
export const {configFile: configFileName} = yargs
8+
const angularRoot = findAngularJsonPath();
9+
10+
let angularConfig;
11+
12+
try {
13+
angularConfig = JSON.parse(readFileSync(join(angularRoot, 'angular.json')).toString());
14+
} catch (e) {
15+
logError(`Angular config file could not be parsed!`, e);
16+
process.exit(15);
17+
}
18+
const defaFaultProjectName = angularConfig.defaultProject;
19+
20+
const createConfigName = (name = defaFaultProjectName) => `scully.${name}.config.js`;
21+
22+
export const {configFile: configFileName, project} = yargs
923
.string('cf')
1024
.alias('cf', 'configFile')
11-
.default('cf', 'scully.config.js')
12-
.describe('cf', 'provide name for config file').argv;
25+
.default('cf', '')
26+
.describe(
27+
'cf',
28+
'provide name of the config file to use. if the option --project is also there that takes precedence)'
29+
)
30+
.string('pr')
31+
.alias('pr', 'project')
32+
.default('pr', '')
33+
.describe('pr', 'provide name of the project to handle').argv;
1334

1435
export const compileConfig = async (): Promise<ScullyConfig> => {
1536
try {
16-
const path = join(angularRoot, configFileName);
37+
let path = join(angularRoot, createConfigName());
38+
if (configFileName) {
39+
path = join(angularRoot, configFileName);
40+
}
41+
if (project) {
42+
path = join(angularRoot, createConfigName(project));
43+
}
1744
if (!(await pathExists(path))) {
18-
/** no ts config, nothing to do. */
19-
logWarn(`Config file "${yellow(path)}" not found, only rendering normal routes`);
20-
return ({} as unknown) as ScullyConfig;
45+
/** no js config, nothing to do. */
46+
logWarn(`
47+
---------
48+
Config file "${yellow(path)}" not found, only rendering routes without parameters
49+
The config file should have a name that is formated as:
50+
scully.${yellow('<projectName>')}.config.js
51+
where ${yellow('<projectName>')} is the name of the project as defined in the 'angular.json' file
52+
---------
53+
`);
54+
return ({projectName: project || defaFaultProjectName} as unknown) as ScullyConfig;
2155
}
2256
const {config} = await import(path);
23-
return config;
57+
return {projectName: project || defaFaultProjectName, ...config};
2458
} catch (e) {
25-
console.error(e);
26-
return ({} as unknown) as ScullyConfig;
59+
// console.error(e);
60+
return ({projectName: project || defaFaultProjectName} as unknown) as ScullyConfig;
2761
}
2862
};
29-
30-
function myReq(path: string): Promise<any> {
31-
return import(join(scullyConfig.homeFolder, path));
32-
}

scully/utils/config.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,13 @@ export const angularRoot = findAngularJsonPath();
1010
export const scullyConfig: ScullyConfig = {} as ScullyConfig;
1111

1212
const loadIt = async () => {
13-
// const userConfigFileLocation = join(angularRoot, 'scully.json');
14-
// const userConfigRaw = readFileSync(userConfigFileLocation).toString() || '';
1513
const compiledConfig = await compileConfig();
16-
// let unCheckedUserConfig = {};
1714
let angularConfig = {} as any;
18-
let distFolder = join(angularRoot, './dist/browser');
19-
// console.log({compiledConfig});
20-
// try {
21-
// unCheckedUserConfig = jsonc.parse(userConfigRaw);
22-
// } catch {
23-
// logError(`Scully config file could not be parsed!`);
24-
// process.exit(0);
25-
// }
26-
// const userConfig = await validateConfig((unCheckedUserConfig as unknown) as ScullyConfig);
15+
let distFolder = join(angularRoot, './dist');
2716
try {
2817
angularConfig = jsonc.parse(readFileSync(join(angularRoot, 'angular.json')).toString());
2918
// TODO: make scully handle other projects as just the default one.
30-
const defaultProject = angularConfig.defaultProject;
19+
const defaultProject = compiledConfig.projectName;
3120
distFolder = angularConfig.projects[defaultProject].architect.build.options.outputPath;
3221
if (distFolder.endsWith('dist') && !distFolder.includes('/')) {
3322
logError(
@@ -36,7 +25,7 @@ const loadIt = async () => {
3625
process.exit(15);
3726
}
3827
} catch (e) {
39-
logError(`Angular config file could not be parsed!`, e);
28+
logError(`Could not find project "${yellow(compiledConfig.projectName)}" in 'angular.json'.`);
4029
process.exit(15);
4130
}
4231

scully/utils/interfacesandenums.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ export enum RouteTypes {
77
}
88

99
export interface ScullyConfig {
10+
/** the name of the project we are using. Provided by Scully itself */
11+
projectName: string;
1012
/** the folder where the app-source is. Can be any off the projects in a repo */
1113
projectRoot: string;
1214
/** Array with string ID's of the content-renderes that will be run on all routes */
@@ -53,7 +55,7 @@ export type RouteTypeJson = {
5355
property: string;
5456
headers?: HeadersObject;
5557
// A handler to map the results to an array that can then be deepGet-ed
56-
resultsHandler?: Function;
58+
resultsHandler?: (raw: any) => any[];
5759
};
5860
};
5961

0 commit comments

Comments
 (0)