-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrun.go
128 lines (107 loc) · 2.99 KB
/
run.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package codacytool
import (
"context"
"flag"
"fmt"
"os"
"strconv"
"strings"
"time"
"github.com/sirupsen/logrus"
)
// RunConfiguration contains the process run configuration
type RunConfiguration struct {
SourceDir string
ToolConfigurationDir string
Timeout time.Duration
Debug bool
}
const (
defaultTimeout = 15 * time.Minute
defaultDebug = false
defaultSourceDir = "/src"
defaultToolConfigurationDir = "/"
)
// StartTool receives the tool implementation as parameter and runs the tool.
// Issues found will be printed to the standard output in a JSON format.
//
// Return codes are as follows:
// - 0 - Tool executed successfully
// - 1 - An unknown error occurred while running the tool
// - 2 - Execution timeout
func StartTool(tool Tool) int {
runConfiguration := parseRunConfiguration()
if runConfiguration.Debug {
logrus.SetLevel(logrus.DebugLevel)
} else {
logrus.SetLevel(logrus.InfoLevel)
}
results, retCode := runWithTimeout(tool, runConfiguration)
if retCode != 0 {
return retCode
}
fmt.Print(strings.Join(results.ToJSON(), "\n"))
return 0
}
func runWithTimeout(tool Tool, runConfiguration RunConfiguration) (Results, int) {
type ResultsAndRetCode struct {
results Results
retCode int
}
c := make(chan ResultsAndRetCode, 1)
ctx, cancel := context.WithTimeout(context.Background(), runConfiguration.Timeout)
defer cancel()
go func() {
toolExec, err := newToolExecution(runConfiguration)
if err != nil {
logrus.Errorf("Failed to create tool execution: %s", err.Error())
c <- ResultsAndRetCode{results: nil, retCode: 1}
return
}
results, err := tool.Run(ctx, *toolExec)
if err != nil {
logrus.Errorf("Failed to run the tool: %s", err.Error())
c <- ResultsAndRetCode{results: nil, retCode: 1}
return
}
c <- ResultsAndRetCode{results: results, retCode: 0}
}()
select {
case res := <-c:
return res.results, res.retCode
case <-ctx.Done():
logrus.Errorf("Failed to run the tool: Context deadline (%s) exceeded", runConfiguration.Timeout)
return nil, 2
}
}
func parseRunConfiguration() RunConfiguration {
sourceDir := flag.String("sourceDir", defaultSourceDir, "Directory with the source files to analyse")
toolConfigurationDir := flag.String("toolConfigLocation", defaultToolConfigurationDir, "Directory of the tool's configuration")
flag.Parse()
return RunConfiguration{
SourceDir: *sourceDir,
ToolConfigurationDir: *toolConfigurationDir,
Timeout: getTimeout(),
Debug: getDebug(),
}
}
func getTimeout() time.Duration {
timeoutVar, exists := os.LookupEnv("TIMEOUT_SECONDS")
if exists {
seconds, err := strconv.Atoi(timeoutVar)
if err == nil {
return time.Duration(seconds) * time.Second
}
}
return defaultTimeout
}
func getDebug() bool {
debugVar, exists := os.LookupEnv("DEBUG")
if exists {
debug, err := strconv.ParseBool(debugVar)
if err == nil {
return debug
}
}
return defaultDebug
}