A flexible, language and framework agnostic tool that allows you to generate projects from templates. Projector has some builtin templates, but you also can use your custom templates.
Currently Projector is in active development stage, therefore breaking changes may occur.
- Single binary, no extra dependencies
- Builtin templates that allow you to start quickly
- Simple template manifest format
- Custom templates
- Optional steps for flexibility
There are two ways to get Projector right now:
- Get binary for your platform on Releases page
- Build Projector from source:
go install github.com/tomakado/projector
Get general usage help with -h
or --help
flags:
❯ projector -h
A flexible, language and framework agnostic tool that allows you to generate projects from templates.
Projector has some builtin templates, but you can use your custom templates or import third-party templates
from GitHub.
Usage:
projector [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
create Create project using specified template
help Help about any command
info Show meta information about template
init Create template manifest in current directory (like `create projector` command)
list List builtin and cached templates
validate Validate manifest without performing actions (dry run)
version Display projector version
Flags:
-h, --help help for projector
-v, --verbose turn verbose mode on
Use "projector [command] --help" for more information about a command.
Create project with create
command:
projector create go/hello-world --author "tomakado <[email protected]>" && \
--name "my-awesome-app" && \
--package "github.com/tomakado/go-helloworld" && \
./hello-world/
where go/hello-world
is template you want to use. You also can use custom manifest file by passing it with --manifest
or -m
flags.
Template may have optional steps omitted by default. Use -i
or --i
flags to include them:
projector create go/hello-world --author "tomakado <[email protected]>" && \
--name "my-awesome-app" && \
--package "github.com/tomakado/go-helloworld" && \
--include=makefile,dockerfile
./hello-world/
Use --all
flag to include all optional steps:
projector create go/hello-world --author "tomakado <[email protected]>" && \
--name "my-awesome-app" && \
--package "github.com/tomakado/go-helloworld" && \
--all
./hello-world/
List all available locally templates with projector list
:
❯ projector list
go/hello-world
go/http
Get a bit more info about concrete template with projector info [template]
:
❯ projector info go/hello-world
go/[email protected] by tomakado
URL: https://github.com/tomakado/projector
Description: Basic program to get started with Go
Validate custom manifest file with projector validate --manifest=[path-to-custom-manifest-file]
:
❯ projector validate -m projector.toml
Manifest is valid ✅
Debug your template with --verbose
flag:
❯ projector create go/hello-world -a "tomakado <[email protected]>" -n "my-awesome-app" -p "github.com/tomakado/go-helloworld" ./hello-world --verbose
2022/02/19 18:22:32 verbose mode is turned on
2022/02/19 18:22:32 using manifest name "go/hello-world" in embed fs
2022/02/19 18:22:32 initialized embedded fs provider
2022/02/19 18:22:32 working directory = "./hello-world"
2022/02/19 18:22:32 loading manifest "go/hello-world/projector.toml"
2022/02/19 18:22:32 [EmbedFSProvider] reading "go/hello-world/projector.toml" in "resources/templates/"
2022/02/19 18:22:32 parsing manifest
2022/02/19 18:22:32 validating manifest
2022/02/19 18:22:32 passing config and provider to new instance of *projector.Generator
2022/02/19 18:22:32 provider = *manifest.EmbedFSProvider, config = {WorkingDirectory:./hello-world ProjectAuthor:tomakado <[email protected]> ProjectName:my-awesome-app ProjectPackage:github.com/tomakado/go-helloworld Manifest:0xc0002a5960 ManifestPath:go/hello-world}
2022/02/19 18:22:32 initializing working directory "./hello-world"
2022/02/19 18:22:32 cd ./hello-world
2022/02/19 18:22:32 traversing manifest steps
2022/02/19 18:22:32 step "init go module and git repository", 1 of 2
2022/02/19 18:22:32 processing files
2022/02/19 18:22:32 extracting file template from "gitignore"
2022/02/19 18:22:32 [EmbedFSProvider] reading "go/hello-world/gitignore" in "resources/templates/"
2022/02/19 18:22:32 parsing file template
2022/02/19 18:22:32 rendering file
2022/02/19 18:22:32 saving rendered file to ".gitignore"
2022/02/19 18:22:32 parsing output path template ".gitignore"
2022/02/19 18:22:32 rendering output path template ".gitignore"
2022/02/19 18:22:32 mkdir .
2022/02/19 18:22:32 writing rendered file to ".gitignore"
2022/02/19 18:22:32 parsing shell script template "go mod init {{ .ProjectPackage }} && git init"
2022/02/19 18:22:32 rendering shell script
2022/02/19 18:22:32 executing shell script "go mod init github.com/tomakado/go-helloworld && git init"
2022/02/19 18:22:32 step "create project bootstrap", 2 of 2
2022/02/19 18:22:32 processing files
2022/02/19 18:22:32 extracting file template from "main.go.tpl"
2022/02/19 18:22:32 [EmbedFSProvider] reading "go/hello-world/main.go.tpl" in "resources/templates/"
2022/02/19 18:22:32 parsing file template
2022/02/19 18:22:32 rendering file
2022/02/19 18:22:32 saving rendered file to "main.go"
2022/02/19 18:22:32 parsing output path template "main.go"
2022/02/19 18:22:32 rendering output path template "main.go"
2022/02/19 18:22:32 mkdir .
2022/02/19 18:22:32 writing rendered file to "main.go"
You can just create file with name projector.toml
and start filling, but Projector has template for... templates:
projector create projector --name="projector-demo" ./projector-demo
that generates file with following content:
name="projector-demo"
author="tomakado"
version="snapshot"
url="https://github.com/tomakado/projector-demo"
description="Enter your template description here"
[[steps]]
name="hello world"
shell="echo \"hello, world!\""
Also there is shortcut for it (you have to be inside target directory):
projector init
Manifest is a file that describes how Projector should act to generate project. Projector uses TOML format to store manifest on disk.
Example:
name="go/hello-world"
author="tomakado"
version="1.0.0"
url="https://github.com/tomakado/projector"
description="Basic program to get started with Go"
[[steps]]
name="init go module and git repository"
shell="go mod init {{ .ProjectPackage }} && git init"
[[steps.files]]
path="gitignore"
output=".gitignore"
[[steps]]
name="create project bootstrap"
[[steps.files]]
path="main.go.tpl"
output="main.go"
The first, top-level section containing fields name
, author
, version
, url
, description
is about meta information. Then manifest must contain at least one step. Step must have name and either list of files to generate or shell script to execute.
Field | Description |
---|---|
name |
Name of template. Required. |
author |
Author of template. Required. |
version |
Version of template. Required. |
url |
URL of repository or website of template. Optional. |
steps |
Array of steps. See step for more info. Required at least one step. |
Step is self-sufficient action performed by Projector to generate project. Projector “executes” steps sequentially, one by one. Inside shell
field text/template
syntax is supported, so you can use values exposed to Template Context inside shell script.
Field | Description |
---|---|
name |
Name of step. Required. |
optional |
Defines if step is optional. If true step will be omitted if not included via -i flag. Optional. Default: false . |
files |
Array of files to generate. See file for more info. Required if shell is not set. |
shell |
Shell script to execute. text/template supported (see Template Context for more info). Required if files is not set. |
File in terms of Projector manifest is something like task of following kind:
- Take file located at
path
; - Render file content as template with Template Context;
- Render output path using
output
value; - Put rendered file to rendered
output
path.
Field | Description |
---|---|
path |
Path to source file. text/template supported in content (see Template Context for more info). Required. |
output |
Template of output path for rendered file. See Template Context for more info. Required. |
Field | Description |
---|---|
WorkingDirectory |
Current working directory. Usually folder where project is being generated. |
ProjectAuthor |
Author of project. |
ProjectName |
Name of project. |
ProjectPackage |
Package name for project. E.g. in Go it would something like github.com/owner/module . |
Manifest |
Reference to manifest. See Manifest for info. |
OptionalSteps |
Slice of optional step names. |
There are some features I'd like to implement in Projector:
- Use multiple templates to generate single project (e.g., for having separate templates for Dockerfile, frontend, “service” level, etc.)
- Nice animated output of current step
- User-friendly error messages
- Import third-party templates from GitHub
- Custom options in template context
- Import third-party templates from any public or private git repository
- Template caching
- List local third-party cached templates
- Support for file masks on input files declaration
If you want to help to develop Projector, the're several options:
- Create issue with problem you've met or any other kind
- Submit PRs with bug fixes or new features, especially from backlog 😉