duct

package module
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Nov 28, 2023 License: MIT Imports: 4 Imported by: 0

README

logo

Wrap a code formatter inside of a `stdin-to-stdout` filter-like data flow

The duct program allows to wrap code formatters inside of a stdin to stdout filter-like data flow. It wraps a code formatter, which accepts file names as commands arguments instead of reading from standard input data stream, inside of a standard Unix stdin to stdout filter-like data flow. Consult the package documentation or see Usage to see how it works.

Installation

Install the package to use the command-line duct to wrap code formatters inside of a stdin to stdout filter-like data flow.

go install github.com/mdm-code/duct/cmd/duct@latest

Although I don't really see the reason why one might want to do it, use the following command to add the package to an existing project.

go get github.com/mdm-code/duct

Usage

Type duct -h to get information and examples on how to use duct and get some ideas on how to use it in your workflow.

This very basic example show how to wrap black, a code formatter for Python, with duct to use it as if it was a regular Unix data filter. Here is a snippet:

duct black -l 79 <<EOF
from typing import (
	Protocol
)
class Sized(Protocol):
	def __len__(self) -> int: ...
def print_size(s: Sized) -> None: len(s)
class Queue:
	def __len__(self) -> int: return 10
q = Queue(); print_size(q)
EOF

The example uses heredoc to direct code to standard input of duct that is going to be formatter with black with the max line length set to 79 characters. The output is going to be written to stdout accordingly. This lets you use black in vim as if it was a regular filter command, which makes life much easier for a regular Python dev.

In case the wrapped command writes the formatted code output to stdout or stderr, duct has two flags -stdout and -stderr that attach them to the wrapped command instead of redirecting the whole R/W flow through a temporary file.

Development

Consult Makefile to see how to format, examine code with go vet, run unit test, run code linter with golint in order to get test coverage and check if the package builds all right.

Remember to install golint before you try to run tests and test the build:

go install golang.org/x/lint/golint@latest

License

Copyright (c) 2023 Michał Adamczyk.

This project is licensed under the MIT license. See LICENSE for more details.

Documentation

Overview

Package duct provides the internals for the duct command-line program wrapping code formatters that do not read from standard input data stream, and instead they take file names as command arguments. The package offers components that allow such commands to be wrapped inside of a standard Unix stdin to stdout filter-like data flow.

The general idea is that input data read from standard input is written to an intermediate temporary file. The name of the file gets passed to as one of the positional arguments of the named program to be executed. The modified contents of the file are then re-read and written out the standard output. This way the wrapped program can be used as a regular Unix filter.

Some code formatters take file names but do not modify files directly. Instead they write the formatted code to stdout or stderr. This scenario is supported by a the WrapWrite function that writes code from stdin to the temporary file but relies on the command's own stdout and/or stderr to write out the output.

Index

Constants

View Source
const Pattern = `duct-*`

Pattern defines the name pattern for the temporary file.

Variables

View Source
var Discard discard

Discard is a WriteCloser that does nothing when either Write or Close methods are invoked. Ever call succeeds.

View Source
var NilFDError error = errors.New("nil file descriptor")

NilFDError indicates that a file descriptor for read/write operation is nil.

Functions

func Cmd

func Cmd(name string, stdout, stderr io.Writer, args ...string) *exec.Cmd

Cmd returns the Cmd stuct to execute a given named program with given arguments and file descriptors attached.

func Wrap

func Wrap(cmd Runner, fds *FDs) error

Wrap executes a given named formatter program cmd and a set of fds file descriptors.

Code to be formatted is being read from the fds.Stdin and written to fds.Stdout with fds.TempFile read/write functioning as an intermediate step necessitated by the design of the CLI interface of the formatter.

func WrapWriteOnly added in v1.3.0

func WrapWriteOnly(cmd Runner, fds *FDs) error

WrapWriteOnly executes the provided named formatter program wrapping the temporary file write operation.

Code to be formatted is read from the fds.Stdin and written to fds.TempFile to allow the wrapped command to read code from the temporary file and handle its output using the command's own stdout and/or stderr.

Types

type FDs

type FDs struct {
	Stdin          io.ReadCloser
	Stdout, Stderr io.WriteCloser
	TempFile       ReadWriteSeekCloser
}

FDs groups file descriptors used in the process of shell command wrapping.

func NewFDs

func NewFDs(stdin io.ReadCloser, stdout, stderr io.WriteCloser, tempFile ReadWriteSeekCloser) (*FDs, func() error)

NewFDs groups file descriptors passed as function arguments in a single struct.

The closer method returned alongside the struct should be deferred to ensure that all files are closed upon the termination of the program.

func (*FDs) Close

func (f *FDs) Close() error

Close consecutively calls Close on all file descriptors.

type ReadWriteSeekCloser

type ReadWriteSeekCloser interface {
	io.Reader
	io.Writer
	io.Seeker
	io.Closer
}

ReadWriteSeekCloser specifies the interface for the temporary file.

type Runner

type Runner interface {
	Run() error
}

Runner defines the interface for a shell process to be executed.

Directories

Path Synopsis
cmd
duct command
duct - add stdin and stdout to a code formatter
duct - add stdin and stdout to a code formatter

Jump to

Keyboard shortcuts

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