script

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 31, 2025 License: MIT Imports: 9 Imported by: 0

README

package script

This package is intended as a collection of helper functions and tools fow quick construction of scripts that process .csv tables.

Note that this is a work in progress. API is not guaranteed to be stable.

Example usage

This demonstrates a very basic case: reading from stdin, checking whether array len is 2 and switching array elements.

package main

import (
	"context"
	"errors"
	"fmt"
	"os/signal"
	"syscall"

	"code.uint32.ru/dmitry/script"
)

func main() {
	ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGTERM, syscall.SIGINT)
	defer stop()

	reader := script.NewStdinReader()
	writer := script.NewStdoutWriter()

	processor := func(_ context.Context, in []string) ([]string, error) {
		if len(in) != 2 {
			return nil, errors.New("incorrect input len")
		}

		return []string{in[1], in[0]}, nil
	}

	conf := script.RunConfig{
		Input:     reader,
		Output:    writer,
		Processor: processor,
	}

	if err := script.Run(ctx, conf); err != nil {
		fmt.Println(err)
	}
}

A more conplicated example featuring a processor which is itself a struct with external dependency.

package main

import (
	"context"
	"fmt"
	"os/signal"
	"syscall"

	"code.uint32.ru/dmitry/script"
)

// ExternalDep represent an external dependency
// which your script utilizes. This can be a DB connection etc.
type ExternalDep interface {
	QueryID(string) ([]string, error)
}

type Processor struct {
	dep ExternalDep
}

func New(e ExternalDep) *Processor {

	return &Processor{
		dep: e,
	}
}

func (p *Processor) Process(ctx context.Context, in []string) ([]string, error) {
	var out []string

	result, err := p.dep.QueryID(in[0])
	if err != nil {
		// you can as well record the error and continue
		// processing without yielding the error here
		return nil, err
	}

	out = append(out, result...)
	out = append(out, "processed")

	return out, nil
}

func main() {
	ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGTERM, syscall.SIGINT)
	defer stop()

	r, err := script.NewCSVReader("/tmp/some_file.csv")
	if err != nil {
		panic(err)
	}

	defer func() {
		if err := r.Close(); err != nil {
			fmt.Println("err closing reader", err)
		}
	}()

	w, err := script.NewCSVWriter("/tmp/some_output.csv")
	if err != nil {
		panic(err)
	}

	defer func() {
		if err := w.Close(); err != nil {
			fmt.Println("err closing writer", err)
		}
	}()

    // intializing the processor
	p := New(ExternalDep(nil))

	conf := script.RunConfig{
		Input:     r,
		Output:    w,
		Processor: p.Process, // Process implements script.Processor
	}

	if err := script.Run(ctx, conf); err != nil {
		fmt.Println(err)
	}
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	EOF             error = io.EOF
	ErrNoProcessors       = errors.New("no processors provided")
)

Functions

func Run

func Run(ctx context.Context, r RunConfig) error

Run starts the script described by r. First Read is called offset times with output of Read being discarded. Then limit Reads are made and processor is called for each portion of data. If limit is 0 then Run keep processing input until it receives EOF from Reader. Run fails on any error including Reader error, Writer error and Processor error. If an error is encountered the writer operation will be attampted anyway so that the output is left in consistent state, recording what has been actually done by Processor.

Types

type CSVReader

type CSVReader struct {
	// contains filtered or unexported fields
}

func NewCSVReader

func NewCSVReader(filename string) (*CSVReader, error)

CSV creates csv.Reader reading from filename.

func (*CSVReader) Close

func (c *CSVReader) Close() error

func (*CSVReader) Read

func (c *CSVReader) Read() ([]string, error)

type CSVWriter

type CSVWriter struct {
	// contains filtered or unexported fields
}

func NewCSVWriter

func NewCSVWriter(filename string) (*CSVWriter, error)

CSV creates csv.Writer writing to underlying file. Do not forget to call Close method once you are done.

func (*CSVWriter) Close

func (c *CSVWriter) Close() error

Close flushes underlying csv.Writer and closes file.

func (*CSVWriter) Error

func (c *CSVWriter) Error() error

Error return last encountered error.

func (*CSVWriter) Write

func (c *CSVWriter) Write(record []string) error

Write writer row to csv. Writes are buffered

type MemReader

type MemReader struct {
	// contains filtered or unexported fields
}

func NewMemReader

func NewMemReader(records [][]string) *MemReader

func (*MemReader) Read

func (m *MemReader) Read() ([]string, error)

type MemWriter

type MemWriter struct {
	// contains filtered or unexported fields
}

func NewMemWriter

func NewMemWriter() *MemWriter

func (*MemWriter) Output

func (m *MemWriter) Output() [][]string

func (*MemWriter) Write

func (m *MemWriter) Write(record []string) error

type NopWriter

type NopWriter struct{}

func NewNopWriter

func NewNopWriter() *NopWriter

func (*NopWriter) Write

func (d *NopWriter) Write([]string) error

type Processor

type Processor func(context.Context, []string) ([]string, error)

Processor accepts string slice, does what it should and returns output. Non-nil error returned by Processor stops further processing.

type Reader

type Reader interface {
	// Read is called by Processor to obtain input
	// for processing. Read must return EOF/io.EOF to indicate
	// that there is no more input.
	Read() ([]string, error)
}

type RunConfig

type RunConfig struct {
	Input       Reader
	Output      Writer
	Processor   Processor
	Offset      int
	Limit       int
	Concurrency int
}

type StdinReader

type StdinReader struct {
	// contains filtered or unexported fields
}

StdinReader reads from stdin

func NewStdinReader

func NewStdinReader() *StdinReader

func (*StdinReader) Read

func (s *StdinReader) Read() ([]string, error)

Read reads from stdin until \n character then splits result at "," separator and returns the resulting slice. It returns EOF when nothing left to read.

type StdoutWriter

type StdoutWriter struct{}

func NewStdoutWriter

func NewStdoutWriter() *StdoutWriter

func (*StdoutWriter) Write

func (s *StdoutWriter) Write(in []string) error

type Writer

type Writer interface {
	// Write is called by Processor to record
	// output.
	Write([]string) error
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL