File: task_run.go

package info (click to toggle)
aptly 1.6.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 49,928 kB
  • sloc: python: 10,398; sh: 252; makefile: 184
file content (153 lines) | stat: -rw-r--r-- 3,419 bytes parent folder | download | duplicates (2)
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package cmd

import (
	"bufio"
	"fmt"
	"os"
	"strings"

	shellwords "github.com/mattn/go-shellwords"
	"github.com/smira/commander"
)

func aptlyTaskRun(cmd *commander.Command, args []string) error {
	var err error
	var cmdList [][]string

	if filename := cmd.Flag.Lookup("filename").Value.Get().(string); filename != "" {
		var text string
		cmdArgs := []string{}

		var finfo os.FileInfo
		if finfo, err = os.Stat(filename); os.IsNotExist(err) || finfo.IsDir() {
			return fmt.Errorf("no such file, %s", filename)
		}

		fmt.Print("Reading file...\n\n")

		var file *os.File
		file, err = os.Open(filename)

		if err != nil {
			return err
		}
		defer func() { _ = file.Close() }()

		scanner := bufio.NewScanner(file)

		for scanner.Scan() {
			text = strings.TrimSpace(scanner.Text()) + ","
			parsedArgs, _ := shellwords.Parse(text)
			cmdArgs = append(cmdArgs, parsedArgs...)
		}

		if err = scanner.Err(); err != nil {
			return err
		}

		if len(cmdArgs) == 0 {
			return fmt.Errorf("the file is empty")
		}

		cmdList = formatCommands(cmdArgs)
	} else if len(args) == 0 {
		var text string
		cmdArgs := []string{}

		fmt.Println("Please enter one command per line and leave one blank when finished.")

		reader := bufio.NewReader(os.Stdin)
		for {
			fmt.Printf("> ")
			text, _ = reader.ReadString('\n')
			if text == "\n" {
				break
			}
			text = strings.TrimSpace(text) + ","
			parsedArgs, _ := shellwords.Parse(text)
			cmdArgs = append(cmdArgs, parsedArgs...)
		}

		if len(cmdArgs) == 0 {
			return fmt.Errorf("nothing entered")
		}

		cmdList = formatCommands(cmdArgs)
	} else {
		cmdList = formatCommands(args)
	}

	commandErrored := false

	for i, command := range cmdList {
		if !commandErrored {
			err = context.ReOpenDatabase()
			if err != nil {
				return fmt.Errorf("failed to reopen DB: %s", err)
			}
			context.Progress().ColoredPrintf("@g%d) [Running]: %s@!", (i + 1), strings.Join(command, " "))
			context.Progress().ColoredPrintf("\n@yBegin command output: ----------------------------@!")
			context.Progress().Flush()

			returnCode := Run(RootCommand(), command, false)
			if returnCode != 0 {
				commandErrored = true
			}
			context.Progress().ColoredPrintf("\n@yEnd command output: ------------------------------@!")
			CleanupContext()
		} else {
			context.Progress().ColoredPrintf("@r%d) [Skipping]: %s@!", (i + 1), strings.Join(command, " "))
		}
	}

	if commandErrored {
		err = fmt.Errorf("at least one command has reported an error")
	}

	return err
}

func formatCommands(args []string) [][]string {
	var cmd []string
	var cmdArray [][]string

	for _, s := range args {
		if sTrimmed := strings.TrimRight(s, ","); sTrimmed != s {
			cmd = append(cmd, sTrimmed)
			cmdArray = append(cmdArray, cmd)
			cmd = []string{}
		} else {
			cmd = append(cmd, s)
		}
	}

	if len(cmd) > 0 {
		cmdArray = append(cmdArray, cmd)
	}

	return cmdArray
}

func makeCmdTaskRun() *commander.Command {
	cmd := &commander.Command{
		Run:       aptlyTaskRun,
		UsageLine: "run (-filename=<filename> | <commands>...)",
		Short:     "run aptly tasks",
		Long: `
Command helps organise multiple aptly commands in one single aptly task, running as single thread.

Example:

	  $ aptly task run
	  > repo create local
	  > repo add local pkg1
	  > publish repo local
	  > serve
	  >

`,
	}

	cmd.Flag.String("filename", "", "specifies the filename that contains the commands to run")
	return cmd
}