Skip to content

Commit

Permalink
feat: Add the code
Browse files Browse the repository at this point in the history
  • Loading branch information
dadav committed Mar 1, 2024
1 parent 3480067 commit c0695f3
Show file tree
Hide file tree
Showing 24 changed files with 1,267 additions and 140 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
name: build

on:
push:
branches:
- '*'
tags-ignore:
- '*'
pull_request:
types:
- opened
- reopened

jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: ^1.22
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v4
with:
distribution: goreleaser
version: latest
args: release --snapshot --clean
31 changes: 31 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: release

on:
push:
tags:
- '*'

permissions:
contents: write

jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: ^1.22
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v4
with:
distribution: goreleaser
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

dist/
41 changes: 41 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj

version: 1

before:
hooks:
- go mod tidy

builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin

archives:
- format: tar.gz
# this name template makes the OS and Arch compatible with the results of `uname`.
name_template: >-
{{ .ProjectName }}_
{{- .Version }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
# use zip for windows archives
format_overrides:
- goos: windows
format: zip

changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
- '^chore:'
91 changes: 91 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# ⭐ Gorge

Gorge is a go implementation for [forgeapi.puppet.com](https://forgeapi.puppet.com/).

## 🌹 Installation

Via `go install`:

```bash
go install github.com/dadav/gorge@latest
```

## 💎 Usage

```bash
Run this command to start serving your own puppet modules.
You can also enable a fallback proxy to forward the requests to
when you don't have the requested module in your local module
set yet.
You can also enable the caching functionality to speed things up.
Usage:
gorge serve [flags]
Flags:
--api-version string the forge api version to use (default "v3")
--backend string backend to use (default "filesystem")
--bind string host to listen to
--cache-prefixes string url prefixes to cache (default "/v3/files")
--cachedir string cache directory (default "/var/cache/gorge")
--cors string allowed cors origins separated by comma (default "*")
--dev enables dev mode
--fallback-proxy string optional fallback upstream proxy url
-h, --help help for serve
--modulesdir string directory containing all the modules (default "/opt/gorge/modules")
--no-cache disables the caching functionality
--port int the port to listen to (default 8080)
Global Flags:
--config string config file (default is $HOME/.gorge.yaml)
```
## 🐂 Examples
```bash
# use the pupeptlabs forge as fallback
gorge serve --fallback-proxy https://forge.puppetlabs.com
# enable cache for every request
gorge serve --fallback-proxy https://forge.puppetlabs.com --cache-prefixes /v3
```
## 🍰 Configuration
Use the `$HOME/.config/gorge.yaml` (or `./gorge.yaml`):
```yaml
---
api-version: v3
backend: filesystem
bind: 127.0.0.1
cache-prefixes: /v3/files
cachedir: /var/cache/gorge
cors: "*"
dev: false
fallback-proxy:
modulesdir: /opt/gorge/modules
no-cache: false
port: 8080
```
Or the environment:
```bash
GORGE_API_VERSION: v3
GORGE_BACKEND: filesystem
GORGE_BIND: 127.0.0.1
GORGE_CACHE_PREFIXES: /v3/files
GORGE_CACHEDIR: /var/cache/gorge
GORGE_CORS: "*"
GORGE_DEV: false
GORGE_FALLBACK_PROXY:
GORGE_MODULESDIR: /opt/gorge/modules
GORGE_NO_CACHE: false
GORGE_PORT: 8080
```
## 🔑 License
[Apache](./LICENSE)
3 changes: 3 additions & 0 deletions cmd/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package cmd

var apiVersion string
76 changes: 46 additions & 30 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
Copyright © 2024 NAME HERE <EMAIL ADDRESS>
Copyright © 2024 dadav
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
Expand All @@ -17,28 +17,30 @@ package cmd

import (
"fmt"
"github.com/spf13/cobra"
"os"
"path/filepath"
"strings"

"github.com/spf13/cobra"
"github.com/spf13/pflag"

homedir "github.com/mitchellh/go-homedir"
"github.com/spf13/viper"
)

var cfgFile string

const envPrefix = "GORGE"

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "gorge",
Short: "A brief description of your application",
Long: `A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
// Uncomment the following line if your bare application
// has an action associated with it:
// Run: func(cmd *cobra.Command, args []string) { },
Short: "Gorge runs a puppet forge server",
Long: `You can run this tool to provide access to your puppet modules.`,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
// You can bind cobra and viper in a few locations, but PersistencePreRunE on the root command works well
return initConfig(cmd)
},
}

// Execute adds all child commands to the root command and sets flags appropriately.
Expand All @@ -51,24 +53,16 @@ func Execute() {
}

func init() {
cobra.OnInitialize(initConfig)

// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.

rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.gorge.yaml)")

// Cobra also supports local flags, which will only run
// when this action is called directly.
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
func initConfig(cmd *cobra.Command) error {
v := viper.New()

if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
v.SetConfigFile(cfgFile)
} else {
// Find home directory.
home, err := homedir.Dir()
Expand All @@ -77,15 +71,37 @@ func initConfig() {
os.Exit(1)
}

homeConfig := filepath.Join(home, ".config")

// Search config in home directory with name ".gorge" (without extension).
viper.AddConfigPath(home)
viper.SetConfigName(".gorge")
v.AddConfigPath(homeConfig)
v.AddConfigPath(".")
v.SetConfigName("gorge")
v.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
v.SetEnvPrefix(envPrefix)
}

viper.AutomaticEnv() // read in environment variables that match
v.AutomaticEnv() // read in environment variables that match

// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
fmt.Println("Using config file:", viper.ConfigFileUsed())
if err := v.ReadInConfig(); err == nil {
fmt.Println("Using config file:", v.ConfigFileUsed())
}

bindFlags(cmd, v)

return nil
}

func bindFlags(cmd *cobra.Command, v *viper.Viper) {
cmd.Flags().VisitAll(func(f *pflag.Flag) {
// Determine the naming convention of the flags when represented in the config file
configName := f.Name

// Apply the viper config value to the flag when the flag is not set and viper has a value
if !f.Changed && v.IsSet(configName) {
val := v.Get(configName)
cmd.Flags().Set(f.Name, fmt.Sprintf("%v", val))
}
})
}
Loading

0 comments on commit c0695f3

Please sign in to comment.