Skip to content

Commit

Permalink
Merge pull request #21 from gchiesa/ignorePaths
Browse files Browse the repository at this point in the history
feat: ignorepaths, and more
  • Loading branch information
gchiesa authored Aug 2, 2024
2 parents e719a0b + 84126a7 commit 9392f4b
Show file tree
Hide file tree
Showing 18 changed files with 342 additions and 210 deletions.
185 changes: 90 additions & 95 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,110 +1,105 @@
# ska

<div align="center">
A general purpose project template for golang CLI applications
<br>
<br>
This template serves as a starting point for golang commandline applications it is based on golang projects that I consider high quality and various other useful blog posts that helped me understanding golang better.
<br>
<br>
<img src="https://github.com/gchiesa/ska/actions/workflows/test.yml/badge.svg" alt="drawing"/>
<img src="https://github.com/gchiesa/ska/actions/workflows/lint.yml/badge.svg" alt="drawing"/>
<img src="https://pkg.go.dev/badge/github.com/gchiesa/ska.svg" alt="drawing"/>
<img src="https://codecov.io/gh/gchiesa/ska/branch/main/graph/badge.svg" alt="drawing"/>
<img src="https://img.shields.io/github/v/release/gchiesa/ska" alt="drawing"/>
<img src="https://img.shields.io/docker/pulls/gchiesa/ska" alt="drawing"/>
<img src="https://img.shields.io/github/downloads/gchiesa/ska/total.svg" alt="drawing"/>
</div>

# Table of Contents
<!--ts-->
* [ska](#ska)
* [Features](#features)
* [Project Layout](#project-layout)
* [How to use this template](#how-to-use-this-template)
* [Demo Application](#demo-application)
* [Makefile Targets](#makefile-targets)
* [Contribute](#contribute)

<!-- Added by: morelly_t1, at: Tue 10 Aug 2021 08:54:24 AM CEST -->

<!--te-->

# Features
- [goreleaser](https://goreleaser.com/) with `deb.` and `.rpm` packer and container (`docker.hub` and `ghcr.io`) releasing including `manpages` and `shell completions` and grouped Changelog generation.
- [golangci-lint](https://golangci-lint.run/) for linting and formatting
- [Github Actions](.github/worflows) Stages (Lint, Test (`windows`, `linux`, `mac-os`), Build, Release)
- [Gitlab CI](.gitlab-ci.yml) Configuration (Lint, Test, Build, Release)
- [cobra](https://cobra.dev/) example setup including tests
- [Makefile](Makefile) - with various useful targets and documentation (see Makefile Targets)
- [Github Pages](_config.yml) using [jekyll-theme-minimal](https://github.com/pages-themes/minimal) (checkout [https://gchiesa.github.io/ska/](https://gchiesa.github.io/ska/))
- Useful `README.md` badges
- [pre-commit-hooks](https://pre-commit.com/) for formatting and validating code before committing

# Project Layout
* [assets/](https://pkg.go.dev/github.com/gchiesa/ska/assets) => docs, images, etc
* [cmd/](https://pkg.go.dev/github.com/gchiesa/ska/cmd) => commandline configurartions (flags, subcommands)
* [pkg/](https://pkg.go.dev/github.com/gchiesa/ska/pkg) => packages that are okay to import for other projects
* [internal/](https://pkg.go.dev/github.com/gchiesa/ska/pkg) => packages that are only for project internal purposes
- [`tools/`](tools/) => for automatically shipping all required dependencies when running `go get` (or `make bootstrap`) such as `golang-ci-lint` (see: https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module)
)
- [`scripts/`](scripts/) => build scripts

# How to use this template
```sh
bash <(curl -s https://raw.githubusercontent.com/gchiesa/ska/master/install.sh)
```
# SKA

> [!IMPORTANT]
> This project is still under development and not intended for production use
In order to make the CI work you will need to have the following Secrets in your repository defined:

Repository -> Settings -> Secrets & variables -> `CODECOV_TOKEN`, `DOCKERHUB_TOKEN` & `DOCKERHUB_USERNAME`
SKA is a "skaffolding" tool that allows you to expand folders based on local or remote blueprint folder structure.

# Demo Application
Additionally, you can update your folder structure from the upstream blueprint to always onboard new changes that are
added centrally to the upstream.

```sh
$> golang-cli-processor -h
golang-cli project processor demo application
The interface is design for immediate use and simplicity. SKA offers also a simple package to integrate its
functionality in other tools and frameworks.

Usage:
golang-cli-processor [flags]
golang-cli-processor [command]

Available Commands:
completion Generate the autocompletion script for the specified shell
example example subcommand which adds or multiplies two given integers
help Help about any command
version golang-cli-processor version
## How To Use

Flags:
-h, --help help for golang-cli-processor
SKA is very simple to use. Just run it with the upstream blueprint you want to expand, with the following command

Use "ska [command] --help" for more information about a command.
```shell
ska create -b https://github.com/gchiesa/ska-example-template -o ~/my-project
```

```sh
$> golang-cli-processor example 2 5 --add
7
This will load the remote template, collect the required variable via Terminal UI and create the project for you. In
the root of the project you can find the SKA configuration file that will keep track from now on of state and
upstream reference.

$> golang-cli-processor example 2 5 --multiply
10
When you want to update your project, just use:

```shell
cd ~/my-project
ska update -p ~/my-project
```

# Makefile Targets
```sh
$> make
bootstrap install build deps
build build golang binary
clean clean up environment
cover display test coverage
docker-build dockerize golang application
fmt format go files
help list makefile targets
install install golang binary
lint lint go files
pre-commit run pre-commit hooks
run run the app
test display test coverage
you can modify the variables or accept the current version. Your project will be updated based on latest changes in
the upstream blueprint.

More information are available with `ska --help`.

## Concepts and Templating

### Upstream Blueprint

This is the typically centrally maintained template that everyone can use to expand its own folder structure. You
can specify the blueprint both locally and remotely with specific URIs:

* **file://** for local blueprints. E.g. `file:///Users/gchiesa/git/ska-example-template`
* **https://** for GitHub or GitLab blueprints. You can optionally pin a specific reference (tag or branch with the `@`
symbol. E.g. `https://github.com/gchiesa/[email protected]`

### Update from upstream

Whenever the upstream template changes, you might want to onboard the changes yourself. This is natively supported
by SKA, by offering a simple `update` command with not additional arguments required.

See How To Use section for more information.


### Upstream Template Language

SKA currently fully supports **[Go Template framework][go-template]** for templating your upstream blueprint.

Moreover, in addition to Go Template you can use the extensions offered by [Sprig functions][sprig]

If you are not familiar with Go Template have a look to this [simple how-to][go-template-how-to].

[go-template]: https://pkg.go.dev/text/template

[sprig]: https://masterminds.github.io/sprig/

[go-template-how-to]: https://www.digitalocean.com/community/tutorials/how-to-use-templates-in-go#step-4-writing-a-template

### Templating with partial sections

SKA offers the capability to manage only part of files. This is generally useful to keep only a specific part of the
file centrally managed by the upstream blueprint and let the user change the rest of the file.

This is achievable with the named partials, a type of block you can use in the SKA template.

For example, if we want to have only a section of a larger file managed by SKA we can use the approach below:

```yaml
# this is an example YAML and we want SKA to only manage the section `key4`
---
root:
key1: value1
key2: {{.notManaged}}
key3: value3
# ska-start:key/4
key4:
subkey: "{{.appName}}"
subkey2: value2
# ska-end
key5: value5
```
# Contribute
If you find issues in that setup or have some nice features / improvements, I would welcome an issue or a PR :)
by using the `ska-start:<blockName>` and `ska-end` tags, you instruct SKA to only process the block and leave the
rest of the file as it is.

This is quite useful for files where only a part should be centrally managed and the rest will be customized by the
user, after the initial creation.

## Credits

SKA is made with 💙 by Giuseppe Chiesa as exercise to learn a bit better GoLang.
9 changes: 7 additions & 2 deletions cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@ import (
)

type CreateCmd struct {
TemplateURI string `arg:"-t,--template,required" help:"URI of the template"`
DestinationPath string `arg:"-d,--destination,required" help:"Destination path"`
TemplateURI string `arg:"-b,--blueprint,required" help:"URI of the template blueprint to use"`
DestinationPath string `arg:"-o,--output,required" help:"Destination path where to expand the blueprint"`
Variables map[string]string `arg:"-v,separate" help:"Variables to use in the template. Can be specified multiple times"`
NonInteractive bool `arg:"-n,--non-interactive" help:"Run in non-interactive mode"`
}

func (c *CreateCmd) Execute() error {
options := &skaffolder.SkaOptions{
NonInteractive: c.NonInteractive,
}
ska := skaffolder.NewSkaCreate(
c.TemplateURI,
c.DestinationPath,
c.Variables,
*options,
)
return ska.Create()
}
37 changes: 30 additions & 7 deletions cmd/entrypoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,42 @@ import (
"github.com/alexflint/go-arg"
"github.com/apex/log"
"github.com/apex/log/handlers/cli"
"github.com/apex/log/handlers/json"
"os"
)

const programName = "ska"
const githubRepo = "https://gchiesa/ska"

var version = "development"
var commandVersion = "development"

type arguments struct {
CreateCmd *CreateCmd `arg:"subcommand:create"`
UpdateCmd *UpdateCmd `arg:"subcommand:update"`
Debug bool `arg:"-d"`
CreateCmd *CreateCmd `arg:"subcommand:create"`
UpdateCmd *UpdateCmd `arg:"subcommand:update"`
Debug bool `arg:"-d"`
JSONOutput bool `arg:"-j,--json" help:"Enable JSON output for logging"`
}

func (arguments) Version() string { return fmt.Sprintf("%s version %s", programName, version) }
func (arguments) Version() string {
return fmt.Sprintf("version: %s\n", commandVersion)
}

func (arguments) Description() string {
return fmt.Sprintf(`
%s is a tool for scaffolding your directories based on blueprint templates available locally or removely on GitHub and GitLab.
`, programName)
}

func (arguments) Epilogue() string {
return fmt.Sprintf(`
For more information check the repository on %s.
func Execute() error {
Made with love by https://github.com/gchiesa.
`, githubRepo)
}

func Execute(version string) error {
commandVersion = version
log.SetHandler(cli.New(os.Stderr))
log.SetLevel(log.InfoLevel)

Expand All @@ -30,6 +50,9 @@ func Execute() error {
if args.Debug {
log.SetLevel(log.DebugLevel)
}
if args.JSONOutput {
log.SetHandler(json.New(os.Stderr))
}

switch {
case args.CreateCmd != nil:
Expand All @@ -41,7 +64,7 @@ func Execute() error {
log.Fatalf("error executing update command: %v", err)
}
default:
fmt.Println("no subcommand specified")
fmt.Println("no subcommand specified, please use the --help flag to check available commands")
}

return nil
Expand Down
9 changes: 7 additions & 2 deletions cmd/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@ import (
)

type UpdateCmd struct {
FolderPath string `arg:"required" help:"Folder path where the .ska-config.yml file is located"`
Variables map[string]string `arg:"-v,separate" help:"Variables to use in the template. Can be specified multiple times"`
FolderPath string `arg:"-p,--path,required" help:"Local path where the .ska-config.yml file is located"`
Variables map[string]string `arg:"-v,separate" help:"Variables to use in the template. Can be specified multiple times"`
NonInteractive bool `arg:"-n,--non-interactive" help:"Run in non-interactive mode"`
}

func (c *UpdateCmd) Execute() error {
options := &skaffolder.SkaOptions{
NonInteractive: c.NonInteractive,
}
ska := skaffolder.NewSkaUpdate(
c.FolderPath,
c.Variables,
*options,
)
return ska.Update()
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/gotesttools/gotestfmt/v2 v2.5.0
github.com/huandu/xstrings v1.5.0
github.com/otiai10/copy v1.14.0
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
github.com/stretchr/testify v1.9.0
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,8 @@ github.com/ryancurrah/gomodguard v1.3.2 h1:CuG27ulzEB1Gu5Dk5gP8PFxSOZ3ptSdP5iI/3
github.com/ryancurrah/gomodguard v1.3.2/go.mod h1:LqdemiFomEjcxOqirbQCb3JFvSxH2JUYMerTFd3sF2o=
github.com/ryanrolds/sqlclosecheck v0.5.1 h1:dibWW826u0P8jNLsLN+En7+RqWWTYrjCB9fJfSfdyCU=
github.com/ryanrolds/sqlclosecheck v0.5.1/go.mod h1:2g3dUjoS6AL4huFdv6wn55WpLIDjY7ZgUR4J8HOO/XQ=
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI=
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs=
github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc=
github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
Expand Down
4 changes: 2 additions & 2 deletions internal/configuration/configfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ func (cf *ConfigFile) GetFilePath() string {
}

func (cf *ConfigFile) WriteConfig(configData []byte) error {
cf.log.WithFields(log.Fields{"filePath": cf.filePath}).Info("Writing configuration to file")
cf.log.WithFields(log.Fields{"filePath": cf.filePath}).Debug("Writing configuration to file")
if err := os.WriteFile(cf.filePath, configData, 0o644); err != nil {
return err
}
return nil
}

func (cf *ConfigFile) ReadConfig() ([]byte, error) {
cf.log.WithFields(log.Fields{"filePath": cf.filePath}).Info("Reading configuration from file")
cf.log.WithFields(log.Fields{"filePath": cf.filePath}).Debug("Reading configuration from file")
return os.ReadFile(cf.filePath)
}
Loading

0 comments on commit 9392f4b

Please sign in to comment.