add FileExists
Some checks failed
Lint / golangci-lint (push) Successful in 9m40s
Declarative Tests / test (push) Failing after 15s
Declarative Tests / build-fedora (push) Successful in 1m58s
Declarative Tests / build-ubuntu-focal (push) Successful in 1m15s

This commit is contained in:
Matthew Rich 2024-07-17 01:19:55 -07:00
parent ba19115390
commit 2c9e178554
6 changed files with 231 additions and 7 deletions

View File

@ -0,0 +1,116 @@
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
package transport
import (
_ "errors"
"path/filepath"
"io"
"os"
"net/url"
"strings"
"fmt"
"compress/gzip"
)
type Buffer struct {
uri *url.URL
path string
exttype string
fileext string
readHandle *os.File
writeHandle *os.File
gzip bool
gzipWriter io.WriteCloser
gzipReader io.ReadCloser
}
func NewBuffer(u *url.URL) (b *Buffer, err error) {
b = &Buffer{
uri: u,
path: filepath.Join(u.Hostname(), u.RequestURI()),
}
b.extension()
b.DetectGzip()
if b.path == "" || b.path == "-" {
b.readHandle = os.Stdin
b.writeHandle = os.Stdout
} else {
if b.readHandle, err = os.OpenFile(b.Path(), os.O_RDWR|os.O_CREATE, 0644); err != nil {
return
}
b.writeHandle = b.readHandle
}
if b.Gzip() {
b.gzipWriter = gzip.NewWriter(b.writeHandle)
if b.gzipReader, err = gzip.NewReader(b.readHandle); err != nil {
return
}
}
return
}
func (b *Buffer) extension() {
elements := strings.Split(b.path, ".")
numberOfElements := len(elements)
if numberOfElements > 2 {
b.exttype = elements[numberOfElements - 2]
b.fileext = elements[numberOfElements - 1]
}
b.exttype = elements[numberOfElements - 1]
}
func (b *Buffer) DetectGzip() {
b.gzip = (b.uri.Query().Get("gzip") == "true" || b.fileext == "gz")
}
func (b *Buffer) URI() *url.URL {
return b.uri
}
func (b *Buffer) Path() string {
return b.path
}
func (b *Buffer) Signature() (documentSignature string) {
if signatureResp, signatureErr := os.Open(fmt.Sprintf("%s.sig", b.uri.String())); signatureErr == nil {
defer signatureResp.Close()
readSignatureBody, readSignatureErr := io.ReadAll(signatureResp)
if readSignatureErr == nil {
documentSignature = string(readSignatureBody)
} else {
panic(readSignatureErr)
}
} else {
panic(signatureErr)
}
return documentSignature
}
func (b *Buffer) ContentType() string {
return b.exttype
}
func (b *Buffer) SetGzip(gzip bool) {
b.gzip = gzip
}
func (b *Buffer) Gzip() bool {
return b.gzip
}
func (b *Buffer) Reader() io.ReadCloser {
if b.Gzip() {
return b.gzipReader
}
return b.readHandle
}
func (b *Buffer) Writer() io.WriteCloser {
if b.Gzip() {
return b.gzipWriter
}
return b.writeHandle
}

View File

@ -0,0 +1,39 @@
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
package transport
import (
"github.com/stretchr/testify/assert"
"testing"
"fmt"
"os"
"net/url"
"path/filepath"
)
var TransportBufferTestFile = fmt.Sprintf("%s/foo", TempDir)
func TestNewTransportBufferReader(t *testing.T) {
path := fmt.Sprintf("%s/foo", TempDir)
u, e := url.Parse(fmt.Sprintf("file://%s", path))
assert.Nil(t, e)
writeErr := os.WriteFile(path, []byte("test"), 0644)
assert.Nil(t, writeErr)
file, err := NewBuffer(u)
assert.Nil(t, err)
assert.Equal(t, file.Path(), path)
}
func TestNewTransportBufferReaderExtension(t *testing.T) {
u, e := url.Parse(fmt.Sprintf("file://%s.yaml", TransportBufferTestFile))
assert.Nil(t, e)
b := &Buffer{
uri: u,
path: filepath.Join(u.Hostname(), u.RequestURI()),
}
b.extension()
assert.Equal(t, b.exttype, "yaml")
}

View File

@ -25,10 +25,19 @@ type File struct {
gzipReader io.ReadCloser gzipReader io.ReadCloser
} }
func FilePath(u *url.URL) string {
return filepath.Join(u.Hostname(), u.RequestURI())
}
func FileExists(u *url.URL) bool {
_, err := os.Stat(FilePath(u))
return err == nil
}
func NewFile(u *url.URL) (f *File, err error) { func NewFile(u *url.URL) (f *File, err error) {
f = &File { f = &File {
uri: u, uri: u,
path: filepath.Join(u.Hostname(), u.RequestURI()), path: FilePath(u),
} }
f.extension() f.extension()
f.DetectGzip() f.DetectGzip()
@ -55,12 +64,14 @@ func NewFile(u *url.URL) (f *File, err error) {
func (f *File) extension() { func (f *File) extension() {
elements := strings.Split(f.path, ".") elements := strings.Split(f.path, ".")
numberOfElements := len(elements) numberOfElements := len(elements)
if numberOfElements > 1 {
if numberOfElements > 2 { if numberOfElements > 2 {
f.exttype = elements[numberOfElements - 2] f.exttype = elements[numberOfElements - 2]
f.fileext = elements[numberOfElements - 1] f.fileext = elements[numberOfElements - 1]
} }
f.exttype = elements[numberOfElements - 1] f.exttype = elements[numberOfElements - 1]
} }
}
func (f *File) DetectGzip() { func (f *File) DetectGzip() {
f.gzip = (f.uri.Query().Get("gzip") == "true" || f.fileext == "gz") f.gzip = (f.uri.Query().Get("gzip") == "true" || f.fileext == "gz")
@ -90,6 +101,9 @@ func (f *File) Signature() (documentSignature string) {
} }
func (f *File) ContentType() string { func (f *File) ContentType() string {
if f.uri.Scheme != "file" {
return f.uri.Scheme
}
return f.exttype return f.exttype
} }

View File

@ -33,6 +33,10 @@ type HTTP struct {
Client *http.Client Client *http.Client
} }
func HTTPExists(u *url.URL) bool {
return false
}
func (b BufferCloser) Close() error { func (b BufferCloser) Close() error {
if b.stream != nil { if b.stream != nil {
return b.stream.Close() return b.stream.Close()

View File

@ -27,6 +27,7 @@ type Reader struct {
uri *url.URL uri *url.URL
handle Handler handle Handler
stream io.ReadCloser stream io.ReadCloser
exists func() bool
} }
func NewReader(u *url.URL) (reader *Reader, e error) { func NewReader(u *url.URL) (reader *Reader, e error) {
@ -39,8 +40,9 @@ func NewReader(u *url.URL) (reader *Reader, e error) {
fallthrough fallthrough
default: default:
reader.handle, e = NewFile(u) reader.handle, e = NewFile(u)
reader.exists = func() bool { return FileExists(u) }
} }
reader.stream = reader.handle.Reader() reader.SetStream(reader.handle.Reader())
return return
} }
@ -56,6 +58,7 @@ type Writer struct {
uri *url.URL uri *url.URL
handle Handler handle Handler
stream io.WriteCloser stream io.WriteCloser
exists func() bool
} }
func NewWriter(u *url.URL) (writer *Writer, e error) { func NewWriter(u *url.URL) (writer *Writer, e error) {
@ -68,8 +71,9 @@ func NewWriter(u *url.URL) (writer *Writer, e error) {
fallthrough fallthrough
default: default:
writer.handle, e = NewFile(u) writer.handle, e = NewFile(u)
writer.exists = func() bool { return FileExists(u) }
} }
writer.stream = writer.handle.Writer() writer.SetStream(writer.handle.Writer())
return writer, e return writer, e
} }
@ -81,6 +85,25 @@ func NewWriterURI(uri string) (writer *Writer, e error) {
return return
} }
func ExistsURI(uri string) bool {
var u *url.URL
u, _ = url.Parse(uri)
return Exists(u)
}
func Exists(u *url.URL) bool {
switch u.Scheme {
case "http", "https":
return HTTPExists(u)
case "file":
fallthrough
default:
return FileExists(u)
}
}
func (r *Reader) Exists() bool { return r.exists() }
func (r *Reader) Read(b []byte) (int, error) { func (r *Reader) Read(b []byte) (int, error) {
return r.stream.Read(b) return r.stream.Read(b)
} }
@ -101,8 +124,13 @@ func (r *Reader) Signature() string {
return r.handle.Signature() return r.handle.Signature()
} }
func (r *Reader) SetStream(s io.ReadCloser) {
r.stream = s
}
func (w *Writer) Exists() bool { return w.exists() }
func (w *Writer) Write(b []byte) (int, error) { func (w *Writer) Write(b []byte) (int, error) {
return w.stream.Write(b) return w.stream.Write(b)
} }
@ -122,3 +150,7 @@ func (w *Writer) Gzip() bool {
func (w *Writer) Signature() string { func (w *Writer) Signature() string {
return w.handle.Signature() return w.handle.Signature()
} }
func (w *Writer) SetStream(s io.WriteCloser) {
w.stream = s
}

View File

@ -52,13 +52,32 @@ func TestTransportReaderContentType(t *testing.T) {
u, e := url.Parse(fmt.Sprintf("file://%s", path)) u, e := url.Parse(fmt.Sprintf("file://%s", path))
assert.Nil(t, e) assert.Nil(t, e)
assert.False(t, Exists(u))
writeErr := os.WriteFile(path, []byte(testFileResourceDoc), 0644) writeErr := os.WriteFile(path, []byte(testFileResourceDoc), 0644)
assert.Nil(t, writeErr) assert.Nil(t, writeErr)
reader, err := NewReader(u) reader, err := NewReader(u)
assert.Nil(t, err) assert.Nil(t, err)
assert.True(t, reader.Exists())
assert.NotNil(t, reader) assert.NotNil(t, reader)
assert.Equal(t, reader.ContentType(), "yaml") assert.Equal(t, reader.ContentType(), "yaml")
} }
func TestTransportWriter(t *testing.T) {
path := fmt.Sprintf("%s/writefoo", TempDir)
u, e := url.Parse(fmt.Sprintf("file://%s", path))
assert.Nil(t, e)
assert.False(t, Exists(u))
writer, err := NewWriter(u)
assert.Nil(t, err)
defer writer.Close()
assert.NotNil(t, writer)
assert.True(t, writer.Exists())
_, writeErr := writer.Write([]byte("testdata"))
assert.Nil(t, writeErr)
assert.FileExists(t, path)
}