Merge branch 'queeno-script_run_command'

This commit is contained in:
Andrey Smirnov
2014-08-25 22:05:34 +04:00
12 changed files with 287 additions and 38 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ language: go
go: go:
- 1.2.1 - 1.2.1
- 1.3 - 1.3.1
- tip - tip
env: env:
+1
View File
@@ -4,6 +4,7 @@ gom 'code.google.com/p/gographviz', :commit => '454bc64fdfa2'
gom 'code.google.com/p/mxk/go1/flowcontrol', :commit => '5ff2502e2556' gom 'code.google.com/p/mxk/go1/flowcontrol', :commit => '5ff2502e2556'
gom 'code.google.com/p/snappy-go/snappy', :commit => '12e4b4183793' gom 'code.google.com/p/snappy-go/snappy', :commit => '12e4b4183793'
gom 'github.com/cheggaaa/pb', :commit => '74be7a1388046f374ac36e93d46f5d56e856f827' gom 'github.com/cheggaaa/pb', :commit => '74be7a1388046f374ac36e93d46f5d56e856f827'
gom 'github.com/mattn/go-shellwords', :commit => 'c7ca6f94add751566a61cf2199e1de78d4c3eee4'
gom 'github.com/mitchellh/goamz/s3', :commit => '55f224c07975fddef9d2116600c664e30df3d594' gom 'github.com/mitchellh/goamz/s3', :commit => '55f224c07975fddef9d2116600c664e30df3d594'
gom 'github.com/mkrautz/goar', :commit => '36eb5f3452b1283a211fa35bc00c646fd0db5c4b' gom 'github.com/mkrautz/goar', :commit => '36eb5f3452b1283a211fa35bc00c646fd0db5c4b'
gom 'github.com/smira/commander', :commit => 'f408b00e68d5d6e21b9f18bd310978dafc604e47' gom 'github.com/smira/commander', :commit => 'f408b00e68d5d6e21b9f18bd310978dafc604e47'
+1
View File
@@ -59,6 +59,7 @@ package environment to new version.`,
makeCmdRepo(), makeCmdRepo(),
makeCmdServe(), makeCmdServe(),
makeCmdSnapshot(), makeCmdSnapshot(),
makeCmdTask(),
makeCmdPublish(), makeCmdPublish(),
makeCmdVersion(), makeCmdVersion(),
}, },
+32 -8
View File
@@ -22,8 +22,8 @@ import (
// AptlyContext is a common context shared by all commands // AptlyContext is a common context shared by all commands
type AptlyContext struct { type AptlyContext struct {
flags *flag.FlagSet flags, globalFlags *flag.FlagSet
configLoaded bool configLoaded bool
progress aptly.Progress progress aptly.Progress
downloader aptly.Downloader downloader aptly.Downloader
@@ -65,7 +65,7 @@ func (context *AptlyContext) Config() *utils.ConfigStructure {
if !context.configLoaded { if !context.configLoaded {
var err error var err error
configLocation := context.flags.Lookup("config").Value.String() configLocation := context.globalFlags.Lookup("config").Value.String()
if configLocation != "" { if configLocation != "" {
err = utils.LoadConfig(configLocation, &utils.Config) err = utils.LoadConfig(configLocation, &utils.Config)
@@ -104,16 +104,16 @@ func (context *AptlyContext) Config() *utils.ConfigStructure {
func (context *AptlyContext) DependencyOptions() int { func (context *AptlyContext) DependencyOptions() int {
if context.dependencyOptions == -1 { if context.dependencyOptions == -1 {
context.dependencyOptions = 0 context.dependencyOptions = 0
if context.Config().DepFollowSuggests || context.flags.Lookup("dep-follow-suggests").Value.Get().(bool) { if context.Config().DepFollowSuggests || context.globalFlags.Lookup("dep-follow-suggests").Value.Get().(bool) {
context.dependencyOptions |= deb.DepFollowSuggests context.dependencyOptions |= deb.DepFollowSuggests
} }
if context.Config().DepFollowRecommends || context.flags.Lookup("dep-follow-recommends").Value.Get().(bool) { if context.Config().DepFollowRecommends || context.globalFlags.Lookup("dep-follow-recommends").Value.Get().(bool) {
context.dependencyOptions |= deb.DepFollowRecommends context.dependencyOptions |= deb.DepFollowRecommends
} }
if context.Config().DepFollowAllVariants || context.flags.Lookup("dep-follow-all-variants").Value.Get().(bool) { if context.Config().DepFollowAllVariants || context.globalFlags.Lookup("dep-follow-all-variants").Value.Get().(bool) {
context.dependencyOptions |= deb.DepFollowAllVariants context.dependencyOptions |= deb.DepFollowAllVariants
} }
if context.Config().DepFollowSource || context.flags.Lookup("dep-follow-source").Value.Get().(bool) { if context.Config().DepFollowSource || context.globalFlags.Lookup("dep-follow-source").Value.Get().(bool) {
context.dependencyOptions |= deb.DepFollowSource context.dependencyOptions |= deb.DepFollowSource
} }
} }
@@ -125,7 +125,7 @@ func (context *AptlyContext) DependencyOptions() int {
func (context *AptlyContext) ArchitecturesList() []string { func (context *AptlyContext) ArchitecturesList() []string {
if context.architecturesList == nil { if context.architecturesList == nil {
context.architecturesList = context.Config().Architectures context.architecturesList = context.Config().Architectures
optionArchitectures := context.flags.Lookup("architectures").Value.String() optionArchitectures := context.globalFlags.Lookup("architectures").Value.String()
if optionArchitectures != "" { if optionArchitectures != "" {
context.architecturesList = strings.Split(optionArchitectures, ",") context.architecturesList = strings.Split(optionArchitectures, ",")
} }
@@ -230,6 +230,10 @@ func (context *AptlyContext) GetPublishedStorage(name string) aptly.PublishedSto
return publishedStorage return publishedStorage
} }
func (context *AptlyContext) UpdateFlags(flags *flag.FlagSet) {
context.flags = flags
}
// ShutdownContext shuts context down // ShutdownContext shuts context down
func ShutdownContext() { func ShutdownContext() {
if aptly.EnableDebug { if aptly.EnableDebug {
@@ -250,12 +254,27 @@ func ShutdownContext() {
} }
if context.database != nil { if context.database != nil {
context.database.Close() context.database.Close()
context.database = nil
} }
if context.downloader != nil { if context.downloader != nil {
context.downloader.Shutdown() context.downloader.Shutdown()
context.downloader = nil
} }
if context.progress != nil { if context.progress != nil {
context.progress.Shutdown() context.progress.Shutdown()
context.progress = nil
}
}
// CleanupContext does partial shutdown of context
func CleanupContext() {
if context.downloader != nil {
context.downloader.Shutdown()
context.downloader = nil
}
if context.progress != nil {
context.progress.Shutdown()
context.progress = nil
} }
} }
@@ -263,8 +282,13 @@ func ShutdownContext() {
func InitContext(flags *flag.FlagSet) error { func InitContext(flags *flag.FlagSet) error {
var err error var err error
if context != nil {
panic("context already initialized")
}
context = &AptlyContext{ context = &AptlyContext{
flags: flags, flags: flags,
globalFlags: flags,
dependencyOptions: -1, dependencyOptions: -1,
publishedStorages: map[string]aptly.PublishedStorage{}, publishedStorages: map[string]aptly.PublishedStorage{},
} }
+43
View File
@@ -0,0 +1,43 @@
package cmd
import (
"fmt"
"github.com/smira/commander"
)
func Run(cmd *commander.Command, cmd_args []string, initContext bool) (returnCode int) {
defer func() {
if r := recover(); r != nil {
fatal, ok := r.(*FatalError)
if !ok {
panic(r)
}
fmt.Println("ERROR:", fatal.Message)
returnCode = fatal.ReturnCode
}
}()
returnCode = 0
flags, args, err := cmd.ParseFlags(cmd_args)
if err != nil {
Fatal(err)
}
if initContext {
err = InitContext(flags)
if err != nil {
Fatal(err)
}
defer ShutdownContext()
}
context.UpdateFlags(flags)
err = cmd.Dispatch(args)
if err != nil {
Fatal(err)
}
return
}
+15
View File
@@ -0,0 +1,15 @@
package cmd
import (
"github.com/smira/commander"
)
func makeCmdTask() *commander.Command {
return &commander.Command{
UsageLine: "task",
Short: "manage aptly tasks",
Subcommands: []*commander.Command{
makeCmdTaskRun(),
},
}
}
+152
View File
@@ -0,0 +1,152 @@
package cmd
import (
"bufio"
"fmt"
"os"
"strings"
"github.com/mattn/go-shellwords"
"github.com/smira/commander"
)
func aptlyTaskRun(cmd *commander.Command, args []string) error {
var err error
var cmd_list [][]string
if filename := cmd.Flag.Lookup("filename").Value.Get().(string); filename != "" {
var text string
cmd_args := []string{}
if finfo, err := os.Stat(filename); os.IsNotExist(err) || finfo.IsDir() {
return fmt.Errorf("No such file, %s\n", filename)
}
fmt.Println("Reading file...\n")
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
text = strings.TrimSpace(scanner.Text()) + ","
parsed_args, _ := shellwords.Parse(text)
cmd_args = append(cmd_args, parsed_args...)
}
if err = scanner.Err(); err != nil {
return err
}
if len(cmd_args) == 0 {
return fmt.Errorf("The file is empty. Exiting...\n")
}
cmd_list = formatCommands(cmd_args)
} else if len(args) == 0 {
var text string
cmd_args := []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
} else {
text = strings.TrimSpace(text) + ","
parsed_args, _ := shellwords.Parse(text)
cmd_args = append(cmd_args, parsed_args...)
}
}
if len(cmd_args) == 0 {
return fmt.Errorf("Nothing entered. Exiting...\n")
}
cmd_list = formatCommands(cmd_args)
} else {
cmd_list = formatCommands(args)
}
commandErrored := false
for i, command := range cmd_list {
if !commandErrored {
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\n")
}
return err
}
func formatCommands(args []string) [][]string {
var cmd []string
var cmd_array [][]string
for _, s := range args {
if s_trimmed := strings.TrimRight(s, ","); s_trimmed != s {
cmd = append(cmd, s_trimmed)
cmd_array = append(cmd_array, cmd)
cmd = []string{}
} else {
cmd = append(cmd, s)
}
}
if len(cmd) > 0 {
cmd_array = append(cmd_array, cmd)
}
return cmd_array
}
func makeCmdTaskRun() *commander.Command {
cmd := &commander.Command{
Run: aptlyTaskRun,
UsageLine: "run -filename=<filename> | <command1>, <command2>, ...",
Short: "run aptly tasks",
Long: `
Command helps origanise 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
}
+1 -29
View File
@@ -1,38 +1,10 @@
package main package main
import ( import (
"fmt"
"github.com/smira/aptly/cmd" "github.com/smira/aptly/cmd"
"os" "os"
) )
func main() { func main() {
defer func() { os.Exit(cmd.Run(cmd.RootCommand(), os.Args[1:], true))
if r := recover(); r != nil {
fatal, ok := r.(*cmd.FatalError)
if !ok {
panic(r)
}
fmt.Println("ERROR:", fatal.Message)
os.Exit(fatal.ReturnCode)
}
}()
command := cmd.RootCommand()
flags, args, err := command.ParseFlags(os.Args[1:])
if err != nil {
cmd.Fatal(err)
}
err = cmd.InitContext(flags)
if err != nil {
cmd.Fatal(err)
}
defer cmd.ShutdownContext()
err = command.Dispatch(args)
if err != nil {
cmd.Fatal(err)
}
} }
+1
View File
@@ -9,6 +9,7 @@ Commands:
repo manage local package repositories repo manage local package repositories
serve HTTP serve published repositories serve HTTP serve published repositories
snapshot manage snapshots of repositories snapshot manage snapshots of repositories
task manage aptly tasks
version display version version display version
Use "aptly help <command>" for more information about a command. Use "aptly help <command>" for more information about a command.
+26
View File
@@ -0,0 +1,26 @@
1) [Running]: repo list
Begin command output: ----------------------------
No local repositories found, create one with `aptly repo create ...`.
End command output: ------------------------------
2) [Running]: repo create local
Begin command output: ----------------------------
Local repo [local] successfully added.
You can run 'aptly repo add local ...' to add packages to repository.
End command output: ------------------------------
Local repo `local` has been removed.
3) [Running]: repo drop local
Begin command output: ----------------------------
End command output: ------------------------------
aptly version: 0.8~dev
4) [Running]: version
Begin command output: ----------------------------
End command output: ------------------------------
+5
View File
@@ -0,0 +1,5 @@
"""
Test aptly task run
"""
from .run import *
+9
View File
@@ -0,0 +1,9 @@
from lib import BaseTest
class RunTask1Test(BaseTest):
"""
output should match
"""
runCmd = "aptly task run repo list, repo create local, repo drop local, version"