feat: add file input flag (#12)
## Description The lambda CLI previously only supported inline string expressions and stdin input. This PR adds support for reading lambda expressions from files using the `-f` flag. This makes it easier to work with larger programs stored in files. Changes: - Added `FileSource` type to `internal/config/source.go` for reading from file paths. - Added `-f` flag to CLI argument parser with validation to prevent conflicting inputs. - Updated Makefile targets (`run`, `profile`, `explain`) to use `-f` flag instead of stdin redirection. ### Decisions The `-f` flag takes precedence over positional arguments. If both are specified, an error is returned to avoid ambiguity. ## Benefits - More intuitive workflow for file-based lambda programs. - Cleaner Makefile targets without stdin redirection. - Consistent with common CLI conventions (e.g., `grep -f`, `awk -f`). ## Checklist - [x] Code follows conventional commit format. - [x] Branch follows naming convention (`<type>/<description>`). - [ ] Tests pass (if applicable). - [ ] Documentation updated (if applicable). Reviewed-on: #12 Co-authored-by: M.V. Hutz <git@maximhutz.me> Co-committed-by: M.V. Hutz <git@maximhutz.me>
This commit was merged in pull request #12.
This commit is contained in:
6
Makefile
6
Makefile
@@ -20,13 +20,13 @@ build:
|
||||
chmod +x ${BINARY_NAME}
|
||||
|
||||
run: build
|
||||
./${BINARY_NAME} - < ./samples/$(TEST).txt > program.out
|
||||
./${BINARY_NAME} -f ./samples/$(TEST).txt > program.out
|
||||
|
||||
profile: build
|
||||
./${BINARY_NAME} -p profile/cpu.prof - < ./samples/$(TEST).txt > program.out
|
||||
./${BINARY_NAME} -p profile/cpu.prof -f ./samples/$(TEST).txt > program.out
|
||||
|
||||
explain: build
|
||||
./${BINARY_NAME} -x -p profile/cpu.prof - < ./samples/$(TEST).txt > program.out
|
||||
./${BINARY_NAME} -x -p profile/cpu.prof -f ./samples/$(TEST).txt > program.out
|
||||
|
||||
graph:
|
||||
go tool pprof -raw -output=profile/cpu.raw profile/cpu.prof
|
||||
|
||||
@@ -12,21 +12,28 @@ func FromArgs() (*Config, error) {
|
||||
explanation := flag.Bool("x", false, "Explanation. Whether or not to show all reduction steps.")
|
||||
statistics := flag.Bool("s", false, "Statistics. If set, the process will print various statistics about the run.")
|
||||
profile := flag.String("p", "", "CPU profiling. If an output file is defined, the program will profile its execution and dump its results into it.")
|
||||
file := flag.String("f", "", "File. If set, read source from the specified file.")
|
||||
flag.Parse()
|
||||
|
||||
// There must only be one input argument.
|
||||
if flag.NArg() == 0 {
|
||||
return nil, fmt.Errorf("no input given")
|
||||
} else if flag.NArg() > 1 {
|
||||
return nil, fmt.Errorf("more than 1 command-line argument")
|
||||
}
|
||||
|
||||
// Parse source type.
|
||||
var source Source
|
||||
if flag.Arg(0) == "-" {
|
||||
source = StdinSource{}
|
||||
if *file != "" {
|
||||
// File flag takes precedence.
|
||||
if flag.NArg() > 0 {
|
||||
return nil, fmt.Errorf("cannot specify both -f flag and positional argument")
|
||||
}
|
||||
source = FileSource{Path: *file}
|
||||
} else if flag.NArg() == 0 {
|
||||
return nil, fmt.Errorf("no input given")
|
||||
} else if flag.NArg() > 1 {
|
||||
return nil, fmt.Errorf("more than 1 command-line argument")
|
||||
} else {
|
||||
source = StringSource{Data: flag.Arg(0)}
|
||||
// Positional argument.
|
||||
if flag.Arg(0) == "-" {
|
||||
source = StdinSource{}
|
||||
} else {
|
||||
source = StringSource{Data: flag.Arg(0)}
|
||||
}
|
||||
}
|
||||
|
||||
return &Config{
|
||||
|
||||
@@ -27,3 +27,15 @@ func (s StdinSource) Extract() (string, error) {
|
||||
|
||||
return string(data), nil
|
||||
}
|
||||
|
||||
// A source reading from a file.
|
||||
type FileSource struct{ Path string }
|
||||
|
||||
func (s FileSource) Extract() (string, error) {
|
||||
data, err := os.ReadFile(s.Path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(data), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user