mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-01-11 03:11:50 +00:00
Refactoring: new packages console, http, Progress is interface.
This commit is contained in:
134
console/progress.go
Normal file
134
console/progress.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package console
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/cheggaaa/pb"
|
||||
"github.com/smira/aptly/aptly"
|
||||
)
|
||||
|
||||
const (
|
||||
codePrint = iota
|
||||
codeProgress
|
||||
codeHideProgress
|
||||
)
|
||||
|
||||
type printTask struct {
|
||||
code int
|
||||
message string
|
||||
}
|
||||
|
||||
// Progress is a progress displaying subroutine, it allows to show download and other operations progress
|
||||
// mixed with progress bar
|
||||
type Progress struct {
|
||||
stop chan bool
|
||||
stopped chan bool
|
||||
queue chan printTask
|
||||
bar *pb.ProgressBar
|
||||
barShown bool
|
||||
}
|
||||
|
||||
// Check interface
|
||||
var (
|
||||
_ aptly.Progress = (*Progress)(nil)
|
||||
)
|
||||
|
||||
// NewProgress creates new progress instance
|
||||
func NewProgress() *Progress {
|
||||
return &Progress{
|
||||
stop: make(chan bool),
|
||||
stopped: make(chan bool),
|
||||
queue: make(chan printTask, 100),
|
||||
}
|
||||
}
|
||||
|
||||
// Start makes progress start its work
|
||||
func (p *Progress) Start() {
|
||||
go p.worker()
|
||||
}
|
||||
|
||||
// Shutdown shuts down progress display
|
||||
func (p *Progress) Shutdown() {
|
||||
p.ShutdownBar()
|
||||
p.stop <- true
|
||||
<-p.stopped
|
||||
}
|
||||
|
||||
// InitBar starts progressbar for count bytes or count items
|
||||
func (p *Progress) InitBar(count int64, isBytes bool) {
|
||||
if p.bar != nil {
|
||||
panic("bar already initialized")
|
||||
}
|
||||
if RunningOnTerminal() {
|
||||
p.bar = pb.New(0)
|
||||
p.bar.Total = count
|
||||
p.bar.NotPrint = true
|
||||
p.bar.Callback = func(out string) {
|
||||
p.queue <- printTask{code: codeProgress, message: out}
|
||||
}
|
||||
|
||||
if isBytes {
|
||||
p.bar.SetUnits(pb.U_BYTES)
|
||||
p.bar.ShowSpeed = true
|
||||
}
|
||||
p.bar.Start()
|
||||
}
|
||||
}
|
||||
|
||||
// ShutdownBar stops progress bar and hides it
|
||||
func (p *Progress) ShutdownBar() {
|
||||
if p.bar == nil {
|
||||
return
|
||||
}
|
||||
p.bar.Finish()
|
||||
p.bar = nil
|
||||
p.queue <- printTask{code: codeHideProgress}
|
||||
}
|
||||
|
||||
// Write is implementation of io.Writer to support updating of progress bar
|
||||
func (p *Progress) Write(s []byte) (int, error) {
|
||||
if p.bar != nil {
|
||||
p.bar.Add(len(s))
|
||||
}
|
||||
return len(s), nil
|
||||
}
|
||||
|
||||
// AddBar increments progress for progress bar
|
||||
func (p *Progress) AddBar(count int) {
|
||||
if p.bar != nil {
|
||||
p.bar.Add(count)
|
||||
}
|
||||
}
|
||||
|
||||
// Printf does printf but in safe manner: not overwriting progress bar
|
||||
func (p *Progress) Printf(msg string, a ...interface{}) {
|
||||
p.queue <- printTask{code: codePrint, message: fmt.Sprintf(msg, a...)}
|
||||
}
|
||||
|
||||
func (p *Progress) worker() {
|
||||
for {
|
||||
select {
|
||||
case task := <-p.queue:
|
||||
switch task.code {
|
||||
case codePrint:
|
||||
if p.barShown {
|
||||
fmt.Print("\r\033[2K")
|
||||
p.barShown = false
|
||||
}
|
||||
fmt.Print(task.message)
|
||||
case codeProgress:
|
||||
if p.bar != nil {
|
||||
fmt.Print("\r" + task.message)
|
||||
p.barShown = true
|
||||
}
|
||||
case codeHideProgress:
|
||||
if p.barShown {
|
||||
fmt.Print("\r\033[2K")
|
||||
p.barShown = false
|
||||
}
|
||||
}
|
||||
case <-p.stop:
|
||||
p.stopped <- true
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
13
console/terminal.go
Normal file
13
console/terminal.go
Normal file
@@ -0,0 +1,13 @@
|
||||
// +build !freebsd
|
||||
|
||||
package console
|
||||
|
||||
import (
|
||||
"code.google.com/p/go.crypto/ssh/terminal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// RunningOnTerminal checks whether stdout is terminal
|
||||
func RunningOnTerminal() bool {
|
||||
return terminal.IsTerminal(syscall.Stdout)
|
||||
}
|
||||
10
console/terminal_bsd.go
Normal file
10
console/terminal_bsd.go
Normal file
@@ -0,0 +1,10 @@
|
||||
// +build freebsd
|
||||
|
||||
package console
|
||||
|
||||
// RunningOnTerminal checks whether stdout is terminal
|
||||
//
|
||||
// Stub for FreeBSD, until in go1.3 terminal.IsTerminal would start working for FreeBSD
|
||||
func RunningOnTerminal() bool {
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user