Skip to content

Commit

Permalink
Improved usage description, added clipboard option
Browse files Browse the repository at this point in the history
• Dgen now has a proper usage description.
• No longer dependent on github.com/pkg/errors.
• Updated README.
• Added more presets.
• Updated Makefile.
• General code improvements.
  • Loading branch information
Steven Xie committed Aug 13, 2018
1 parent 07ece01 commit 7b3067b
Show file tree
Hide file tree
Showing 33 changed files with 1,009 additions and 695 deletions.
15 changes: 9 additions & 6 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 0 additions & 4 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@
# unused-packages = true


[[constraint]]
name = "github.com/pkg/errors"
version = "0.8.0"

[prune]
go-tests = true
unused-packages = true
120 changes: 83 additions & 37 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
### Variables:
## ----- Variables -----
PKG_NAME = $(shell basename "$$(pwd)")

## Source config
Expand All @@ -10,37 +10,67 @@ TEST_TIMEOUT = 20s
COVER_OUT = coverage.out


### Commands (targets):
## ------ Commands (targets) -----
## Prevent targeting filenames...
.PHONY: default run build install all all-bench check fmt test test-v \
test-race bench
.PHONY: default run build install get update review review-race review-bench \
check fmt test test-v test-race bench

## Default target when no arguments are given to make (build and run program).
default: build run

## Builds and runs the program (package must be main).
run:
@if [ -f ".env.sh" ]; then \
printf 'Exporting environment variables by sourcing ".env.sh"... ' && \
. .env.sh && \
echo "done!"; \
fi; \
if [ -f "$(PKG_NAME)" ]; then \
echo 'Running "$(PKG_NAME)"...' && \
./$(PKG_NAME); \
else echo '[ERROR] Could not find program "$(PKG_NAME)".'; \
fi
printf 'Exporting environment variables by sourcing ".env.sh"... '; \
. .env.sh; \
echo "done."; \
fi
@if [ -f "$(PKG_NAME)" ]; then \
echo 'Running "$(PKG_NAME)"...'; \
./$(PKG_NAME); \
else echo '[ERROR] Could not find program "$(PKG_NAME)".'; \
fi

## Builds the program specified by the main package.
build:
@printf "Building... "
@go build
@printf "done!\n"
@GOBUILD_OUT="$$(go build 2>&1)"; \
if [ -n "$$GOBUILD_OUT" ]; then \
echo "\n[ERROR] Failed to build program:"; \
echo $$GOBUILD_OUT; \
else echo "done."; \
fi

install:
@printf 'Installing with "go install"... '
@go install
@echo "done!"
@GOINSTALL_OUT="$$(go install 2>&1)"; \
if [ -n "$$GOBUILD_OUT" ]; then \
echo "\n[ERROR] failed to install:"; \
echo "$$GOINSTALL_OUT"; \
else echo "done."; \
fi


## Installs package dependencies.
get:
@printf 'Installing package dependencies with "go get"... '
@GOGET_OUT="$$(go get ./... 2>&1)"; \
if [ -n "$$GOGET_OUT" ]; then \
echo "\n[ERROR] Failed to install package dependencies:"; \
echo "$$GOGET_OUT"; \
else echo "done."; \
fi

## Installs and updates package dependencies.
update:
@printf 'Installing and updating package dependencies with "go get"... '
@GOGET_OUT="$$(go get -u 2>&1)"; \
if [ -n "$$GOGET_OUT" ]; then \
echo "\n[ERROR] Failed to install package dependencies:"; \
echo "$$GOGET_OUT"; \
else echo "done."; \
fi


## Formats, checks, and tests the code.
review: fmt check test
Expand All @@ -49,35 +79,51 @@ review-race: fmt check test-race
## Like "review-race", but includes benchmarks.
review-bench: fmt check test-race bench


## Checks for formatting, linting, and suspicious code.
check:
## Check formatting...
@printf "Check format:"
@GOFMT_OUT="$(shell gofmt -l $(SRC_FILES))"; if [ -n "$$GOFMT_OUT" ]; then \
printf "\n> [WARN] Fix formatting issues in the following files with "; \
printf '"make fmt":\n$$GOFMT_OUT\n\n'; else printf " ...OK!\n"; fi
@printf "Check fmt... "
@GOFMT_OUT="$$(gofmt -l $(SRC_FILES) 2>&1)"; \
if [ -n "$$GOFMT_OUT" ]; then \
echo '\n[WARN] Fix formatting issues in the following files with \
"make fmt":'; \
echo "$$GOFMT_OUT\n"; \
else echo "ok"; \
fi
## Lint files...
@printf "Check lint:"
@GOLINT_OUT="$(shell for PKG in "$(SRC_PKGS)"; do golint $$PKG; done)"; \
if [ -n "$$GOLINT_OUT" ]; then printf "\n" && \
for PKG in "$$GOLINT_OUT"; do printf "> $$PKG\n"; done; printf "\n"; \
else printf " ...OK!\n"; fi
@printf "Check lint... "
@GOLINT_OUT="$(for PKG in "$(SRC_PKGS)"; do golint $$PKG 2>&1; done)"; \
if [ -n "$$GOLINT_OUT" ]; then \
printf "\n"; \
for PKG in "$$GOLINT_OUT"; do \
echo "$$PKG"; \
done; \
printf "\n"; \
else echo "ok"; \
fi
## Check suspicious code...
@printf "Check vet:"
@GOVET_OUT="$(shell go vet 2>&1)"; if [ -n "$$GOVET_OUT" ]; \
then printf '\n> [WARN] Fix suspicious code from "go vet":\n'; \
printf "$$GOVET_OUT\n\n"; else printf " ...OK!\n"; fi
@printf "Check vet... "
@GOVET_OUT="$$(go vet 2>&1)"; \
if [ -n "$$GOVET_OUT" ]; then \
echo '\n[WARN] Fix suspicious code from "go vet":'; \
echo "$$GOVET_OUT\n"; \
else echo "ok"; \
fi

## Reformats code according to "gofmt".
fmt:
@echo Formatting:
@GOFMT_OUT=$(shell gofmt -l -s -w $(SRC_FILES)); if [ -n "$$GOFMT_OUT" ]; \
then for FILE in "$$GOFMT_OUT"; do printf "> $$FILE\n"; done; \
else printf "> ...all files formmatted correctly!\n"; fi
@printf "Formatting source files... "
@GOFMT_OUT="$$(gofmt -l -s -w $(SRC_FILES) 2>&1)"; \
if [ -n "$$GOFMT_OUT" ]; \
then printf "\n$$GOFMT_OUT\n"; \
else echo "ok"; \
fi;

## Testing commands:
GOTEST = go test ./... -coverprofile=$(COVER_OUT) -covermode=atomic \
-timeout=$(TEST_TIMEOUT)
GOTEST = go test ./... -coverprofile=$(COVER_OUT) \
-covermode=atomic \
-timeout=$(TEST_TIMEOUT)
test:
@echo "Testing:"
@$(GOTEST)
Expand All @@ -89,4 +135,4 @@ test-race:
@$(GOTEST) -race
bench:
@echo "Benchmarking..."
@go test ./... -run=$^ -bench=. -benchmem
@go test ./... -run=^$ -bench=. -benchmem
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,63 @@ For more advanced usage options, view the help prompt with:
dgen --help
```

### Presets

`dgen` comes with several presets in order to make your life easier. Each preset
represents the character limit on the associated messaging service:

```bash
dgen "👀 " fb
# Output: 👀 👀 👀 👀 👀 👀 👀 👀 👀 (... x5000)
```

#### List of current `dgen` presets:

| Name / ID | Value | service |
| --------- | ------ | ------------------ |
| fb | 5000 | Facebook Messenger |
| twitter | 280 | Twitter |
| rpost | 40,000 | Reddit (post) |
| rcomment | 10,000 | Reddit (comment) |
| rmsg | 10,000 | Reddit (message) |

## Performance

`dgen` is one of the top-of-the-line string generators out there. `dgen v1.0.1`
sports the following benchmark:

- **Input:** "benchmark test text "
- **Repetitions:** 1,000,000
- **Duration:** 25.050 seconds
- **Milliseconds / operation:** 0.025039
- **Byte allocated / operation:** 21
- **Allocations / operation:** 0

## Integration

`dgen` is a wrapper around an internal library, `throughput`, which contains
the real repeating and buffering logic. To create a program that is able to
use `dgen`'s string dumping algorithm, simply import `throughput`:

```go
import (
"github.com/steven-xie/dgen/throughput"
"os"
)


func main() {
const (
in = "test string "
reps = 5000
bufsize = 3000
)

// Dump "test string " 5000 times into os.Stdout.
throughput.Dump(in, reps, bufsize, os.Stdout)
}
```

[godoc-img]: https://godoc.org/github.com/steven-xie/dgen?status.svg
[godoc]: https://godoc.org/github.com/steven-xie/dgen
[travis-img]: https://travis-ci.org/steven-xie/dgen.svg?branch=master
Expand Down
3 changes: 2 additions & 1 deletion args.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ func parseArgs(args []string) (str string, reps int) {

if nargs == 0 {
// Quit if no arguments were received.
fmt.Printf("Warning: Did not receive any arguments!\n\n")
errln("Warning: Did not receive any arguments!\n")
showHelp()

os.Exit(2)
}

if nargs > 2 {
// Warn the user if more arguments were received than expected.
fmt.Printf("Warning: Received more than 2 arguments. Ignoring the " +
Expand Down
5 changes: 4 additions & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ const (
var (
// Presets is a map of string identifiers to repeat counts. Identifiers
// correspond to various messaging services.
Presets = map[string]uint{"fb": 5000}
Presets = map[string]uint{
"fb": 5000, "rpost": 40000, "rcomment": 10000, "rmsg": 10000,
"twitter": 280,
}
)

func parsePreset(id string) int {
Expand Down
16 changes: 10 additions & 6 deletions flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,20 @@ import (
var (
// Opts are flag-enabled options for dgen.
Opts struct {
// Stats will show statistics at the end of the string dump.
Stats bool `short:"s" long:"stats" description:"Show statistics after string dump."`
Preserve bool `short:"p" long:"preserve" description:"Preserve whitespacing; do not add terminating newlines."`
Copy bool `short:"c" long:"copy" description:"Write dump to clipboard, rather than to standard output."`
}

fparser = flags.NewParser(&Opts, flags.Default)
fparser = makeParser()
)

func makeParser() (p *flags.Parser) {
p = flags.NewParser(&Opts, flags.Default)
p.Usage = "[OPTIONS] <string> [<repeat count> | <preset name>]"
return p
}

func showHelp() {
fparser.WriteHelp(os.Stdout)
}
Expand All @@ -43,14 +49,12 @@ func parseFlags() (args []string) {
os.Exit(4)

default:
fmt.Fprintln(os.Stderr, "Encountered flag parsing error of type:",
flagerr.Type)
errln("Encountered flag parsing error of type:", flagerr.Type)
os.Exit(4)
}
}

fmt.Fprintln(os.Stderr, "Failed to parse given flags (unknown error type):",
err)
errln("Failed to parse given flags (unknown error type):", err)
os.Exit(5)
}
return args
Expand Down
41 changes: 29 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,50 @@ package main
import (
"fmt"
"github.com/steven-xie/dgen/throughput"
"github.com/steven-xie/glip"
"io"
"os"
)

func main() {
args := parseFlags()
str, reps := parseArgs(args)

n, err := throughput.Dump(str, reps, Bufsize, os.Stdout)
// Set up output device.
var out io.Writer = os.Stdout
if Opts.Copy {
board, err := glip.NewBoard()
if err != nil {
errln("Failed to open system clipboard:", err)
os.Exit(1)
}
out = board
}

n, err := throughput.Dump(str, reps, Bufsize, out)

hasnl := hasTrailingNewline(str)
// Ensure that if extra info is about to be produced, there are at least two
// newlines before that info is printed.
if err != nil || Opts.Stats {
if hasnl {
// If wrote to os.Sdout...
if !Opts.Copy {
hasnl := hasTrailingNewline(str)

// Ensure that if extra info is about to be produced, there are at least two
// newlines before that info is printed.
if err != nil || Opts.Stats {
if hasnl {
fmt.Print("\n")
} else {
fmt.Print("\n\n")
}
} else if !Opts.Preserve && !hasnl {
fmt.Print("\n")
} else {
fmt.Print("\n\n")
}
} else if !Opts.Preserve && !hasnl {
fmt.Print("\n")
}

if err != nil {
fmt.Fprintln(os.Stderr, "Encountered error while dumping source string:",
err)
errln("Encountered error while dumping source string:", err)
os.Exit(7)
}

if Opts.Stats {
fmt.Printf("Successfully printed %d bytes.\n", n)
}
Expand Down
Loading

0 comments on commit 7b3067b

Please sign in to comment.