Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add saber eject-theme command #259

Merged
merged 14 commits into from
Aug 19, 2019
101 changes: 101 additions & 0 deletions packages/saber/lib/cli.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
#!/usr/bin/env node
const path = require('path')
const { exec } = require('child_process')
const { fs } = require('saber-utils')
const { log } = require('saber-log')
const cac = require('cac')
const configLoader = require('./utils/configLoader')
const resolvePackage = require('./utils/resolvePackage')

const cli = cac()

Expand Down Expand Up @@ -54,6 +60,101 @@ cli
.catch(handleError)
})

cli
.command(
'eject [app]',
`Copy the currently used theme's source code to a local folder.`
)
.option(
'--git',
'Pull code from Git, instead of node_modules, and add the theme as a submodule',
{ default: false }
)
.option('--path <path>', 'Ejected theme destination', { default: './theme' })
.action(async (cwd = '.', options) => {
cwd = path.join(process.cwd(), cwd)
const { git } = options

const config =
configLoader.load({ cwd, files: configLoader.CONFIG_FILES }).data || {}
if (!config.theme) {
log.error('No theme specified in config.')
process.exit(1)
}

const destPath = path.join(cwd, options.path)
const relativeDest = path.relative(cwd, destPath)
if (await fs.pathExists(destPath)) {
log.error(
`The path ${
options.path
} already exists. Please specify a different one using "--path".`
)
process.exit(1)
}

const themePath = resolvePackage(config.theme, {
prefix: 'saber-theme-',
cwd
})
if (!themePath) {
log.error(
`Theme "${config.theme}" could not be found in your node_modules.`
)
process.exit(1)
}

if (git) {
const themePackage = configLoader.load({
cwd: themePath,
files: ['package.json']
}).data

if (themePackage.repository && themePackage.repository.url) {
const repo = themePackage.repository.url
await new Promise(resolve =>
exec(
`git submodule add "${repo}" "${relativeDest}"`,
krmax44 marked this conversation as resolved.
Show resolved Hide resolved
{ cwd },
(error, stdout, stderr) => {
if (error) {
log.error(`Could not add submodule: ${stderr.toString()}`)
process.exit(1)
}

if (options.verbose) {
log.verbose(stdout)
if (stderr) log.verbose(stderr)
}

log.info('Added theme as submodule.')
resolve()
}
)
)
} else {
log.error(
'The theme has no git repository specified within its package.json.'
)
process.exit(1)
}
} else {
try {
await fs.copy(themePath, destPath, {
filter: src => !src.endsWith('/node_modules')
})

log.info('Copied theme from node_modules.')
} catch (error) {
log.error(`Could not copy files: ${error.toString()}`)
}
}

log.info(
`Plese change "theme" in your Saber config to "./${relativeDest}".`
)
krmax44 marked this conversation as resolved.
Show resolved Hide resolved
})

cli
.command('serve [app]', 'Serve the output directory')
.option('--host <host>', 'Server host', { default: '0.0.0.0' })
Expand Down
10 changes: 10 additions & 0 deletions website/pages/docs/themes.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,13 @@ There are already a number of themes available for you to play with. If you deci
- [Ume](https://github.com/iCyris/Ume) - An elegant blog theme by [iCyris](https://github.com/iCyris).

We are also working on adding a page on this site to showcase all the themes.

## Ejecting

If you are using a theme from npm and wish to modify it to better suit your needs, you might want to eject it. This will copy over its source code to `./theme`, allowing you to edit it.

```bash
saber eject
```

The above command will use the files from `node_modules`, but if you want the source code from the repository instead, add the `--git` flag. This will clone the theme's Git repository as a submodule, which adds the benefits of easier upgradability, contribution to the upstream code and better version control management.