Skip to content

Commit

Permalink
feat(compildconfig): support multiple projects (#229)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
SanderElias authored Jan 24, 2020
1 parent 641ca23 commit bf046c7
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 35 deletions.
41 changes: 41 additions & 0 deletions docs/scully-cmd-line.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Scully command line options

Scully has the following options available:

- [Scully command line options](#scully-command-line-options)
- [serve](#serve)
- [showBrowser](#showbrowser)
- [configFile](#configfile)
- [project](#project)

## serve

```bash
npx scully serve
```

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.

## showBrowser

```bash
npx scully --showBrowser
```

Alias `--sb`. This will show the chromium browser that is rendering your application. Can be used to diagnose some issues

## configFile

```bash
npx scully --configFile someName
```

Alias `--cf`. loads a different config file. if used at the same time as `--project` the project flag takes precedence.

## project

```bash
npx scully --project someName
```

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.
1 change: 1 addition & 0 deletions docs/scully.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Visit one of the following topics:
- [Pre-requisites](pre-requisites.md)
- [Getting Started](getting-started.md)
- [Scully Configuration](scully-configuration.md)
- [Scully command line options](./scully-cmd-line.md)
- [Adding Blog Support](blog.md)
- [Working with Plugins](plugins.md)
- [Polyfills](polyfills.md)
Expand Down
100 changes: 100 additions & 0 deletions scully.sampleBlog.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/** load the plugin */
require('./extraPlugin/extra-plugin.js');
require('./extraPlugin/tocPlugin');
require('./extraPlugin/voidPlugin');

exports.config = {
/** projectRoot is mandatory! */
projectRoot: './projects/sampleBlog/src/app',
/** outDir is where the static distribution files end up */
outDir: './dist/static',
// hostName: '0.0.0.0',
extraRoutes: [''],
routes: {
'/demo/:id': {
type: 'extra',
numberOfPages: 5,
},
'/home/:topLevel': {
type: 'extra',
data: [
{title: 'All routes in application', data: 'all'},
{title: 'Unpublished routes in application', data: 'unpublished'},
{title: 'Toplevel routes in application', data: ''},
],
},
'/user/:userId': {
// Type is mandatory
type: 'json',
/**
* Every parameter in the route must exist here
*/
userId: {
url: 'https://jsonplaceholder.typicode.com/users',
property: 'id',
},
},
'/nouser/:userId/:friendCode': {
// Type is mandatory
type: 'json',
/**
* Every parameter in the route must exist here
*/
userId: {
url: 'https://jsonplaceholder.typicode.com/users',
property: 'id',
},
friendCode: {
/** users are their own friend in this sample ;) */
url: 'https://jsonplaceholder.typicode.com/users?userId=${userId}',
property: 'id',
},
},
'/todos/:todoId': {
// Type is mandatory
type: 'json',
/**
* Every parameter in the route must exist here
*/
todoId: {
url: 'https://jsonplaceholder.typicode.com/todos',
property: 'id',
/**
* Headers can be sent optionally
*/
headers: {
'API-KEY': '0123456789',
},
},
},
'/nouser/:userId/:posts/:comments': {
// Type is mandatory
type: 'json',
/**
* Every parameter in the route must exist here
*/
userId: {
url: 'https://jsonplaceholder.typicode.com/users',
property: 'id',
},
posts: {
url: 'https://jsonplaceholder.typicode.com/posts?userId=${userId}',
property: 'id',
},
comments: {
url: 'https://jsonplaceholder.typicode.com/comments?postId=${posts}',
property: 'id',
},
},
'/blog/:slug': {
type: 'contentFolder',
postRenderers: ['toc'],
slug: {
folder: './blog',
},
},
'/**': {
type: 'void',
},
},
};
6 changes: 4 additions & 2 deletions scully/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@scullyio/scully",
"version": "0.0.60",
"version": "0.0.61",
"description": "Scully CLI",
"repository": {
"type": "GIT",
Expand All @@ -10,7 +10,9 @@
"scully": "./scully.js"
},
"main": "/index.js",
"scripts": {},
"scripts": {
"postinstall": "npx scully killServer"
},
"dependencies": {
"asciidoctor.js": "^1.5.9",
"chalk": "2.4.2",
Expand Down
66 changes: 48 additions & 18 deletions scully/utils/compileConfig.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,62 @@
import {pathExists} from 'fs-extra';
import {pathExists, readFileSync} from 'fs-extra';
import {join} from 'path';
import * as yargs from 'yargs';
import {ScullyConfig} from '..';
import {angularRoot, scullyConfig} from './config';
import {logWarn, yellow} from './log';
import {findAngularJsonPath} from './findAngularJsonPath';
import {ScullyConfig} from './interfacesandenums';
import {logError, logWarn, yellow} from './log';

export const {configFile: configFileName} = yargs
const angularRoot = findAngularJsonPath();

let angularConfig;

try {
angularConfig = JSON.parse(readFileSync(join(angularRoot, 'angular.json')).toString());
} catch (e) {
logError(`Angular config file could not be parsed!`, e);
process.exit(15);
}
const defaFaultProjectName = angularConfig.defaultProject;

const createConfigName = (name = defaFaultProjectName) => `scully.${name}.config.js`;

export const {configFile: configFileName, project} = yargs
.string('cf')
.alias('cf', 'configFile')
.default('cf', 'scully.config.js')
.describe('cf', 'provide name for config file').argv;
.default('cf', '')
.describe(
'cf',
'provide name of the config file to use. if the option --project is also there that takes precedence)'
)
.string('pr')
.alias('pr', 'project')
.default('pr', '')
.describe('pr', 'provide name of the project to handle').argv;

export const compileConfig = async (): Promise<ScullyConfig> => {
try {
const path = join(angularRoot, configFileName);
let path = join(angularRoot, createConfigName());
if (configFileName) {
path = join(angularRoot, configFileName);
}
if (project) {
path = join(angularRoot, createConfigName(project));
}
if (!(await pathExists(path))) {
/** no ts config, nothing to do. */
logWarn(`Config file "${yellow(path)}" not found, only rendering normal routes`);
return ({} as unknown) as ScullyConfig;
/** no js config, nothing to do. */
logWarn(`
---------
Config file "${yellow(path)}" not found, only rendering routes without parameters
The config file should have a name that is formated as:
scully.${yellow('<projectName>')}.config.js
where ${yellow('<projectName>')} is the name of the project as defined in the 'angular.json' file
---------
`);
return ({projectName: project || defaFaultProjectName} as unknown) as ScullyConfig;
}
const {config} = await import(path);
return config;
return {projectName: project || defaFaultProjectName, ...config};
} catch (e) {
console.error(e);
return ({} as unknown) as ScullyConfig;
// console.error(e);
return ({projectName: project || defaFaultProjectName} as unknown) as ScullyConfig;
}
};

function myReq(path: string): Promise<any> {
return import(join(scullyConfig.homeFolder, path));
}
17 changes: 3 additions & 14 deletions scully/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,13 @@ export const angularRoot = findAngularJsonPath();
export const scullyConfig: ScullyConfig = {} as ScullyConfig;

const loadIt = async () => {
// const userConfigFileLocation = join(angularRoot, 'scully.json');
// const userConfigRaw = readFileSync(userConfigFileLocation).toString() || '';
const compiledConfig = await compileConfig();
// let unCheckedUserConfig = {};
let angularConfig = {} as any;
let distFolder = join(angularRoot, './dist/browser');
// console.log({compiledConfig});
// try {
// unCheckedUserConfig = jsonc.parse(userConfigRaw);
// } catch {
// logError(`Scully config file could not be parsed!`);
// process.exit(0);
// }
// const userConfig = await validateConfig((unCheckedUserConfig as unknown) as ScullyConfig);
let distFolder = join(angularRoot, './dist');
try {
angularConfig = jsonc.parse(readFileSync(join(angularRoot, 'angular.json')).toString());
// TODO: make scully handle other projects as just the default one.
const defaultProject = angularConfig.defaultProject;
const defaultProject = compiledConfig.projectName;
distFolder = angularConfig.projects[defaultProject].architect.build.options.outputPath;
if (distFolder.endsWith('dist') && !distFolder.includes('/')) {
logError(
Expand All @@ -36,7 +25,7 @@ const loadIt = async () => {
process.exit(15);
}
} catch (e) {
logError(`Angular config file could not be parsed!`, e);
logError(`Could not find project "${yellow(compiledConfig.projectName)}" in 'angular.json'.`);
process.exit(15);
}

Expand Down
4 changes: 3 additions & 1 deletion scully/utils/interfacesandenums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export enum RouteTypes {
}

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

Expand Down

0 comments on commit bf046c7

Please sign in to comment.