Pinion
Pinion is a flexible task runner and code generator for any language. Using TypeScript, it gives you full flexibility over what you can do with type-safe tasks and templates out of the box.
Let's see how you can get started with Pinion in 30 seconds.
Install Pinion
Add Pinion as a development dependency in your project like this:
npm install @featherscloud/pinion --save-dev
Note
While generators are written in TypeScript your project can use any programming language. For projects without a package.json
run npm init --yes
first.
Creating a generator
A Pinion generator has two ingredients:
- A TypeScript interface to define
Context
- A
generate
export that wraps the context in a promise and runs through the generator steps
The following file generates a basic readme.md
from a TypeScript template string:
import { PinionContext, toFile, renderTemplate } from '@featherscloud/pinion'
// A Context interface. (This one is empty)
interface Context extends PinionContext {}
// The file content as a template string
const readme = () =>
`# Hello world
This is a readme generated by Pinion
Copyright (c) ${new Date().getFullYear()}
`
// A `generate` export that wraps the context and renders the template
export const generate = (init: Context) =>
Promise.resolve(init).then(renderTemplate(readme, toFile('readme.md')))
npx pinion generators/readme.tpl.ts
Once you ran the command, you can find your readme.md
file in the current directory.
Asking questions
Pinion comes with a prompt
utility that works with your typed context. Let's get some input from the user!
You can ask questions from the command line with the prompt task:
import {
PinionContext, renderTemplate, toFile, prompt
} from '@featherscloud/pinion'
// Setup the Context to receive user input
interface Context extends PinionContext {
name: string
description: string
}
// The template uses Context variables.
const readme = ({ name, description }: Context) =>
`# ${name}
> ${description}
This is a readme generated by Pinion
Copyright (c) ${new Date().getFullYear()}
`
export const generate = (init: Context) => Promise.resolve(init)
// Ask prompts (using Inquirer)
.then(
prompt({
name: {
type: 'input',
message: 'What is the name of your app?'
},
description: {
type: 'input',
message: 'Write a short description'
}
})
)
// Render the template
.then(renderTemplate(readme, toFile('readme.md')))
npx pinion generators/readme.tpl.ts
Pinion uses Inquirer under the hood to ask questions. The prompt
task takes an array or object of Inquirer questions and returns a function that takes a context and returns a promise with the updated context. We can then use this context in the next step to render our template with the answers.
Note
If you already created the readme.md
the generator will ask if you want to overwrite the existing file.
What's next?
This is everything needed to get started with writing a generator. Next you can learn more about why we created Pinion and how it can be useful for you, go more in-depth with generators or look at the complete API.