Skip to content

Commit

Permalink
feat: big bang 💥
Browse files Browse the repository at this point in the history
  • Loading branch information
brunoluiz committed Oct 15, 2020
0 parents commit 8fb1e92
Show file tree
Hide file tree
Showing 16 changed files with 584 additions and 0 deletions.
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
root = true

[*]
end_of_line = lf
insert_final_newline = true

[*.{js,ts,md,json,html}]
charset = utf-8
indent_style = space
tab_width = 2
indent_size = 2
trim_trailing_whitespace = true

[{Makefile,go.mod,go.sum,*.go}]
indent_style = tab
indent_size = 2
29 changes: 29 additions & 0 deletions .github/workflows/goreleaser.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: goreleaser

on:
push:
tags:
- '*'

jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
-
name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.14
-
name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output
*.env
dist
113 changes: 113 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# options for analysis running
run:
deadline: 20s
tests: true
skip-dirs:
- generated
skip-files:
- ".*\\.pb\\.go"
silent: true

# output configuration options
output:
format: colored-line-number
print-issued-lines: true
print-linter-name: true

# all available settings of specific linters
linters-settings:
errcheck:
check-type-assertions: true
check-blank: true
govet:
check-shadowing: false
disable:
- shadow
gofmt:
simplify: true
goconst:
min-len: 3
min-occurrences: 3
misspell:
locale: UK
unused:
check-exported: true
unparam:
algo: cha
nakedret:
max-func-lines: 30
prealloc:
simple: true
range-loops: true
for-loops: true

linters:
enable:
- golint # Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes [fast: true]
- misspell # Finds commonly misspelled English words in comments [fast: true]
- nakedret # Finds naked returns in functions greater than a specified function length [fast: true]
- errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases [fast: false]
- gas # Inspects source code for security problems [fast: false]
- structcheck # Finds an unused struct fields [fast: false]
- interfacer # Linter that suggests narrower interface types [fast: false]
- unconvert # Remove unnecessary type conversions [fast: false]
- unparam # Reports unused function parameters [fast: false]
- prealloc # Finds slice declarations that could potentially be preallocated [fast: true]
- goimports # Goimports does everything that gofmt does. Additionally it checks unused imports [fast: true]
- lll # Reports long lines [fast: true]
- megacheck # 3 sub-linters in one: unused, gosimple and staticcheck [fast: false]

disable:
- staticcheck # (megacheck) Staticcheck is a go vet on steroids, applying a ton of static analysis checks [fast: false]
- unused # (megacheck) Checks Go code for unused constants, variables, functions and types [fast: false]
- gosimple # (megacheck) Linter for Go source code that specializes in simplifying a code [fast: false]
- gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification [fast: true]
- dupl # Tool for code clone detection [fast: true]
- typecheck # Like the front-end of a Go compiler, parses and type-checks Go code [fast: false]
- depguard # Go linter that checks if package imports are in a list of acceptable packages [fast: false]
- varcheck # Finds unused global variables and constants [fast: false]
- deadcode # Finds unused code [fast: false]
- goconst # Finds repeated strings that could be replaced by a constant [fast: true]
- gocyclo # Computes and checks the cyclomatic complexity of functions [fast: true]
- maligned # Tool to detect Go structs that would take less memory if their fields were sorted [fast: false]

issues:
exclude-use-default: false
exclude:
# errcheck: Almost all programs ignore errors on these functions and in most cases it's ok
- Error return value of
.((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv|.*Disconnect).
is not checked

# golint: Exported variables are rarely used and generally reserved for errors which should be self explanitory
- exported var \w+ should have comment or be unexported

# golint: False positive when tests are defined in package 'test'
- func name will be used as test\.Test.* by other packages, and that
stutters; consider calling this

# gas: Too many false-positives on 'unsafe' usage
- Use of unsafe calls should be audited

# gas: Too many false-positives for parametrized shell calls
- Subprocess launch(ed with variable|ing should be audited)

# gas: Duplicated errcheck checks
- G104

# gas: Too many issues in popular repos
- (Expect directory permissions to be 0750 or less|Expect file permissions
to be 0600 or less)

# gas: False positive is triggered by 'src, err := ioutil.ReadFile(filename)'
- Potential file inclusion via variable

# govet: Common false positives
- (possible misuse of unsafe.Pointer|should have signature)

# megacheck: Developers tend to write in C-style with an explicit 'break' in a 'switch', so it's ok to ignore
- ineffective break statement. Did you mean to break out of the outer loop

# disable comments
- exported [a-z]+ `?[^ ]+ should have comment

37 changes: 37 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
project_name: 'urlzap'

builds:
- main: './cmd/urlzap/main.go'
binary: 'urlzap'
goos: ['linux', 'darwin', 'windows']
goarch: ['amd64']

changelog:
sort: 'asc'
filters:
exclude: ['^docs:', '^test:', 'Merge pull request', 'Merge branch']

archives:
- format_overrides:
- goos: 'windows'
format: 'zip'

nfpms:
- formats: ['deb', 'rpm']
dependencies: ['git']

# dockers:
# - image_templates:
# - 'brunoluiz/urlzap:{{ .Tag }}'
# - 'brunoluiz/urlzap:v{{ .Major }}.{{ .Minor }}'
# - 'brunoluiz/urlzap:latest'
# dockerfile: 'Dockerfile.prod'
# binaries:
# - 'urlzap'

brews:
- github:
owner: 'brunoluiz'
name: 'homebrew-tap'
folder: 'Formula'

36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# urlzap

Your own URL manager, statically generated ⚡️

- Keep your (shortned or not) URLs with you
- No need to run a server (although supported)
- Can be used with Github Page

## Usage:

First set-up your URLs in `./config.yml`. Each key in the map will map to `/{key}` routes,
redirecting to `{value}`. In the example below, `https://yourwebsite/google` will
redirect to Google and `https://yourwebsite/tools/github` to Github.

```
urls:
google: https://google.com
tools:
github: https://github.com
path: './output' # default is './'
```

To generate the static files, call `urlzap generate`.

## Usage with Github Pages:

1. Enable Github Pages and set-up the branch where your static HTML files will be located.
More details at [Github Pages guide](https://pages.github.com/)
1. Update your `config.yml` with new URLs
1. Commit and push to `main`
1. Checkout to your Github Pages branch (usually `gh-pages`) and merge `main` into it
1. Run `urlzap generate`
1. Commit and push the results

If you don't have any cache configured (eg: Cloudflare), it shouldn't a minute to get
the updates.
81 changes: 81 additions & 0 deletions cmd/urlzap/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package main

import (
"errors"
"net/http"
"os"

"github.com/brunoluiz/urlzap"
_ "github.com/joho/godotenv/autoload"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)

func main() {
app := &cli.App{
Commands: []*cli.Command{
{
Name: "generate",
Aliases: []string{"exec", "e"},
Usage: "Generate static content for redirecting to URLs",
Action: run(generate),
Flags: []cli.Flag{
&cli.StringFlag{
Name: "config, c",
Value: "./config.yml",
Usage: "Site configs",
},
},
},
{
Name: "serve",
Aliases: []string{"s"},
Usage: "Serve config and return HTTP 301 for configured keys",
Action: run(serve),
Flags: []cli.Flag{
&cli.StringFlag{
Name: "config, c",
Value: "./config.yml",
Usage: "Site configs",
},
},
},
},
}

if err := app.Run(os.Args); err != nil {
logrus.Fatal(err)
}
}

func run(cb func(c *cli.Context, config urlzap.Config) error) cli.ActionFunc {
return func(c *cli.Context) error {
freader, err := os.Open(c.String("config"))
if err != nil {
return err
}

conf, err := urlzap.FromYAML(freader)
if err != nil {
return err
}

return cb(c, conf)
}
}

func generate(c *cli.Context, conf urlzap.Config) error {
if conf.Path == "" {
conf.Path = "./"
}

return urlzap.Generate(conf)
}

func serve(c *cli.Context, conf urlzap.Config) error {
if conf.HTTP.Address == "" || conf.HTTP.Path == "" {
return errors.New("Missing http.address or http.path configs")
}

return http.ListenAndServe(conf.HTTP.Address, urlzap.NewServer(conf))
}
8 changes: 8 additions & 0 deletions example/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
path: './output'
http:
address: ':80'
path: '/example'
urls:
google: https://google.com
tools:
github: https://github.com
28 changes: 28 additions & 0 deletions generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package urlzap

import (
"html/template"
)

const redirectHTMLTemplate = `
<!DOCTYPE html>
<html>
<head>
<title>{{.URL}}</title>
<link rel="canonical" href="{{.URL}}"/>
<meta name="robots" content="noindex">
<meta charset="utf-8" />
<meta http-equiv="refresh" content="0; url={{.URL}}" />
</head>
</html>
`

// Generate generate static files with HTML redirects
func Generate(c Config) error {
tmpl, err := template.New("redirect").Parse(redirectHTMLTemplate)
if err != nil {
return err
}

return Read("", c.URLs, HTMLFileCallback(c.Path, tmpl))
}
33 changes: 33 additions & 0 deletions generate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package urlzap_test

import (
"os"
"testing"

"github.com/brunoluiz/urlzap"
"github.com/stretchr/testify/require"
)

func TestGenerate(t *testing.T) {
err := urlzap.Generate(urlzap.Config{
Path: "./output",
URLs: urlzap.URLs{
"google": "https://google.com",
"tools": urlzap.URLs{
"github": "https://github.com",
},
},
})
require.NoError(t, err)

f1, err := os.Stat("./output/google/index.html")
require.NoError(t, err)
require.NotEqual(t, f1.Size(), 0)

f2, err := os.Stat("./output/tools/github/index.html")
require.NoError(t, err)
require.NotEqual(t, f2.Size(), 0)

err = os.RemoveAll("./output")
require.NoError(t, err)
}
Loading

0 comments on commit 8fb1e92

Please sign in to comment.