Skip to content

Commit

Permalink
Add context support in the commands (#37)
Browse files Browse the repository at this point in the history
* Add context support in the commands

* Add more test cases

* Upload test coverage to codecov.io
  • Loading branch information
LinuxSuRen authored Aug 27, 2021
1 parent 42825a0 commit 255c95a
Show file tree
Hide file tree
Showing 11 changed files with 244 additions and 37 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/coverage-report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,11 @@ jobs:
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
run: |
bash <(curl -Ls https://coverage.codacy.com/get.sh) report -r coverage.out --force-coverage-parser go
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: coverage.out
flags: unittests
name: codecov-umbrella
fail_ci_if_error: true
4 changes: 2 additions & 2 deletions cmd/fetch.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package cmd

import (
"context"
"fmt"
"github.com/linuxsuren/http-downloader/pkg/installer"
"github.com/spf13/cobra"
"os"
)

func newFetchCmd() (cmd *cobra.Command) {
func newFetchCmd(context.Context) (cmd *cobra.Command) {
opt := &fetchOption{}

cmd = &cobra.Command{
Use: "fetch",
Short: "Fetch the latest hd config",
Expand Down
11 changes: 8 additions & 3 deletions cmd/get.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
package cmd

import (
"context"
"fmt"
"github.com/linuxsuren/http-downloader/pkg"
"github.com/linuxsuren/http-downloader/pkg/installer"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
"net/http"
"net/url"
"path"
"runtime"
"strings"
)

// NewGetCmd return the get command
func NewGetCmd() (cmd *cobra.Command) {
opt := &downloadOption{}
// newGetCmd return the get command
func newGetCmd(ctx context.Context) (cmd *cobra.Command) {
opt := &downloadOption{
RoundTripper: *getRoundTripper(ctx),
}
cmd = &cobra.Command{
Use: "get",
Short: "download the file",
Expand Down Expand Up @@ -59,6 +63,7 @@ type downloadOption struct {
Timeout int
MaxAttempts int
AcceptPreRelease bool
RoundTripper http.RoundTripper

ContinueAt int64

Expand Down
11 changes: 8 additions & 3 deletions cmd/install.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package cmd

import (
"context"
"github.com/linuxsuren/http-downloader/pkg/installer"
"github.com/linuxsuren/http-downloader/pkg/os"
"github.com/spf13/cobra"
"runtime"
)

// NewInstallCmd returns the install command
func NewInstallCmd() (cmd *cobra.Command) {
opt := &installOption{}
// newInstallCmd returns the install command
func newInstallCmd(ctx context.Context) (cmd *cobra.Command) {
opt := &installOption{
downloadOption: downloadOption{
RoundTripper: *getRoundTripper(ctx),
},
}
cmd = &cobra.Command{
Use: "install",
Short: "Install a package from https://github.com/LinuxSuRen/hd-home",
Expand Down
5 changes: 3 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package cmd

import (
"context"
extver "github.com/linuxsuren/cobra-extension/version"
"github.com/spf13/cobra"
)

// NewRoot returns the root command
func NewRoot() (cmd *cobra.Command) {
func NewRoot(cxt context.Context) (cmd *cobra.Command) {
cmd = &cobra.Command{
Use: "hd",
Short: "HTTP download tool",
}

cmd.AddCommand(
NewGetCmd(), NewInstallCmd(), newFetchCmd(), newSearchCmd(), newTestCmd(),
newGetCmd(cxt), newInstallCmd(cxt), newFetchCmd(cxt), newSearchCmd(cxt), newTestCmd(),
extver.NewVersionCmd("linuxsuren", "http-downloader", "hd", nil))
return
}
3 changes: 2 additions & 1 deletion cmd/search.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"context"
"fmt"
"github.com/linuxsuren/http-downloader/pkg/installer"
"github.com/spf13/cobra"
Expand All @@ -9,7 +10,7 @@ import (
"strings"
)

func newSearchCmd() (cmd *cobra.Command) {
func newSearchCmd(context.Context) (cmd *cobra.Command) {
cmd = &cobra.Command{
Use: "search",
Short: "Search packages from the hd config repo",
Expand Down
103 changes: 103 additions & 0 deletions cmd/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package cmd

import (
"context"
"io"
"net/http"
"os"
"os/exec"
"sync"
)

func getOrDefault(key, def string, data map[string]string) (result string) {
var ok bool
if result, ok = data[key]; !ok {
result = def
}
return
}

func getReplacement(key string, data map[string]string) (result string) {
return getOrDefault(key, key, data)
}

func getRoundTripper(ctx context.Context) (tripper *http.RoundTripper) {
roundTripper := ctx.Value("roundTripper")

var ok bool
if tripper, ok = roundTripper.(*http.RoundTripper); ok {
tripper = nil
}
return
}

func pathExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}

func execCommandInDir(name, dir string, arg ...string) (err error) {
command := exec.Command(name, arg...)
if dir != "" {
command.Dir = dir
}

//var stdout []byte
//var errStdout error
stdoutIn, _ := command.StdoutPipe()
stderrIn, _ := command.StderrPipe()
err = command.Start()
if err != nil {
return err
}

// cmd.Wait() should be called only after we finish reading
// from stdoutIn and stderrIn.
// wg ensures that we finish
var wg sync.WaitGroup
wg.Add(1)
go func() {
_, _ = copyAndCapture(os.Stdout, stdoutIn)
wg.Done()
}()

_, _ = copyAndCapture(os.Stderr, stderrIn)

wg.Wait()

err = command.Wait()
return
}

func execCommand(name string, arg ...string) (err error) {
return execCommandInDir(name, "", arg...)
}

func copyAndCapture(w io.Writer, r io.Reader) ([]byte, error) {
var out []byte
buf := make([]byte, 1024, 1024)
for {
n, err := r.Read(buf[:])
if n > 0 {
d := buf[:n]
out = append(out, d...)
_, err := w.Write(d)
if err != nil {
return out, err
}
}
if err != nil {
// Read returns io.EOF at the end of file, which is not an error for us
if err == io.EOF {
err = nil
}
return out, err
}
}
}
3 changes: 2 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package main

import (
"context"
"github.com/linuxsuren/http-downloader/cmd"
"os"
)

func main() {
if err := cmd.NewRoot().Execute(); err != nil {
if err := cmd.NewRoot(context.TODO()).Execute(); err != nil {
os.Exit(1)
}
}
16 changes: 16 additions & 0 deletions pkg/net/error_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package net_test

import (
"github.com/linuxsuren/http-downloader/pkg/net"
"github.com/stretchr/testify/assert"
"testing"
)

func TestError(t *testing.T) {
err := net.DownloadError{
Message: "message",
StatusCode: 200,
}
assert.Contains(t, err.Error(), "message")
assert.Contains(t, err.Error(), "200")
}
Loading

0 comments on commit 255c95a

Please sign in to comment.