Skip to content

Commit

Permalink
Improve http/reader/writer; add net package; procs support vars
Browse files Browse the repository at this point in the history
  • Loading branch information
vladimirvivien committed Dec 29, 2023
1 parent d55c730 commit 72d2cd4
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 63 deletions.
5 changes: 5 additions & 0 deletions exec/proc.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,3 +315,8 @@ func (p *Proc) GetErrorPipe() io.Reader {
func (p *Proc) hasStarted() bool {
return (p.cmd.Process != nil && p.cmd.Process.Pid != 0)
}

// Parse parses the command string and returns its tokens
func Parse(cmd string) ([]string, error) {
return parse(cmd)
}
5 changes: 5 additions & 0 deletions fs/file_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ func (fw *FileWriter) SetVars(variables *vars.Variables) *FileWriter {
return fw
}

func (fw *FileWriter) WithMode(mode os.FileMode) *FileWriter {
fw.mode = mode
return fw
}

// Err returns FileWriter error during execution
func (fw *FileWriter) Err() error {
return fw.err
Expand Down
116 changes: 56 additions & 60 deletions http/http_reader.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package http

import (
"io"
"net/http"
"time"

"github.com/vladimirvivien/gexe/fs"
"github.com/vladimirvivien/gexe/vars"
)

Expand All @@ -13,7 +12,6 @@ type ResourceReader struct {
client *http.Client
err error
url string
res *Response
vars *vars.Variables
}

Expand All @@ -40,73 +38,71 @@ func (r *ResourceReader) Err() error {
return r.err
}

// Response returns the server's response info
func (r *ResourceReader) Response() *Response {
return r.res
// WithTimeout sets the HTTP reader's timeout
func (r *ResourceReader) WithTimeout(to time.Duration) *ResourceReader {
r.client.Timeout = to
return r
}

// Bytes returns the server response as a []byte
func (r *ResourceReader) Bytes() []byte {
if err := r.Do().Err(); err != nil {
r.err = err
return nil
}
return r.read()
}
// // Bytes returns the server response as a []byte
// func (r *ResourceReader) Bytes() []byte {
// if err := r.Do().Err(); err != nil {
// r.err = err
// return nil
// }
// return r.read()
// }

// String returns the server response as a string
func (r *ResourceReader) String() string {
if err := r.Do().Err(); err != nil {
r.err = err
return ""
}
return string(r.read())
}
// // String returns the server response as a string
// func (r *ResourceReader) String() string {
// if err := r.Do().Err(); err != nil {
// r.err = err
// return ""
// }
// return string(r.read())
// }

// Body returns an io.ReadCloser to stream the server response.
// NOTE: ensure to close the stream when finished.
func (r *ResourceReader) Body() io.ReadCloser {
if err := r.Do().Err(); err != nil {
r.err = err
return nil
}
return r.res.body
}
// // Body returns an io.ReadCloser to stream the server response.
// // NOTE: ensure to close the stream when finished.
// func (r *ResourceReader) Body() io.ReadCloser {
// if err := r.Do().Err(); err != nil {
// r.err = err
// return nil
// }
// return r.res.body
// }

// Do invokes the client.Get to "GET" the content from server
func (r *ResourceReader) Do() *ResourceReader {
func (r *ResourceReader) Do() *Response {
res, err := r.client.Get(r.url)
if err != nil {
r.err = err
r.res = &Response{}
return r
return &Response{err: err}
}
r.res = &Response{stat: res.Status, statCode: res.StatusCode, body: res.Body}
return r
return &Response{stat: res.Status, statCode: res.StatusCode, body: res.Body}
}

func (r *ResourceReader) WriteFile(fileName string) error {
fileName = r.vars.Eval(fileName)
if err := r.Do().Err(); err != nil {
return err
}
if err := fs.Write(fileName).From(r.Body()).Err(); err != nil {
return err
}
return nil
}
// func (r *ResourceReader) WriteFile(fileName string) error {
// fileName = r.vars.Eval(fileName)
// if err := r.Do().Err(); err != nil {
// return err
// }
// if err := fs.Write(fileName).WithMode(0766).From(r.Body()).Err(); err != nil {
// return err
// }
// return nil
// }

// read reads the content of the response body and returns a []byte
func (r *ResourceReader) read() []byte {
if r.res.body == nil {
return nil
}
// // read reads the content of the response body and returns a []byte
// func (r *ResourceReader) read() []byte {
// if r.res.body == nil {
// return nil
// }

data, err := io.ReadAll(r.res.body)
defer r.res.body.Close()
if err != nil {
r.err = err
return nil
}
return data
}
// data, err := io.ReadAll(r.res.body)
// defer r.res.body.Close()
// if err != nil {
// r.err = err
// return nil
// }
// return data
// }
5 changes: 2 additions & 3 deletions http/http_reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,8 @@ func TestHttpReader_Do(t *testing.T) {
t.Fatal("unexpected server response length: ", dataLen)
}

res := r.Response()
if res.StatusCode() != test.status {
t.Fatal("got unexpected status code: ", res.StatusCode())
if r.StatusCode() != test.status {
t.Fatal("got unexpected status code: ", r.StatusCode())
}
})
}
Expand Down
31 changes: 31 additions & 0 deletions http/http_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ type Response struct {
stat string
statCode int
body io.ReadCloser
err error
}

// Status returns the standard lib http.Response.Status value from the server
Expand All @@ -24,3 +25,33 @@ func (res *Response) StatusCode() int {
func (res *Response) Body() io.ReadCloser {
return res.body
}

// Err returns the response known error
func (r *Response) Err() error {
return r.err
}

// Bytes returns the server response as a []byte
func (r *Response) Bytes() []byte {
return r.read()
}

// String returns the server response as a string
func (r *Response) String() string {
return string(r.read())
}

// read reads the content of the response body and returns as []byte
func (r *Response) read() []byte {
if r.body == nil {
return nil
}

data, err := io.ReadAll(r.body)
defer r.body.Close()
if err != nil {
r.err = err
return nil
}
return data
}
7 changes: 7 additions & 0 deletions http/http_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"
"net/url"
"strings"
"time"

"github.com/vladimirvivien/gexe/vars"
)
Expand Down Expand Up @@ -39,6 +40,12 @@ func (w *ResourceWriter) SetVars(variables *vars.Variables) *ResourceWriter {
return w
}

// WithTimeout sets the HTTP client's timeout
func (w *ResourceWriter) WithTimeout(to time.Duration) *ResourceWriter {
w.client.Timeout = to
return w
}

// Err returns the last known error for the post operation
func (w *ResourceWriter) Err() error {
return w.err
Expand Down
9 changes: 9 additions & 0 deletions net.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package gexe

import (
"github.com/vladimirvivien/gexe/net"
)

func (e *Echo) AddressUsable(addr string) error {
return net.AddrUsable(e.Eval(addr))
}
29 changes: 29 additions & 0 deletions net/listener.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package net

import (
"errors"
"fmt"
"net"
"os"
"syscall"
)

func AddrUsable(address string) error {
addr, err := net.ResolveTCPAddr("tcp", address)
if err != nil {
return fmt.Errorf("net: address parsing: %s", err)
}

lsnr, err := net.Listen(addr.Network(), addr.String())

if err != nil {
sysErr, ok := err.(*os.SyscallError)
if ok && errors.Is(sysErr.Err, syscall.EADDRINUSE) {
return fmt.Errorf("net: addr in use: %s", sysErr.Err)
}
return fmt.Errorf("net: %s", err)
}

defer lsnr.Close()
return nil
}
11 changes: 11 additions & 0 deletions procs.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,14 @@ func (e *Echo) RunConcur(cmdStrs ...string) *exec.CommandResult {
func (e *Echo) Pipe(cmdStrs ...string) *exec.PipedCommandResult {
return exec.CommandsWithVars(e.vars, cmdStrs...).Pipe()
}

// ParseCommand parses the string into individual command tokens
func (e *Echo) ParseCommand(cmdStr string) (cmdName string, args []string) {
result, err := exec.Parse(e.vars.Eval(cmdStr))
if err != nil {
e.err = err
}
cmdName = result[0]
args = result[1:]
return
}

0 comments on commit 72d2cd4

Please sign in to comment.