new attribute interpreter for commands (#7)

This commit is contained in:
Julien Neuhart
2018-05-16 10:55:08 +02:00
committed by GitHub
parent faec55dd01
commit 5100693789
15 changed files with 102 additions and 25 deletions

View File

@@ -8,6 +8,7 @@ package config
import (
"fmt"
"strings"
"text/template"
"github.com/sirupsen/logrus"
@@ -29,6 +30,8 @@ type (
Command struct {
// Template is the data-driven template of the command.
Template *template.Template
// The binary which will call the command.
Interpreter []string
// Timeout is the duration in seconds after which the command's process will be killed
// if it does not finish before.
Timeout int
@@ -123,15 +126,29 @@ func GetLogsFormatter() logrus.Formatter {
return config.logsFormatter
}
type interpreterEmptyError struct {
command string
}
const interpreterEmptyErrorMessage = "the interepreter for command %s should not be empty"
func (e *interpreterEmptyError) Error() string {
return fmt.Sprintf(interpreterEmptyErrorMessage, e.command)
}
// NewCommand instantiates a Command. If the given command string
// is not a valid template, throws an error.
func NewCommand(command string, timeout int) (*Command, error) {
func NewCommand(command string, interpreter string, timeout int) (*Command, error) {
t, err := template.New(command).Parse(command)
if err != nil {
return nil, err
}
return &Command{t, timeout}, nil
if interpreter == "" {
return nil, &interpreterEmptyError{command}
}
return &Command{t, strings.Fields(interpreter), timeout}, nil
}
type fileExtensionAlreadyUsedError struct {
@@ -140,7 +157,7 @@ type fileExtensionAlreadyUsedError struct {
existingCommand *Command
}
const fileExtensionAlreadyUsedErrorMessage = "file extension '%s' from command '%s' is already used by command '%s'"
const fileExtensionAlreadyUsedErrorMessage = "file extension %s from command %s is already used by command %s"
func (e *fileExtensionAlreadyUsedError) Error() string {
return fmt.Sprintf(fileExtensionAlreadyUsedErrorMessage, e.extension, e.command.Template.Name(), e.existingCommand.Template.Name())
@@ -167,7 +184,7 @@ type noCommandFoundForFileExtensionError struct {
extension string
}
const noCommandFoundForFileExtensionErrorMessage = "no command found for file extension '%s'"
const noCommandFoundForFileExtensionErrorMessage = "no command found for file extension %s"
func (e *noCommandFoundForFileExtensionError) Error() string {
return fmt.Sprintf(noCommandFoundForFileExtensionErrorMessage, e.extension)

View File

@@ -99,26 +99,39 @@ func TestGetLogsFormatter(t *testing.T) {
}
}
func TestInterpreterEmptyError(t *testing.T) {
err := &interpreterEmptyError{"echo hello world"}
expected := fmt.Sprintf(interpreterEmptyErrorMessage, err.command)
if err.Error() != expected {
t.Errorf("Error returned a wrong message: got '%s' want '%s'", err.Error(), expected)
}
}
func TestNewCommand(t *testing.T) {
var cmd string
// case 1: uses a wrong command template.
cmd = "pdftk {{ range $filePath := FilesPaths }} {{ $filePath }} {{ end }} cat output {{ .ResultFilePath }}"
if _, err := NewCommand(cmd, 0); err == nil {
if _, err := NewCommand(cmd, "/bin/sh -c", 0); err == nil {
t.Errorf("Command should not have been instantiated by using '%s' as command template", cmd)
}
// case 2: uses a correct command template.
cmd = "pdftk {{ range $filePath := .FilesPaths }} {{ $filePath }} {{ end }} cat output {{ .ResultFilePath }}"
if _, err := NewCommand(cmd, 0); err != nil {
if _, err := NewCommand(cmd, "/bin/sh -c", 0); err != nil {
t.Errorf("Command should have been instantiated by using '%s' as command template", cmd)
}
// case 3: uses an empty interpreter.
if _, err := NewCommand(cmd, "", 0); err == nil {
t.Error("Command should not have been instantiated by using an empty interpreter")
}
}
func TestFileExtensionAlreadyUsedError(t *testing.T) {
ext := ".pdf"
cmd1, _ := NewCommand("echo", 0)
cmd2, _ := NewCommand("echo", 0)
cmd1, _ := NewCommand("echo", "/bin/sh -c", 0)
cmd2, _ := NewCommand("echo", "/bin/sh -c", 0)
err := &fileExtensionAlreadyUsedError{ext, cmd1, cmd2}
expected := fmt.Sprintf(fileExtensionAlreadyUsedErrorMessage, err.extension, err.command.Template.Name(), err.existingCommand.Template.Name())
@@ -129,7 +142,7 @@ func TestFileExtensionAlreadyUsedError(t *testing.T) {
func TestWithCommand(t *testing.T) {
ext := ".pdf"
cmd, _ := NewCommand("echo", 0)
cmd, _ := NewCommand("echo", "/bin/sh -c", 0)
// case 1: uses a command with a file extension not already referenced.
if err := WithCommand(ext, cmd); err != nil {
@@ -154,7 +167,7 @@ func TestNoCommandFoundForFileExtensionError(t *testing.T) {
func TestGetCommand(t *testing.T) {
Reset()
ext := ".pdf"
cmd, _ := NewCommand("echo", 0)
cmd, _ := NewCommand("echo", "/bin/sh -c", 0)
WithCommand(ext, cmd)
// case 1: uses a file extension which has a command associated.

View File

@@ -24,7 +24,7 @@ func ParseFile(configurationFilePath string) error {
}
// handles merge command first...
cmd, err := NewCommand(fileConfig.Commands.Merge.Template, fileConfig.Commands.Merge.Timeout)
cmd, err := NewCommand(fileConfig.Commands.Merge.Template, fileConfig.Commands.Merge.Interpreter, fileConfig.Commands.Merge.Timeout)
if err != nil {
return err
}
@@ -33,7 +33,7 @@ func ParseFile(configurationFilePath string) error {
// ...then conversion commands!
for _, command := range fileConfig.Commands.Conversions {
cmd, err := NewCommand(command.Template, command.Timeout)
cmd, err := NewCommand(command.Template, command.Interpreter, command.Timeout)
if err != nil {
return err
}
@@ -64,15 +64,17 @@ type (
// mergeCommand gathers all data regarding the... merge command.
mergeCommand struct {
Template string `yaml:"template"`
Timeout int `yaml:"timeout"`
Template string `yaml:"template"`
Interpreter string `yaml:"interpreter"`
Timeout int `yaml:"timeout"`
}
// conversionCommand gathers all data regarding a conversion command.
conversionCommand struct {
Template string `yaml:"template"`
Timeout int `yaml:"timeout"`
Extensions []string `yaml:"extensions"`
Template string `yaml:"template"`
Interpreter string `yaml:"interpreter"`
Timeout int `yaml:"timeout"`
Extensions []string `yaml:"extensions"`
}
)