build script

pull/5/head
Miguel Mota 6 years ago
parent 7da09bc644
commit 6f3f3dd824

12
Gopkg.lock generated

@ -65,7 +65,7 @@
branch = "master"
name = "github.com/miguelmota/go-coinmarketcap"
packages = ["."]
revision = "05fd2d0c45f763462f90e630da2ddc0392d2cdd3"
revision = "9c6b4c2a42d7189f8778825da9640c3efda17d7e"
[[projects]]
branch = "master"
@ -79,12 +79,6 @@
packages = ["."]
revision = "e2050e41c8847748ec5288741c0b19a8cb26d084"
[[projects]]
branch = "master"
name = "github.com/willf/pad"
packages = ["."]
revision = "b3d7806010228b1a954b4d9c4ee4cf6cb476b063"
[[projects]]
branch = "master"
name = "go4.org"
@ -98,7 +92,7 @@
"html",
"html/atom"
]
revision = "6078986fec03a1dcc236c34816c71b0e05018fda"
revision = "b68f30494add4df6bd8ef5e82803f308e7f7c59c"
[[projects]]
branch = "master"
@ -109,6 +103,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "ff54fa52bac3cde3f10f5c237dad28da497594584e4291356b5efd040501fe4e"
inputs-digest = "cc43de082ffa9bbc96488c9bfc6659269a914a24c4ff2a04e1d43bfc66a992a4"
solver-name = "gps-cdcl"
solver-version = 1

@ -49,10 +49,6 @@
branch = "master"
name = "github.com/miguelmota/go-coinmarketcap"
[[constraint]]
branch = "master"
name = "github.com/willf/pad"
[prune]
go-tests = true
unused-packages = true

@ -2,7 +2,10 @@ all:
@echo "no default"
run:
go run cointop.go keybindings.go navigation.go sort.go
go run cointop.go keybindings.go navigation.go sort.go layout.go status.go chart.go table.go
build:
go build
build: clean
go build -ldflags "-s -w" -o bin/cointop && upx bin/cointop
clean:
go clean && rm -f bin/cointop

@ -14,6 +14,11 @@ Make sure to have [golang](https://golang.org/) installed, then do:
go install github.com/miguelmota/cointop
```
### Alternatively
```
```
## Usage
```bash

Binary file not shown.

@ -0,0 +1,84 @@
package main
import (
"fmt"
"log"
"time"
"github.com/gizak/termui"
)
func (ct *Cointop) updateChart() error {
maxX, _ := ct.g.Size()
if len(ct.chartpoints) == 0 {
ct.chartPoints(maxX, "bitcoin")
}
for i := range ct.chartpoints {
var s string
for j := range ct.chartpoints[i] {
p := ct.chartpoints[i][j]
s = fmt.Sprintf("%s%c", s, p.Ch)
}
fmt.Fprintln(ct.chartview, s)
}
return nil
}
func (ct *Cointop) chartPoints(maxX int, coin string) error {
chart := termui.NewLineChart()
chart.Height = 10
chart.AxesColor = termui.ColorWhite
chart.LineColor = termui.ColorCyan
chart.Border = false
now := time.Now()
secs := now.Unix()
start := secs - oneDay
end := secs
_ = coin
//graphData, err := cmc.GetCoinGraphData(coin, start, end)
graphData, err := ct.api.GetGlobalMarketGraphData(start, end)
if err != nil {
log.Fatal(err)
return nil
}
var data []float64
/*
for i := range graphData.PriceUSD {
data = append(data, graphData.PriceUSD[i][1])
}
*/
for i := range graphData.MarketCapByAvailableSupply {
data = append(data, graphData.MarketCapByAvailableSupply[i][1])
}
chart.Data = data
termui.Body = termui.NewGrid()
termui.Body.Width = maxX
termui.Body.AddRows(
termui.NewRow(
termui.NewCol(12, 0, chart),
),
)
var points [][]termui.Cell
// calculate layout
termui.Body.Align()
w := termui.Body.Width
h := 10
row := termui.Body.Rows[0]
b := row.Buffer()
for i := 0; i < h; i = i + 1 {
var rowpoints []termui.Cell
for j := 0; j < w; j = j + 1 {
p := b.At(j, i)
rowpoints = append(rowpoints, p)
}
points = append(points, rowpoints)
}
ct.chartpoints = points
return nil
}

@ -3,19 +3,13 @@ package main
import (
"fmt"
"log"
"os/exec"
"strconv"
"strings"
"time"
humanize "github.com/dustin/go-humanize"
"github.com/gizak/termui"
"github.com/jroimartin/gocui"
"github.com/miguelmota/cointop/apis"
apitypes "github.com/miguelmota/cointop/apis/types"
"github.com/miguelmota/cointop/color"
"github.com/miguelmota/cointop/pad"
"github.com/miguelmota/cointop/table"
"github.com/miguelmota/cointop/pkg/api"
apitypes "github.com/miguelmota/cointop/pkg/api/types"
"github.com/miguelmota/cointop/pkg/pad"
"github.com/miguelmota/cointop/pkg/table"
)
var (
@ -30,6 +24,7 @@ var (
// Cointop cointop
type Cointop struct {
g *gocui.Gui
marketview *gocui.View
chartview *gocui.View
chartpoints [][]termui.Cell
headersview *gocui.View
@ -38,81 +33,10 @@ type Cointop struct {
statusview *gocui.View
sortdesc bool
currentsort string
api apis.Interface
api api.Interface
coins []*apitypes.Coin
}
func (ct *Cointop) layout(g *gocui.Gui) error {
maxX, maxY := g.Size()
chartHeight := 10
if v, err := g.SetView("chart", 0, 0, maxX, chartHeight); err != nil {
if err != gocui.ErrUnknownView {
return err
}
ct.chartview = v
ct.chartview.Frame = false
ct.updateChart()
}
if v, err := g.SetView("header", 0, chartHeight, maxX, maxY); err != nil {
if err != gocui.ErrUnknownView {
return err
}
t := table.New().SetWidth(maxX)
headers := []string{
pad.Right("[r]ank", 13, " "),
pad.Right("[n]ame", 13, " "),
pad.Right("[s]ymbol", 8, " "),
pad.Left("[p]rice", 10, " "),
pad.Left("[m]arket cap", 17, " "),
pad.Left("24H [v]olume", 15, " "),
pad.Left("[1]H%", 9, " "),
pad.Left("[2]4H%", 9, " "),
pad.Left("[7]D%", 9, " "),
pad.Left("[t]otal supply", 20, " "),
pad.Left("[a]vailable supply", 19, " "),
pad.Left("[l]ast updated", 17, " "),
}
for _, h := range headers {
t.AddCol(h)
}
t.Format().Fprint(v)
ct.headersview = v
ct.headersview.Frame = false
ct.headersview.Highlight = true
ct.headersview.SelBgColor = gocui.ColorGreen
ct.headersview.SelFgColor = gocui.ColorBlack
}
if v, err := g.SetView("table", 0, chartHeight+1, maxX, maxY-1); err != nil {
if err != gocui.ErrUnknownView {
return err
}
ct.tableview = v
ct.tableview.Frame = false
ct.tableview.Highlight = true
ct.tableview.SelBgColor = gocui.ColorCyan
ct.tableview.SelFgColor = gocui.ColorBlack
ct.updateTable()
ct.rowChanged()
}
if v, err := g.SetView("status", 0, maxY-2, maxX, maxY); err != nil {
if err != gocui.ErrUnknownView {
return err
}
ct.statusview = v
ct.statusview.Frame = false
ct.statusview.Highlight = true
ct.statusview.SelBgColor = gocui.ColorCyan
ct.statusview.SelFgColor = gocui.ColorBlack
ct.updateStatus("")
}
return nil
}
func (ct *Cointop) rowChanged() {
ct.showLink()
}
@ -133,188 +57,13 @@ func (ct *Cointop) fetchData() ([]*apitypes.Coin, error) {
return result, nil
}
func (ct *Cointop) chartPoints(maxX int, coin string) error {
chart := termui.NewLineChart()
chart.Height = 10
chart.AxesColor = termui.ColorWhite
chart.LineColor = termui.ColorCyan
chart.Border = false
now := time.Now()
secs := now.Unix()
start := secs - oneDay
end := secs
_ = coin
//graphData, err := cmc.GetCoinGraphData(coin, start, end)
graphData, err := ct.api.GetGlobalMarketGraphData(start, end)
if err != nil {
log.Fatal(err)
return nil
}
var data []float64
/*
for i := range graphData.PriceUSD {
data = append(data, graphData.PriceUSD[i][1])
}
*/
for i := range graphData.MarketCapByAvailableSupply {
data = append(data, graphData.MarketCapByAvailableSupply[i][1])
}
chart.Data = data
termui.Body = termui.NewGrid()
termui.Body.Width = maxX
termui.Body.AddRows(
termui.NewRow(
termui.NewCol(12, 0, chart),
),
)
var points [][]termui.Cell
// calculate layout
termui.Body.Align()
w := termui.Body.Width
h := 10
row := termui.Body.Rows[0]
b := row.Buffer()
for i := 0; i < h; i = i + 1 {
var rowpoints []termui.Cell
for j := 0; j < w; j = j + 1 {
p := b.At(j, i)
rowpoints = append(rowpoints, p)
}
points = append(points, rowpoints)
}
ct.chartpoints = points
return nil
}
func (ct *Cointop) updateChart() error {
func (ct *Cointop) updateMarket() error {
maxX, _ := ct.g.Size()
if len(ct.chartpoints) == 0 {
ct.chartPoints(maxX, "bitcoin")
}
for i := range ct.chartpoints {
var s string
for j := range ct.chartpoints[i] {
p := ct.chartpoints[i][j]
s = fmt.Sprintf("%s%c", s, p.Ch)
}
fmt.Fprintln(ct.chartview, s)
}
s := "barfoo"
fmt.Fprintln(ct.marketview, pad.Right(fmt.Sprintf("[q]uit %s", s), maxX, " "))
return nil
}
func (ct *Cointop) updateTable() error {
maxX, _ := ct.g.Size()
ct.table = table.New().SetWidth(maxX)
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.HideColumHeaders = true
var err error
if len(ct.coins) == 0 {
ct.coins, err = ct.fetchData()
if err != nil {
return err
}
}
for _, coin := range ct.coins {
unix, _ := strconv.ParseInt(coin.LastUpdated, 10, 64)
lastUpdated := time.Unix(unix, 0).Format("15:04:05 Jan 02")
colorprice := color.Cyan
color1h := color.White
color24h := color.White
color7d := color.White
if coin.PercentChange1H > 0 {
color1h = color.Green
}
if coin.PercentChange1H < 0 {
color1h = color.Red
}
if coin.PercentChange24H > 0 {
color24h = color.Green
}
if coin.PercentChange24H < 0 {
color24h = color.Red
}
if coin.PercentChange7D > 0 {
color7d = color.Green
}
if coin.PercentChange7D < 0 {
color7d = color.Red
}
ct.table.AddRow(
pad.Left(fmt.Sprint(coin.Rank), 4, " "),
pad.Right(coin.Name, 22, " "),
pad.Right(coin.Symbol, 6, " "),
colorprice(pad.Left(humanize.Commaf(coin.PriceUSD), 12, " ")),
pad.Left(humanize.Commaf(coin.MarketCapUSD), 17, " "),
pad.Left(humanize.Commaf(coin.USD24HVolume), 15, " "),
color1h(pad.Left(fmt.Sprintf("%.2f%%", coin.PercentChange1H), 9, " ")),
color24h(pad.Left(fmt.Sprintf("%.2f%%", coin.PercentChange24H), 9, " ")),
color7d(pad.Left(fmt.Sprintf("%.2f%%", coin.PercentChange7D), 9, " ")),
pad.Left(humanize.Commaf(coin.TotalSupply), 20, " "),
pad.Left(humanize.Commaf(coin.AvailableSupply), 18, " "),
pad.Left(fmt.Sprintf("%s", lastUpdated), 18, " "),
// add %percent of cap
)
}
ct.table.Format().Fprint(ct.tableview)
return nil
}
func (ct *Cointop) updateStatus(s string) {
maxX, _ := ct.g.Size()
ct.statusview.Clear()
fmt.Fprintln(ct.statusview, pad.Right(fmt.Sprintf("[q]uit %s", s), maxX, " "))
}
func (ct *Cointop) showLink() {
url := ct.rowLink()
ct.g.Update(func(g *gocui.Gui) error {
ct.updateStatus(fmt.Sprintf("[enter]=%s", url))
return nil
})
}
func (ct *Cointop) enter(g *gocui.Gui, v *gocui.View) error {
exec.Command("open", ct.rowLink()).Output()
return nil
}
func (ct *Cointop) quit(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit
}
func (ct *Cointop) selectedRowIndex() int {
_, y := ct.tableview.Origin()
_, cy := ct.tableview.Cursor()
return y + cy
}
func (ct *Cointop) selectedCoin() *apitypes.Coin {
return ct.coins[ct.selectedRowIndex()]
}
func (ct *Cointop) rowLink() string {
slug := strings.ToLower(strings.Replace(ct.selectedCoin().Name, " ", "-", -1))
return fmt.Sprintf("https://coinmarketcap.com/currencies/%s", slug)
}
func main() {
g, err := gocui.NewGui(gocui.Output256)
if err != nil {
@ -324,17 +73,14 @@ func main() {
g.Cursor = true
g.Mouse = true
g.Highlight = true
ct := Cointop{
g: g,
api: apis.NewCMC(),
api: api.NewCMC(),
}
g.SetManagerFunc(ct.layout)
if err := ct.keybindings(g); err != nil {
log.Fatalf("keybindings: %v", err)
}
if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
log.Fatalf("main loop: %v", err)
}

@ -2,6 +2,7 @@ package main
import (
"log"
"os/exec"
"github.com/jroimartin/gocui"
)
@ -45,3 +46,12 @@ func (ct *Cointop) keybindings(g *gocui.Gui) error {
ct.setKeybinding(gocui.KeyEsc, ct.quit)
return nil
}
func (ct *Cointop) enter(g *gocui.Gui, v *gocui.View) error {
exec.Command("open", ct.rowLink()).Output()
return nil
}
func (ct *Cointop) quit(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit
}

@ -0,0 +1,93 @@
package main
import (
"github.com/jroimartin/gocui"
"github.com/miguelmota/cointop/pkg/pad"
"github.com/miguelmota/cointop/pkg/table"
)
func (ct *Cointop) layout(g *gocui.Gui) error {
maxX, maxY := g.Size()
chartHeight := 10
topOffset := 0
if v, err := g.SetView("market", 0, topOffset, maxX, 2); err != nil {
if err != gocui.ErrUnknownView {
return err
}
ct.marketview = v
ct.marketview.Frame = false
ct.marketview.BgColor = gocui.ColorBlack
ct.marketview.FgColor = gocui.ColorWhite
ct.updateMarket()
}
topOffset = topOffset + 1
if v, err := g.SetView("chart", 0, topOffset, maxX, topOffset+chartHeight); err != nil {
if err != gocui.ErrUnknownView {
return err
}
ct.chartview = v
ct.chartview.Frame = false
ct.updateChart()
}
topOffset = topOffset + chartHeight
if v, err := g.SetView("header", 0, topOffset, maxX, topOffset+2); err != nil {
if err != gocui.ErrUnknownView {
return err
}
t := table.New().SetWidth(maxX)
headers := []string{
pad.Right("[r]ank", 13, " "),
pad.Right("[n]ame", 13, " "),
pad.Right("[s]ymbol", 8, " "),
pad.Left("[p]rice", 10, " "),
pad.Left("[m]arket cap", 17, " "),
pad.Left("24H [v]olume", 15, " "),
pad.Left("[1]H%", 9, " "),
pad.Left("[2]4H%", 9, " "),
pad.Left("[7]D%", 9, " "),
pad.Left("[t]otal supply", 20, " "),
pad.Left("[a]vailable supply", 19, " "),
pad.Left("[l]ast updated", 17, " "),
}
for _, h := range headers {
t.AddCol(h)
}
t.Format().Fprint(v)
ct.headersview = v
ct.headersview.Frame = false
ct.headersview.Highlight = true
ct.headersview.SelBgColor = gocui.ColorGreen
ct.headersview.SelFgColor = gocui.ColorBlack
}
topOffset = topOffset + 1
if v, err := g.SetView("table", 0, topOffset, maxX, maxY-1); err != nil {
if err != gocui.ErrUnknownView {
return err
}
ct.tableview = v
ct.tableview.Frame = false
ct.tableview.Highlight = true
ct.tableview.SelBgColor = gocui.ColorCyan
ct.tableview.SelFgColor = gocui.ColorBlack
ct.updateTable()
ct.rowChanged()
}
if v, err := g.SetView("status", 0, maxY-2, maxX, maxY); err != nil {
if err != gocui.ErrUnknownView {
return err
}
ct.statusview = v
ct.statusview.Frame = false
ct.statusview.BgColor = gocui.ColorCyan
ct.statusview.FgColor = gocui.ColorBlack
ct.updateStatus("")
}
return nil
}

@ -1,7 +1,7 @@
package apis
package api
import (
cmc "github.com/miguelmota/cointop/apis/cmc"
cmc "github.com/miguelmota/cointop/pkg/api/cmc"
)
// NewCMC new CoinMarketCap api

@ -1,7 +1,7 @@
package apis
package api
import (
types "github.com/miguelmota/cointop/apis/types"
types "github.com/miguelmota/cointop/pkg/api/types"
cmc "github.com/miguelmota/go-coinmarketcap"
)

@ -1,7 +1,7 @@
package apis
package api
import (
types "github.com/miguelmota/cointop/apis/types"
types "github.com/miguelmota/cointop/pkg/api/types"
)
// Interface interface

@ -1,4 +1,4 @@
package apis
package api
// Coin struct
type Coin struct {

@ -6,7 +6,7 @@ import (
"sort"
"strings"
"github.com/miguelmota/cointop/table/align"
"github.com/miguelmota/cointop/pkg/table/align"
)
// Table table

@ -0,0 +1,22 @@
package main
import (
"fmt"
"github.com/jroimartin/gocui"
"github.com/miguelmota/cointop/pkg/pad"
)
func (ct *Cointop) updateStatus(s string) {
maxX, _ := ct.g.Size()
ct.statusview.Clear()
fmt.Fprintln(ct.statusview, pad.Right(fmt.Sprintf("[q]uit %s", s), maxX, " "))
}
func (ct *Cointop) showLink() {
url := ct.rowLink()
ct.g.Update(func(g *gocui.Gui) error {
ct.updateStatus(fmt.Sprintf("[↵]%s", url))
return nil
})
}

@ -0,0 +1,98 @@
package main
import (
"fmt"
"strconv"
"strings"
"time"
humanize "github.com/dustin/go-humanize"
apitypes "github.com/miguelmota/cointop/pkg/api/types"
"github.com/miguelmota/cointop/pkg/color"
"github.com/miguelmota/cointop/pkg/pad"
"github.com/miguelmota/cointop/pkg/table"
)
func (ct *Cointop) updateTable() error {
maxX, _ := ct.g.Size()
ct.table = table.New().SetWidth(maxX)
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.HideColumHeaders = true
var err error
if len(ct.coins) == 0 {
ct.coins, err = ct.fetchData()
if err != nil {
return err
}
}
for _, coin := range ct.coins {
unix, _ := strconv.ParseInt(coin.LastUpdated, 10, 64)
lastUpdated := time.Unix(unix, 0).Format("15:04:05 Jan 02")
colorprice := color.Cyan
color1h := color.White
color24h := color.White
color7d := color.White
if coin.PercentChange1H > 0 {
color1h = color.Green
}
if coin.PercentChange1H < 0 {
color1h = color.Red
}
if coin.PercentChange24H > 0 {
color24h = color.Green
}
if coin.PercentChange24H < 0 {
color24h = color.Red
}
if coin.PercentChange7D > 0 {
color7d = color.Green
}
if coin.PercentChange7D < 0 {
color7d = color.Red
}
ct.table.AddRow(
pad.Left(fmt.Sprint(coin.Rank), 4, " "),
pad.Right(coin.Name, 22, " "),
pad.Right(coin.Symbol, 6, " "),
colorprice(pad.Left(humanize.Commaf(coin.PriceUSD), 12, " ")),
pad.Left(humanize.Commaf(coin.MarketCapUSD), 17, " "),
pad.Left(humanize.Commaf(coin.USD24HVolume), 15, " "),
color1h(pad.Left(fmt.Sprintf("%.2f%%", coin.PercentChange1H), 9, " ")),
color24h(pad.Left(fmt.Sprintf("%.2f%%", coin.PercentChange24H), 9, " ")),
color7d(pad.Left(fmt.Sprintf("%.2f%%", coin.PercentChange7D), 9, " ")),
pad.Left(humanize.Commaf(coin.TotalSupply), 20, " "),
pad.Left(humanize.Commaf(coin.AvailableSupply), 18, " "),
pad.Left(fmt.Sprintf("%s", lastUpdated), 18, " "),
// add %percent of cap
)
}
ct.table.Format().Fprint(ct.tableview)
return nil
}
func (ct *Cointop) selectedRowIndex() int {
_, y := ct.tableview.Origin()
_, cy := ct.tableview.Cursor()
return y + cy
}
func (ct *Cointop) selectedCoin() *apitypes.Coin {
return ct.coins[ct.selectedRowIndex()]
}
func (ct *Cointop) rowLink() string {
slug := strings.ToLower(strings.Replace(ct.selectedCoin().Name, " ", "-", -1))
return fmt.Sprintf("https://coinmarketcap.com/currencies/%s", slug)
}

@ -1,5 +1,17 @@
package coinmarketcap
// Interface interface
type Interface interface {
GetGlobalMarketData() (GlobalMarketData, error)
GetGlobalMarketGraphData(start int64, end int64) (MarketGraph, error)
GetAltcoinMarketGraphData(start int64, end int64) (MarketGraph, error)
GetCoinData(coin string) (Coin, error)
GetAllCoinData(limit int) (map[string]Coin, error)
GetCoinGraphData(coin string, start int64, end int64) (CoinGraph, error)
GetCoinPriceUSD(coin string) (float64, error)
GetCoinMarkets(coin string) ([]Market, error)
}
// Coin struct
type Coin struct {
ID string `json:"id"`

@ -1,24 +0,0 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof

@ -1,2 +0,0 @@
language: go

@ -1,24 +0,0 @@
Copyright (c) 2016 Will Fitzgerald. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -1,36 +0,0 @@
pad
-------------
[![Join the chat at https://gitter.im/willf/pad](https://badges.gitter.im/willf/pad.svg)](https://gitter.im/willf/pad?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.org/willf/pad.svg?branch=master)](https://travis-ci.org/willf/pad)
A golang implementation of the [left-pad javascript library](https://www.npmjs.com/package/left-pad)
I was inspired by [Stew](https://twitter.com/StewOConnor)'s [`left-cats`](https://github.com/stew/left-cats), who was inspired by [this article](http://arstechnica.com/information-technology/2016/03/rage-quit-coder-unpublished-17-lines-of-javascript-and-broke-the-internet/), to port this to Go.
This implementation will let you pad byte-strings and UTF-8 encoded strings
example usage:
```go
package main
import (
"fmt"
"github.com/willf/pad"
padUtf8 "github.com/willf/pad/utf8"
)
func main() {
fmt.Println(pad.Right("Hello", 20, "!"))
fmt.Println(padUtf8.Left("Exit now", 20, "→"))
}
```
```bash
> go run example.go
Hello!!!!!!!!!!!!!!!
→→→→→→→→→→→→Exit now
```

@ -1,24 +0,0 @@
/*
Package pad provides left-padding functionality
*/
package pad
func times(str string, n int) (out string) {
for i := 0; i < n; i++ {
out += str
}
return
}
// Left left-pads the string with pad up to len runes
// len may be exceeded if
func Left(str string, length int, pad string) string {
return times(pad, length-len(str)) + str
}
// Right right-pads the string with pad up to len runes
func Right(str string, length int, pad string) string {
return str + times(pad, length-len(str))
}
Loading…
Cancel
Save