Skip to content

Commit

Permalink
get started (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredLunde authored May 14, 2024
1 parent 64e37ff commit fd93f81
Show file tree
Hide file tree
Showing 34 changed files with 3,426 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Pull request
on:
pull_request:
branches:
- main
jobs:
vet:
name: Vet
runs-on: ubuntu-latest
concurrency:
group: ${{ github.head_ref }}-vet
cancel-in-progress: true
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup asdf
uses: asdf-vm/actions/install@v3
- name: Install dependencies
run: go mod download
- name: Add asdf shims to PATH
run: |
echo "${HOME}/.asdf/shims" >> $GITHUB_PATH
- name: Lint
run: go vet ./...
- name: Run integration tests
run: go test -v ./...
27 changes: 27 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Release

on:
push:

permissions:
contents: write

jobs:
release:
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v4
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5
with:
distribution: goreleaser
version: "~> v1"
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
dist/
/Dockerfile
36 changes: 36 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
version: 1

before:
hooks:
- go mod tidy

builds:
- main: ./cmd/new-dockerfile
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 }}-
{{- .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:"
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
golang 1.22.3
95 changes: 95 additions & 0 deletions cmd/new-dockerfile/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package main

import (
"fmt"
"log/slog"
"os"
"path/filepath"
"strings"
"time"

dockerfile "github.com/flexstack/new-dockerfile"
"github.com/flexstack/new-dockerfile/runtime"
"github.com/lmittmann/tint"
flag "github.com/spf13/pflag"
)

func main() {
var path string
flag.StringVar(&path, "path", ".", "Path to the project directory")
var noColor bool
flag.BoolVar(&noColor, "no-color", false, "Disable colorized output")
var runtimeArg string
flag.StringVar(&runtimeArg, "runtime", "", "Force a specific runtime")
var quiet bool
flag.BoolVar(&quiet, "quiet", false, "Disable all log output except errors")
var write bool
flag.BoolVar(&write, "write", false, "Write the Dockerfile to disk at ./Dockerfile")
flag.Parse()

level := slog.LevelInfo
if os.Getenv("DEBUG") != "" {
level = slog.LevelDebug
} else if quiet {
level = slog.LevelError
}

handler := tint.NewHandler(os.Stderr, &tint.Options{
Level: level,
TimeFormat: time.Kitchen,
NoColor: noColor,
})

log := slog.New(handler)
df := dockerfile.New(log)

var (
r runtime.Runtime
err error
)

if runtimeArg != "" {
runtimes := df.ListRuntimes()

for _, rt := range runtimes {
if strings.ToLower(string(rt.Name())) == strings.ToLower(runtimeArg) {
r = rt
break
}
}
if r == nil {
runtimeNames := make([]string, len(runtimes))
for i, rt := range runtimes {
runtimeNames[i] = string(rt.Name())
}
log.Error(fmt.Sprintf(`Runtime "%s" not found. Expected one of: %s`, runtimeArg, "\n - "+strings.Join(runtimeNames, "\n - ")))
os.Exit(1)
}
}

if r == nil {
r, err = df.MatchRuntime(path)
if err != nil {
log.Error("Fatal error: " + err.Error())
os.Exit(1)
}
}

contents, err := r.GenerateDockerfile(path)
if err != nil {
os.Exit(1)
}

if !write {
fmt.Println(string(contents))
return
}

output := filepath.Join(path, "Dockerfile")
if err = os.WriteFile(output, contents, 0644); err != nil {
log.Error("Fatal error: " + err.Error())
os.Exit(1)
}

log.Info(fmt.Sprintf("Auto-generated Dockerfile for project using %s: %s", string(r.Name()), output))
}
9 changes: 9 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module github.com/flexstack/new-dockerfile

go 1.22.3

require (
github.com/lmittmann/tint v1.0.4
github.com/pelletier/go-toml v1.9.5
github.com/spf13/pflag v1.0.5
)
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc=
github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
80 changes: 80 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package dockerfile

import (
"fmt"
"log/slog"
"os"
"path/filepath"

"github.com/flexstack/new-dockerfile/runtime"
)

// Creates a new Dockerfile generator.
func New(log ...*slog.Logger) *Dockerfile {
var logger *slog.Logger

if len(log) > 0 {
logger = log[0]
} else {
logger = slog.New(slog.NewTextHandler(os.Stdout, nil))
}

return &Dockerfile{
log: logger,
}
}

type Dockerfile struct {
log *slog.Logger
}

// Generates a Dockerfile for the given path and writes it to the same directory.
func (a *Dockerfile) Write(path string) error {
runtime, err := a.MatchRuntime(path)
if err != nil {
return err
}

contents, err := runtime.GenerateDockerfile(path)
if err != nil {
return err
}

// Write the Dockerfile to the same directory
if err = os.WriteFile(filepath.Join(path, "Dockerfile"), contents, 0644); err != nil {
return err
}

// a.log.Info("Auto-generated Dockerfile for project using " + string(lang.Name()) + "\n" + *contents)
a.log.Info("Auto-generated Dockerfile for project using " + string(runtime.Name()))
return nil
}

func (a *Dockerfile) ListRuntimes() []runtime.Runtime {
return []runtime.Runtime{
&runtime.Golang{Log: a.log},
&runtime.Rust{Log: a.log},
&runtime.Ruby{Log: a.log},
&runtime.Python{Log: a.log},
&runtime.PHP{Log: a.log},
&runtime.Java{Log: a.log},
&runtime.Elixir{Log: a.log},
&runtime.Deno{Log: a.log},
&runtime.Bun{Log: a.log},
&runtime.NextJS{Log: a.log},
&runtime.Node{Log: a.log},
&runtime.Static{Log: a.log},
}
}

func (a *Dockerfile) MatchRuntime(path string) (runtime.Runtime, error) {
for _, r := range a.ListRuntimes() {
if r.Match(path) {
return r, nil
}
}

return nil, ErrRuntimeNotFound
}

var ErrRuntimeNotFound = fmt.Errorf("A Dockerfile was not detected in the project and we could not auto-generate one for you.")
1 change: 1 addition & 0 deletions node/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Autogenerate a Dockerfile from your project source code
5 changes: 5 additions & 0 deletions node/install.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// TODO:
// 1. Determine the platform and architecture of the system
// 2. Determine the version of the npm package
// 3. Download the Golang binary for the platform and architecture from GitHub releases
console.log("Coming soon...");
41 changes: 41 additions & 0 deletions node/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "new-dockerfile",
"version": "0.1.1",
"description": "Autogenerate Dockerfiles from your project source code",
"main": "index.js",
"bin": {
"new-dockerfile": "bin/new-dockerfile"
},
"scripts": {
"postinstall": "node install.js"
},
"os": [
"darwin",
"linux",
"win32"
],
"cpu": [
"arm64",
"x64"
],
"repository": {
"type": "git",
"url": "git+https://github.com/flexstack/new-dockerfile.git"
},
"keywords": [
"flexstack",
"docker",
"dockerfile",
"dockerfile-generator",
"dockerfile-generator-cli",
"dockerfile-generator-tool",
"generate-dockerfile",
"autogenerate-dockerfile"
],
"author": "Jared Lunde",
"license": "MIT",
"bugs": {
"url": "https://github.com/flexstack/new-dockerfile/issues"
},
"homepage": "https://flexstack.com/docs/languages-and-frameworks/autogenerate-dockerfile"
}
Loading

0 comments on commit fd93f81

Please sign in to comment.