Skip to content

Commit

Permalink
Merge pull request #27 from josegonzalez/master
Browse files Browse the repository at this point in the history
Release 0.11.0
  • Loading branch information
josegonzalez authored Oct 27, 2020
2 parents b7d6bc7 + f0e5865 commit 34a0157
Show file tree
Hide file tree
Showing 45 changed files with 1,198 additions and 919 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ validation/*
# .env files
.env*

*Procfile
*.Procfile
!fixtures/**/*Procfile

procfile-util
2 changes: 1 addition & 1 deletion Dockerfile.build
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM golang:1.12.0-stretch

RUN apt-get update \
&& apt install apt-transport-https build-essential curl gnupg2 lintian rpm rsync rubygems-integration ruby-dev ruby -qy \
&& apt install apt-transport-https bats build-essential curl gnupg2 lintian rpm rsync rubygems-integration ruby-dev ruby -qy \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ MAINTAINER_NAME = Jose Diaz-Gonzalez
REPOSITORY = go-procfile-util
HARDWARE = $(shell uname -m)
SYSTEM_NAME = $(shell uname -s | tr '[:upper:]' '[:lower:]')
BASE_VERSION ?= 0.10.1
BASE_VERSION ?= 0.11.0
IMAGE_NAME ?= $(MAINTAINER)/$(REPOSITORY)
PACKAGECLOUD_REPOSITORY ?= dokku/dokku-betafish

Expand Down Expand Up @@ -162,7 +162,8 @@ validate:
ls -lah build/deb build/rpm validation
sha1sum build/deb/$(NAME)_$(VERSION)_amd64.deb
sha1sum build/rpm/$(NAME)-$(VERSION)-1.x86_64.rpm
bats test.bats

prebuild:
go get -u github.com/go-bindata/go-bindata/...
go-bindata templates/...
cd export && go-bindata -pkg export templates/...
26 changes: 26 additions & 0 deletions commands/check_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package commands

import (
"fmt"
"os"
"strings"

"procfile-util/procfile"
)


func CheckCommand(entries []procfile.ProcfileEntry) bool {
if len(entries) == 0 {
fmt.Fprintf(os.Stderr, "no processes defined\n")
return false
}

names := []string{}
for _, entry := range entries {
names = append(names, entry.Name)
}

processNames := strings.Join(names[:], ", ")
fmt.Printf("valid procfile detected %v\n", processNames)
return true
}
72 changes: 72 additions & 0 deletions commands/commands.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package commands

import (
"io/ioutil"
"os"
"strconv"
"strings"

"procfile-util/procfile"

"github.com/joho/godotenv"
)

const portEnvVar = "PORT"

func expandEnv(e procfile.ProcfileEntry, envPath string, allowEnv bool, defaultPort int) (string, error) {
baseExpandFunc := func(key string) string {
if key == "PS" {
return os.Getenv("PS")
}
if key == portEnvVar {
return strconv.Itoa(defaultPort)
}
return ""
}

expandFunc := func(key string) string {
return baseExpandFunc(key)
}

if allowEnv {
expandFunc = func(key string) string {
value := os.Getenv(key)
if value == "" {
value = baseExpandFunc(key)
}
return value
}
}

if envPath != "" {
b, err := ioutil.ReadFile(envPath)
if err != nil {
return "", err
}

content := string(b)
env, err := godotenv.Unmarshal(content)
if err != nil {
return "", err
}

expandFunc = func(key string) string {
if val, ok := env[key]; ok {
return val
}
value := ""
if allowEnv {
value = os.Getenv(key)
}
if value == "" {
value = baseExpandFunc(key)
}
return value
}
}

os.Setenv("PS", e.Name)
os.Setenv("EXPENV_PARENTHESIS", "$(")
s := strings.Replace(e.Command, "$(", "${EXPENV_PARENTHESIS}", -1)
return os.Expand(s, expandFunc), nil
}
17 changes: 17 additions & 0 deletions commands/delete_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package commands

import (
"procfile-util/procfile"
)

func DeleteCommand(entries []procfile.ProcfileEntry, processType string, writePath string, stdout bool, delimiter string, path string) bool {
var validEntries []procfile.ProcfileEntry
for _, entry := range entries {
if processType == entry.Name {
continue
}
validEntries = append(validEntries, entry)
}

return procfile.OutputProcfile(path, writePath, delimiter, stdout, validEntries)
}
19 changes: 19 additions & 0 deletions commands/exists_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package commands

import (
"fmt"
"os"

"procfile-util/procfile"
)

func ExistsCommand(entries []procfile.ProcfileEntry, processType string) bool {
for _, entry := range entries {
if processType == entry.Name {
return true
}
}

fmt.Fprint(os.Stderr, "no matching process entry found\n")
return false
}
35 changes: 35 additions & 0 deletions commands/expand_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package commands

import (
"fmt"
"os"

"procfile-util/procfile"
)

func ExpandCommand(entries []procfile.ProcfileEntry, envPath string, allowGetenv bool, processType string, defaultPort int, delimiter string) bool {
hasErrors := false
var expandedEntries []procfile.ProcfileEntry
for _, entry := range entries {
command, err := expandEnv(entry, envPath, allowGetenv, defaultPort)
if err != nil {
fmt.Fprintf(os.Stderr, "error processing command: %s\n", err)
hasErrors = true
}

entry.Command = command
expandedEntries = append(expandedEntries, entry)
}

if hasErrors {
return false
}

for _, entry := range expandedEntries {
if processType == "" || processType == entry.Name {
fmt.Printf("%v%v %v\n", entry.Name, delimiter, entry.Command)
}
}

return true
}
143 changes: 143 additions & 0 deletions commands/export_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package commands

import (
"fmt"
"io/ioutil"
"os"
"os/user"
"strconv"
"strings"

"procfile-util/export"
"procfile-util/procfile"

"github.com/joho/godotenv"
)

func ExportCommand(entries []procfile.ProcfileEntry, app string, description string, envPath string, format string, formation string, group string, home string, limitCoredump string, limitCputime string, limitData string, limitFileSize string, limitLockedMemory string, limitOpenFiles string, limitUserProcesses string, limitPhysicalMemory string, limitStackSize string, location string, logPath string, nice string, prestart string, workingDirectoryPath string, runPath string, timeout int, processUser string, defaultPort int) bool {
if format == "" {
fmt.Fprintf(os.Stderr, "no format specified\n")
return false
}
if location == "" {
fmt.Fprintf(os.Stderr, "no output location specified\n")
return false
}

formats := map[string]export.ExportFunc{
"launchd": export.ExportLaunchd,
"runit": export.ExportRunit,
"systemd": export.ExportSystemd,
"systemd-user": export.ExportSystemdUser,
"sysv": export.ExportSysv,
"upstart": export.ExportUpstart,
}

if _, ok := formats[format]; !ok {
fmt.Fprintf(os.Stderr, "invalid format type: %s\n", format)
return false
}

formations, err := procfile.ParseFormation(formation)
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
return false
}

if processUser == "" {
processUser = app
}

if group == "" {
group = app
}

u, err := user.Current()
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
return false
}

if home == "" {
home = "/home/" + u.Username
}

env := make(map[string]string)
if envPath != "" {
b, err := ioutil.ReadFile(envPath)
if err != nil {
fmt.Fprintf(os.Stderr, "error reading env file: %s\n", err)
return false
}

content := string(b)
env, err = godotenv.Unmarshal(content)
if err != nil {
fmt.Fprintf(os.Stderr, "error parsing env file: %s\n", err)
return false
}
}

vars := make(map[string]interface{})
vars["app"] = app
vars["description"] = description
vars["env"] = env
vars["group"] = group
vars["home"] = home
vars["log"] = logPath
vars["location"] = location
vars["limit_coredump"] = limitCoredump
vars["limit_cputime"] = limitCputime
vars["limit_data"] = limitData
vars["limit_file_size"] = limitFileSize
vars["limit_locked_memory"] = limitLockedMemory
vars["limit_open_files"] = limitOpenFiles
vars["limit_user_processes"] = limitUserProcesses
vars["limit_physical_memory"] = limitPhysicalMemory
vars["limit_stack_size"] = limitStackSize
vars["nice"] = nice
vars["prestart"] = prestart
vars["working_directory"] = workingDirectoryPath
vars["timeout"] = strconv.Itoa(timeout)
vars["ulimit_shell"] = ulimitShell(limitCoredump, limitCputime, limitData, limitFileSize, limitLockedMemory, limitOpenFiles, limitUserProcesses, limitPhysicalMemory, limitStackSize)
vars["user"] = processUser

if fn, ok := formats[format]; ok {
return fn(app, entries, formations, location, defaultPort, vars)
}

return false
}

func ulimitShell(limitCoredump string, limitCputime string, limitData string, limitFileSize string, limitLockedMemory string, limitOpenFiles string, limitUserProcesses string, limitPhysicalMemory string, limitStackSize string) string {
s := []string{}
if limitCoredump != "" {
s = append(s, "ulimit -c ${limit_coredump}")
}
if limitCputime != "" {
s = append(s, "ulimit -t ${limit_cputime}")
}
if limitData != "" {
s = append(s, "ulimit -d ${limit_data}")
}
if limitFileSize != "" {
s = append(s, "ulimit -f ${limit_file_size}")
}
if limitLockedMemory != "" {
s = append(s, "ulimit -l ${limit_locked_memory}")
}
if limitOpenFiles != "" {
s = append(s, "ulimit -n ${limit_open_files}")
}
if limitUserProcesses != "" {
s = append(s, "ulimit -u ${limit_user_processes}")
}
if limitPhysicalMemory != "" {
s = append(s, "ulimit -m ${limit_physical_memory}")
}
if limitStackSize != "" {
s = append(s, "ulimit -s ${limit_stack_size}")
}

return strings.Join(s, "\n")
}
14 changes: 14 additions & 0 deletions commands/list_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package commands

import (
"fmt"

"procfile-util/procfile"
)

func ListCommand(entries []procfile.ProcfileEntry) bool {
for _, entry := range entries {
fmt.Printf("%v\n", entry.Name)
}
return true
}
18 changes: 18 additions & 0 deletions commands/set_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package commands

import (
"procfile-util/procfile"
)

func SetCommand(entries []procfile.ProcfileEntry, processType string, command string, writePath string, stdout bool, delimiter string, path string) bool {
var validEntries []procfile.ProcfileEntry
validEntries = append(validEntries, procfile.ProcfileEntry{processType, command})
for _, entry := range entries {
if processType == entry.Name {
continue
}
validEntries = append(validEntries, entry)
}

return procfile.OutputProcfile(path, writePath, delimiter, stdout, validEntries)
}
Loading

0 comments on commit 34a0157

Please sign in to comment.