The hof tool tries to remove redundent development activities
by using high level designs, code generation, and diff3
while letting you write custom code directly in the output.
( low-code for developers )
- Users write Single Source of Truth (SSoT) design for data models and the application generators
hofreads the SSoT, processes it through the code generators, and outputs directories and files- Users can write custom code in the output, change their designs, and regenerate code in any order
hofcan be customized and extended by only editing text files and nothofsource code.- Use your own tools, technologies, and practices,
hofdoes not make any choices for you hofis powered by Cue (https://cuelang.org & https://cuetorials.com)
You will have to download hof the first time.
After that hof will prompt you to update and
install new releases as they become available.
# Install (Linux, Mac, Windows)
curl -LO https://github.com/hofstadter-io/hof/releases/download/v0.5.15/hof_0.5.15_$(uname)_$(uname -m)
mv hof_0.5.15_$(uname)_$(uname -m) /usr/local/bin/hof
# Shell Completions (bash, zsh, fish, power-shell)
echo ". <(hof completion bash)" >> $HOME/.profile
source $HOME/.profile
# Show the help text
hof --help
You can always find the latest version from the
releases page
or use hof to install a specific version of itself with hof update --version vX.Y.Z.
Please see https://docs.hofstadter.io to learn more.
Join us on Slack! https://hofstadter-io.slack.com (invite link)
There are currently hof modules for:
- hofmod-cli - CLI infrastructure based on the Golang Cobra library.
- hofmod-server - API server based on the Golang Echo library.
You can see them used in:
hofuseshofmod-cli- saas uses
hofmod-server
The following is a single file example:
package gen
import (
// import hof's schemas for our generator
"github.com/hofstadter-io/hof/schema"
)
// A schema for our generator's input
#Input: {
name: string
todos: [...{
name: string
effort: int
complete: bool
}]
}
// create a generator
#Gen: schema.#HofGenerator & {
// We often have some input values for the user to provide.
// Use a Cue definition to enforce a schema
Input: #Input
// Required filed for generator definitions, details can be found in the hof docs
PackageName: "dummy"
// Required field for a generator to work, the list of files to generate
Out: [...schema.#HofGeneratorFile] & [
todo,
done,
debug,
]
// In is supplied as the root data object to every template
// pass user inputs to the tempaltes here, possibly modified, enhanced, or transformed
In: {
INPUT: Input
Completed: _C
Incomplete: _I
}
// calculate some internal data from the input
_C: [ for t in Input.todos if t.complete == true { t } ]
_I: [ for t in Input.todos if t.complete == false { t } ]
// the template files
todo: {
Template: """
Hello {{ .INPUT.name }}.
The items still on your todo list:
{{ range $T := .Incomplete -}}
{{ printf "%-4s%v" $T.name $T.effort }}
{{ end }}
"""
// The output filename, using string interpolation
Filepath: "\(Input.name)-todo.txt"
}
done: {
Template: """
Here's what you have finished {{ .INPUT.name }}. Good job!
{{ range $T := .Completed -}}
{{ $T.name }}
{{ end }}
"""
Filepath: "\(Input.name)-done.txt"
}
// useful helper
debug: {
Template: """
{{ yaml . }}
"""
Filepath: "debug.yaml"
}
}
// Add the @gen(<name>,<name>,...) to denote usage of a generator
Gen: _ @gen(todos)
// Construct the generator
Gen: #Gen & {
Input: {
// from first.cue
name: gen.data.name
todos: gen.data.tasks
}
}