2020-11-16 10:20:16 -05:00
/ * *
* Copyright ( c ) Facebook , Inc . and its affiliates .
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree .
* /
2022-01-07 23:59:28 -05:00
/* eslint-disable import/no-extraneous-dependencies */
import fs from 'fs-extra' ;
import shell from 'shelljs' ;
2020-11-16 10:20:16 -05:00
2021-12-21 11:49:39 -05:00
const NODE _MAJOR _VERSION = parseInt ( process . versions . node . split ( '.' ) [ 0 ] , 10 ) ;
if ( NODE _MAJOR _VERSION < 16 ) {
throw new Error (
'This generateExamples Docusaurus script requires at least Node.js 16 and npm 7. See why here: https://github.com/facebook/docusaurus/pull/5722#issuecomment-948847891' ,
) ;
}
2020-11-16 11:09:44 -05:00
// Generate one example per init template
// We use those generated examples as CodeSandbox projects
// See https://github.com/facebook/docusaurus/issues/1699
2022-01-07 23:59:28 -05:00
async function generateTemplateExample ( template ) {
2020-11-16 10:20:16 -05:00
try {
console . log (
` generating ${ template } template for codesandbox in the examples folder... ` ,
) ;
2022-01-30 21:31:24 -05:00
// run the docusaurus script to create the template in the examples folder
2021-08-06 13:11:36 -04:00
const command = template . endsWith ( '-typescript' )
2021-10-20 06:45:06 -04:00
? template . replace ( '-typescript' , ' -- --typescript' )
2021-08-06 13:11:36 -04:00
: template ;
2022-01-07 23:59:28 -05:00
shell . exec (
2020-11-16 11:09:44 -05:00
// /!\ we use the published init script on purpose,
2022-01-30 21:31:24 -05:00
// because using the local init script is too early and could generate
// upcoming/unavailable config options. Remember CodeSandbox templates
// will use the published version, not the repo version
2021-10-07 10:06:42 -04:00
` npm init docusaurus@latest examples/ ${ template } ${ command } ` ,
2020-11-16 10:20:16 -05:00
) ;
// read the content of the package.json
const templatePackageJson = JSON . parse (
2022-01-07 23:59:28 -05:00
await fs . readFile ( ` examples/ ${ template } /package.json ` , 'utf8' ) ,
2020-11-16 10:20:16 -05:00
) ;
// attach the dev script which would be used in code sandbox by default
templatePackageJson . scripts . dev = 'docusaurus start' ;
2021-01-20 07:29:45 -05:00
// these example projects are not meant to be published to npm
templatePackageJson . private = true ;
2022-01-30 21:31:24 -05:00
// Make sure package.json name is not "examples-classic". The package.json
// name appears in CodeSandbox UI so let's display a good name!
// Unfortunately we can't use uppercase or spaces... See also
// https://github.com/codesandbox/codesandbox-client/pull/5136#issuecomment-763521662
2021-01-20 07:29:45 -05:00
templatePackageJson . name =
template === 'classic' ? 'docusaurus' : ` docusaurus- ${ template } ` ;
templatePackageJson . description =
template === 'classic'
? 'Docusaurus example project'
: ` Docusaurus example project ( ${ template } template) ` ;
2020-11-16 10:20:16 -05:00
// rewrite the package.json file with the new edit
2022-01-07 23:59:28 -05:00
await fs . writeFile (
2020-11-16 10:20:16 -05:00
` ./examples/ ${ template } /package.json ` ,
2021-12-24 09:11:35 -05:00
` ${ JSON . stringify ( templatePackageJson , null , 2 ) } \n ` ,
2020-11-16 10:20:16 -05:00
) ;
// create sandbox.config.json file at the root of template
2022-01-13 01:36:53 -05:00
const codeSandboxConfig = {
2020-11-16 10:20:16 -05:00
infiniteLoopProtection : true ,
hardReloadOnChange : true ,
view : 'browser' ,
2021-01-19 10:13:14 -05:00
template : 'docusaurus' ,
2021-04-07 12:28:06 -04:00
node : '14' ,
container : {
node : '14' ,
} ,
2020-11-16 10:20:16 -05:00
} ;
2022-01-07 23:59:28 -05:00
await fs . writeFile (
2020-11-16 10:20:16 -05:00
` ./examples/ ${ template } /sandbox.config.json ` ,
2022-01-13 01:36:53 -05:00
` ${ JSON . stringify ( codeSandboxConfig , null , 2 ) } \n ` ,
2021-07-28 13:27:58 -04:00
) ;
const stackBlitzConfig = {
installDependencies : true ,
startCommand : 'npm start' ,
} ;
2022-01-07 23:59:28 -05:00
await fs . writeFile (
2021-07-28 13:27:58 -04:00
` ./examples/ ${ template } /.stackblitzrc ` ,
2021-12-24 09:11:35 -05:00
` ${ JSON . stringify ( stackBlitzConfig , null , 2 ) } \n ` ,
2020-11-16 10:20:16 -05:00
) ;
console . log ( ` Generated example for template ${ template } ` ) ;
} catch ( error ) {
console . error ( ` Failed to generated example for template ${ template } ` ) ;
throw error ;
}
}
2022-01-30 21:31:24 -05:00
/ * *
* Starters are repositories / branches that only contains a newly initialized
* Docusaurus site . Those are useful for users to inspect ( may be more
* convenient than " examples / classic ) Also some tools like Netlify deploy button
* currently require using the main branch of a dedicated repo .
* See https : //github.com/jamstack/jamstack.org/pull/609
* Button visible here : https : //jamstack.org/generators/
2021-07-22 11:55:04 -04:00
* /
function updateStarters ( ) {
2021-09-03 10:54:06 -04:00
function forcePushGitSubtree ( { subfolder , remote , remoteBranch } ) {
console . log ( '' ) ;
// See https://stackoverflow.com/questions/33172857/how-do-i-force-a-subtree-push-to-overwrite-remote-changes
const command = ` git push ${ remote } \` git subtree split --prefix ${ subfolder } \` : ${ remoteBranch } --force ` ;
try {
console . log ( ` forcePushGitSubtree command: ${ command } ` ) ;
2022-01-07 23:59:28 -05:00
shell . exec ( command ) ;
2021-09-03 10:54:06 -04:00
console . log ( 'forcePushGitSubtree success!' ) ;
} catch ( e ) {
console . error (
` Can't force push to git subtree with command ' ${ command } ' ` ,
) ;
console . error ( ` If it's a permission problem, ask @slorber ` ) ;
console . error ( e ) ;
}
console . log ( '' ) ;
2021-07-22 11:55:04 -04:00
}
2021-09-03 10:54:06 -04:00
console . log ( '' ) ;
console . log ( 'Updating https://github.com/facebook/docusaurus/tree/starter' ) ;
forcePushGitSubtree ( {
subfolder : 'examples/classic' ,
remote : 'origin' ,
remoteBranch : 'starter' ,
} ) ;
console . log ( '' ) ;
console . log ( '' ) ;
// TODO replace by starter repo in Docusaurus-community org (if we get it)
console . log ( 'Updating https://github.com/slorber/docusaurus-starter' ) ;
forcePushGitSubtree ( {
subfolder : 'examples/classic' ,
remote : 'git@github.com:slorber/docusaurus-starter.git' ,
remoteBranch : 'main' ,
} ) ;
console . log ( '' ) ;
2021-07-22 11:55:04 -04:00
}
2022-01-07 23:59:28 -05:00
const branch = shell . exec ( 'git rev-parse --abbrev-ref HEAD' ) . stdout ;
if ( branch === 'main' ) {
throw new Error (
"Please don't generate Docusaurus examples from the main branch!\nWe are going to commit during this process!" ,
) ;
}
if ( shell . exec ( 'git diff --exit-code' ) . code !== 0 ) {
throw new Error (
'Please run the generate examples command with a clean Git state and no uncommitted local changes. git diff should display nothing!' ,
) ;
2021-07-28 13:27:58 -04:00
}
2022-01-07 23:59:28 -05:00
console . log ( `
# Generate examples start !
` );
// delete the examples directories if they exists
console . log ( ` -------
# # Removing example folders ...
` );
await fs . rm ( './examples/classic' , { recursive : true , force : true } ) ;
await fs . rm ( './examples/classic-typescript' , { recursive : true , force : true } ) ;
await fs . rm ( './examples/facebook' , { recursive : true , force : true } ) ;
// get the list of all available templates
console . log ( `
-- -- -- -
# # Generate example folders ...
` );
const excludes = [ 'README.md' , 'shared' ] ;
const templates = (
await fs . readdir ( './packages/create-docusaurus/templates' )
) . filter ( ( name ) => ! excludes . includes ( name ) ) ;
console . log ( ` Will generate examples for templates: ${ templates . join ( ',' ) } ` ) ;
for ( const template of templates ) {
await generateTemplateExample ( template ) ;
}
2022-01-13 01:36:53 -05:00
console . log ( 'Committing changes' ) ;
2022-01-07 23:59:28 -05:00
shell . exec ( 'git add examples' ) ;
shell . exec ( "git commit -am 'update examples' --allow-empty" ) ;
// update starters
console . log ( `
-- -- -- -
# Updating starter repos and branches ...
It can take some time ... please wait until done ...
` );
updateStarters ( ) ;
console . log ( `
-- -- -- -
Generate examples end !
Don ' t forget to push and merge your pull request !
` );