util

package
v0.0.0-...-351a61c Latest Latest
Warning

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

Go to latest
Published: Apr 27, 2024 License: GPL-3.0 Imports: 25 Imported by: 126

Documentation

Overview

Package util contains a collection of miscellaneous utility functions.

Index

Examples

Constants

View Source
const (
	// FedoraDownloadURL is the default fedora releases and updates download
	// URL. If you try to use this, you will get redirected to a mirror near
	// you.
	FedoraDownloadURL = "https://download.fedoraproject.org/pub/fedora/linux/"

	// FedoraReleasesEndpointJSON is the location of the fedora release data
	// as specified in json format.
	FedoraReleasesEndpointJSON = "https://fedoraproject.org/releases.json"
)
View Source
const (
	// RelPathFsScheme returns a unique name for this type of filesystem.
	RelPathFsScheme = "RelPathFs"
)

Variables

This section is empty.

Functions

func B64ToValue

func B64ToValue(str string) (interface{}, error)

B64ToValue decodes a value from a base64 encoded string (after deserialization).

func Basename

func Basename(p string) string

Basename is the base of a path string.

func Bool

func Bool(x interface{}) bool

Bool returns the interface value if it is a bool, and otherwise it panics.

func BoolMapTrue

func BoolMapTrue(l []bool) bool

BoolMapTrue returns true if everyone in the list is true.

func BoolMapValues

func BoolMapValues(m map[string]bool) []bool

BoolMapValues returns the sorted list of bool values in a map with string values.

func CloseAfter

func CloseAfter(ctx context.Context, d time.Duration) <-chan struct{}

CloseAfter takes a duration, similarly to `time.After`, and returns a channel that closes when either the context is done, or the duration expires.

func Code

func Code(code string) string

Code takes a code block as a backtick enclosed `heredoc` and removes any common indentation from each line. This helps inline code as strings to be formatted nicely without unnecessary indentation. It also drops the very first line of code if it has zero length.

func ContextWithCloser

func ContextWithCloser(ctx context.Context, ch <-chan struct{}) (context.Context, context.CancelFunc)

ContextWithCloser wraps a context and returns a new one exactly like the other context.With* functions, except that it takes a channel as an alternate cancel signal. TODO: switch to interface{} instead of <-chan struct to allow any chan type.

func CopyDiskContentsToFs

func CopyDiskContentsToFs(dstFs afero.Fs, src, dst string, force bool) error

CopyDiskContentsToFs performs exactly as CopyFs, except that the src fs is our local disk os fs, and we don't keep the source dir name, we only copy the contents.

func CopyDiskToFs

func CopyDiskToFs(dstFs afero.Fs, src, dst string, force bool) error

CopyDiskToFs performs exactly as CopyFs, except that the src fs is our local disk os fs.

func CopyDiskToFsAll

func CopyDiskToFsAll(dstFs afero.Fs, src, dst string, force, all bool) error

CopyDiskToFsAll performs exactly as CopyDiskToFs, except that it allows you to specify the `all` argument which switches CopyFs to using MkdirAll instead of the regular Mkdir. TODO: This works around weird copying issues. POSIX is hard.

func CopyFs

func CopyFs(srcFs, dstFs afero.Fs, src, dst string, force bool, all bool) error

CopyFs copies a dir from the srcFs to a dir on the dstFs. It expects that the dst will be either empty, or that the force flag will be set to true. If the dst has a different set of contents in the same location, the behaviour is currently undefined. TODO: this should be made more rsync like and robust!

func CopyFsContents

func CopyFsContents(srcFs afero.Fs, dstFs afero.Fs, src string, dst string, force bool) error

CopyFsContents copies a dir from the srcFs to a dir on the dstFs. It expects that the dst will be either empty, or that the force flag will be set to true. If the dst has a different set of contents in the same location, the behaviour is currently undefined. Notably, this does not copy the src dir itself, and only includes the contents. This is similar to `rsync dir/` vs. `rsync dir`. This function does the former, where as CopyFs does the latter. TODO: this should be made more rsync like and robust!

func CopyFsContentsToDisk

func CopyFsContentsToDisk(srcFs afero.Fs, src, dst string, force bool) error

CopyFsContentsToDisk performs exactly as CopyFs, except that the dst fs is our local disk os fs, and we don't keep the source dir name, we only copy the contents.

func CopyFsToDisk

func CopyFsToDisk(srcFs afero.Fs, src, dst string, force bool) error

CopyFsToDisk performs exactly as CopyFs, except that the dst fs is our local disk os fs.

func CtxWithWg

func CtxWithWg(ctx context.Context, wg *sync.WaitGroup) context.Context

CtxWithWg takes a context and a wait group, and returns a new context that is embedded with the wait group. You must use WgFromCtx to extract it.

func DirParents

func DirParents(p string) []string

DirParents returns a list of the parent directories in a given path. If you pass it an empty string, or a single slash, then you will get an empty list. If you pass it a malformed path, then you might get unexpected results.

func DirifyFileList

func DirifyFileList(fileList []string, removeDirs bool) []string

DirifyFileList adds trailing slashes to any likely dirs in a package manager fileList if removeDirs is true, otherwise, don't keep the dirs in our output.

func Dirname

func Dirname(p string) string

Dirname is similar to the GNU dirname command.

func ExpandHome

func ExpandHome(p string) (string, error)

ExpandHome does an expansion of ~/ or ~james/ into user's home dir value.

func FirstToUpper

func FirstToUpper(str string) string

FirstToUpper returns the string with the first character capitalized.

func FlattenListWithSplit

func FlattenListWithSplit(input []string, split []string) []string

FlattenListWithSplit flattens a list of input by splitting each element by any and all of the strings listed in the split array

func FsTree

func FsTree(fs afero.Fs, name string) (string, error)

FsTree returns a string representation of the file system tree similar to the well-known `tree` command.

func GetFedoraDownloadURL

func GetFedoraDownloadURL(ctx context.Context) (string, error)

GetFedoraDownloadURL gets an https base path of a mirror to use for downloading both the fedora release and updates. It is supposed to find something nearest to you. TODO: Do we need to specify version and arch to make sure mirror has those?

func GetPhysicalEthernetDevices

func GetPhysicalEthernetDevices() ([]string, error)

GetPhysicalEthernetDevices returns a link of physical ethernet devices. This is a heuristic and I wish I knew the better way.

XXX: Patches welcome!

func HasPathPrefix

func HasPathPrefix(p, prefix string) bool

HasPathPrefix tells us if a path string contain the given path prefix in it.

func LatestFedoraVersion

func LatestFedoraVersion(ctx context.Context, arch string) (string, error)

LatestFedoraVersion returns the version number (as a string) of the latest fedora release known. This looks at a well-known endpoint to get the value. If you specify a non-empty arch, it will filter to that.

func MissingMkdirs

func MissingMkdirs(input []string) ([]string, error)

MissingMkdirs takes a list of paths, and returns a list of any missing paths that would be needed to avoid having to `mkdir -p` to prevent missing parent directory errors from happening. This adds paths all the way up to the root, but without including it, because it's implied. TODO: do we want to include the root? TODO: this could probably be implemented in a more efficient way...

func NewRelPathFs

func NewRelPathFs(source afero.Fs, prefix string) afero.Fs

NewRelPathFs creates a new RelPathFs.

func NumToAlpha

func NumToAlpha(idx int) string

NumToAlpha returns a lower case string of letters representing a number. If you specify 0, you'll get `a`, 25 gives you `z`, and 26 gives you `aa` and so on...

func PathPrefixDelta

func PathPrefixDelta(p, prefix string) int

PathPrefixDelta returns the delta of the path prefix, which tells you how many path tokens different the prefix is.

func PathSplit

func PathSplit(p string) []string

PathSplit splits a path into an array of tokens excluding any trailing empty tokens.

func PathSplitFullReversed

func PathSplitFullReversed(p string) []string

PathSplitFullReversed returns the full list of "dependency" paths for a given path in reverse order.

func PriorityStrSliceSort

func PriorityStrSliceSort(input []string, fn func(string) bool) []string

PriorityStrSliceSort filters any elements matching fn to the end of the list. You can reverse the match result with a not to filter to the front instead! A copy of the list is returned, the original is not modified.

func Rebase

func Rebase(path, base, root string) (string, error)

Rebase takes an absolute base path (directory prefix) and removes it from an absolute path and then returns that path with a new root as an absolute path if root is an absolute dir, and as a relative path if root is a relative dir. Eg: Rebase("/usr/bin/foo", "/usr/", "/usr/local/") -> "/usr/local/bin/foo" Eg: Rebase("/var/lib/dir/file.conf", "/var/lib/", "") -> "dir/file.conf"

func RemoveBasePath

func RemoveBasePath(path, base string) (string, error)

RemoveBasePath removes an absolute base path (directory prefix) from an absolute path that is any file or directory. Eg: RemoveBasePath("/usr/bin/foo", "/usr/") -> "bin/foo" Eg: RemoveBasePath("/usr/bin/project/", "/usr/") -> "bin/project/".

func RemoveCommonFilePrefixes

func RemoveCommonFilePrefixes(paths []string) []string

RemoveCommonFilePrefixes removes redundant file path prefixes that are under the tree of other files.

func RemovePathPrefix

func RemovePathPrefix(s string) (string, error)

RemovePathPrefix takes an absolute path and removes the first chunk. It returns the remainder as an absolute path. This function is a bit of a hack, and could probably be re-written to support any kind of path, and return a relative path.

func RemovePathSuffix

func RemovePathSuffix(s string) (string, error)

RemovePathSuffix takes an absolute path and removes the last chunk. It returns the remainder as an absolute path. This function is a bit of a hack, and could probably be re-written to support any kind of path, and return a relative path.

func ReverseStringList

func ReverseStringList(in []string) []string

ReverseStringList reverses a list of strings.

func SessionBusPrivateUsable

func SessionBusPrivateUsable() (conn *dbus.Conn, err error)

SessionBusPrivateUsable makes using the private bus usable. TODO: should be upstream: https://github.com/godbus/dbus/issues/15

func SortMapStringValuesByUInt64Keys

func SortMapStringValuesByUInt64Keys(m map[uint64]string) []string

SortMapStringValuesByUInt64Keys builds a list of strings, sorted by the corresponding key that is associated with that value. TODO: add some tests

func SortedStrSliceCompare

func SortedStrSliceCompare(a, b []string) error

SortedStrSliceCompare takes two lists of strings and returns whether or not they are equivalent. It will return nil if both sets contain the same elements, regardless of order, and an error if they do not.

func StrFilterElementsInList

func StrFilterElementsInList(filter []string, list []string) []string

StrFilterElementsInList removes any of the elements in filter, if they exist in the list.

func StrInList

func StrInList(needle string, haystack []string) bool

StrInList returns true if a string exists inside a list, otherwise false.

func StrInPathPrefixList

func StrInPathPrefixList(needle string, haystack []string) bool

StrInPathPrefixList returns true if the needle is a PathPrefix in the haystack.

func StrListIntersection

func StrListIntersection(list1 []string, list2 []string) []string

StrListIntersection removes any of the elements in filter, if they don't exist in the list. This is an in order intersection of two lists.

func StrMapKeys

func StrMapKeys(m map[string]string) []string

StrMapKeys return the sorted list of string keys in a map with string keys. NOTE: i thought it would be nice for this to use: map[string]interface{} but it turns out that's not allowed. I know we don't have generics, but come on!

func StrMapKeysUint64

func StrMapKeysUint64(m map[string]uint64) []string

StrMapKeysUint64 return the sorted list of string keys in a map with string keys but uint64 values.

func StrMapValues

func StrMapValues(m map[string]string) []string

StrMapValues returns the sorted list of string values in a map with string values.

func StrMapValuesUint64

func StrMapValuesUint64(m map[uint64]string) []string

StrMapValuesUint64 return the sorted list of string values in a map with string values.

func StrRemoveDuplicatesInList

func StrRemoveDuplicatesInList(list []string) []string

StrRemoveDuplicatesInList removes any duplicate values in the list. This implementation is possibly sub-optimal (O(n^2)?) but preserves ordering.

func SystemBusPrivateUsable

func SystemBusPrivateUsable() (conn *dbus.Conn, err error)

SystemBusPrivateUsable makes using the private bus usable. TODO: should be upstream: https://github.com/godbus/dbus/issues/15

func TestDir

func TestDir(suffix string) (string, error)

TestDir gets the absolute path to the test directory if it exists. If the dir does not exist, then this will error, but the path will still be returned. This is a utility function that is used in some tests.

func TestDirFull

func TestDirFull() (string, error)

TestDirFull gets the full absolute path to a unique test directory if it exists. If the dir does not exist, then this will error, but the path will still be returned. This is a utility function that is used in some tests.

func TimeAfterOrBlock

func TimeAfterOrBlock(t int) <-chan time.Time

TimeAfterOrBlock is aspecial version of time.After that blocks when given a negative integer. When used in a case statement, the timer restarts on each select call to it.

func TimeAfterOrBlockCtx

func TimeAfterOrBlockCtx(ctx context.Context, t int) <-chan struct{}

TimeAfterOrBlockCtx returns a channel that closes after a timeout. If you use a negative timeout, it will block forever. It can also unblock using context. Make sure to cancel the context when you're done, or you'll leak a goroutine.

func Uint

func Uint(x interface{}) uint

Uint returns the interface value if it is a uint, and otherwise it panics.

func Uint64KeyFromStrInMap

func Uint64KeyFromStrInMap(needle string, haystack map[uint64]string) (uint64, bool)

Uint64KeyFromStrInMap returns true if needle is found in haystack of keys that have uint64 type.

func ValueToB64

func ValueToB64(value interface{}) (string, error)

ValueToB64 encodes a value to a base64 encoded string (after serialization).

func WgFromCtx

func WgFromCtx(ctx context.Context) *sync.WaitGroup

WgFromCtx takes a context and returns the stored wait group. You must use CtxWithWg to store it.

Types

type AferoFs

type AferoFs struct {
	*afero.Afero

	Scheme string
	Path   string
}

AferoFs is a simple wrapper to a file system to be used for standalone deploys. This is basically a pass-through so that we fulfill the same interface that the deploy mechanism uses. If you give it Scheme and Path fields it will use those to build the URI. NOTE: This struct is here, since I don't know where else to put it for now.

func (*AferoFs) URI

func (obj *AferoFs) URI() string

URI returns the unique URI of this filesystem. It returns the root path.

type BlockedTimer

type BlockedTimer struct {
	// Duration specifies how long we should wait before we run (or print)
	// the function or message. The counter starts when that respective
	// function is run. For an easier method, specify the Seconds parameter
	// instead.
	Duration time.Duration

	// Seconds works exactly as Duration does, except it can be used as a
	// shorter method to accomplish the same thing. If this value is zero,
	// then Duration is used instead.
	Seconds int
	// contains filtered or unexported fields
}

BlockedTimer is a helper facility for printing log messages when you have a possible deadlock. Alternatively, it can run an arbitrary function instead. It does this by starting a timer, and if that timer isn't cancelled soon enough, it executes the task. This is usually most useful before a select statement which should ordinarily unblock rather quickly. It's helpful to avoid unnecessary "waiting for select" log messages being constantly printed, but should those block for longer, you'd definitely like to know where to look first. This is safe for concurrent use. Multiple invocations of Printf or Run are permitted. They each have their own separate countdown timers, but are all cancelled when Cancel is run. It is safe to call Cancel multiple times. If Cancel is called before Printf or Run, then those will never run. A BlockedTimer must not be copied after first use.

func (*BlockedTimer) Cancel

func (obj *BlockedTimer) Cancel()

Cancel cancels the execution of any Run or Printf functions. It is safe to call it multiple times. It is important to call this at least once (on defer for example) if you've used either Printf or Run, because otherwise you will leak goroutines.

func (*BlockedTimer) Printf

func (obj *BlockedTimer) Printf(format string, v ...interface{})

Printf will print as expected when the timer expires if Cancel isn't run first. This can be used multiple times.

func (*BlockedTimer) Run

func (obj *BlockedTimer) Run(f func())

Run will run the passed function as expected when the timer expires if Cancel isn't run first. This can be used multiple times.

type BoundedReadSemaphore

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

BoundedReadSemaphore is a mutex that allows multiple Lock operations to occur concurrently, as if they were read locks. The distinction is that for the first Lock operation to complete, the Start() channel state must be read. At this point subsequent Lock operations will succeed. The End state completes once the last paired Unlock operation is run. The cycle can be repeated without needing to re-initialize the struct. Each Lock or Unlock operation itself contains a call to Lock an internal mutex for accounting and implementation purposes.

This was previously named SharedMutex. We welcome alternate naming suggestions.

Example
fmt.Printf("hello\n")
defer fmt.Printf("goodbye\n")

wg := &sync.WaitGroup{}
defer wg.Wait()

ch := make(chan struct{}) // close signal

brs := NewBoundedReadSemaphore()

wg.Add(1)
go func() {
	defer wg.Done()
	brs.Lock()
	defer brs.Unlock()
	time.Sleep(100 * time.Millisecond) // delay for consistent print

	fmt.Printf("#1 is in the locked zone\n")
	time.Sleep(1 * time.Second)
}()

wg.Add(1)
go func() {
	defer wg.Done()
	brs.Lock()
	defer brs.Unlock()
	time.Sleep(200 * time.Millisecond) // delay for consistent print

	fmt.Printf("#2 is in the locked zone\n")
	time.Sleep(2 * time.Second)
}()

wg.Add(1)
go func() {
	defer wg.Done()
	brs.Lock()
	defer brs.Unlock()
	time.Sleep(300 * time.Millisecond) // delay for consistent print

	fmt.Printf("#3 is in the locked zone\n")
	time.Sleep(3 * time.Second)
}()

wg.Add(1)
go func() {
	defer wg.Done()
	defer close(ch) // exit signal
	max := 2        // configure me
	for {
		if max == 0 {
			break
		}
		max--
		time.Sleep(4 * time.Second)
		brs.Lock()
		time.Sleep(100 * time.Millisecond) // delay for consistent print
		fmt.Printf("#4 is in the locked zone\n")

		brs.Unlock()
		time.Sleep(100 * time.Millisecond) // delay for consistent print
		fmt.Printf("#4 is in the unlocked zone\n")
	}
}()

Loop:
for {
	select {
	case <-ch: // exit signal
		break Loop

	case <-brs.Start(): // An empty value is received to start the locking.
		fmt.Printf("shared mutex start\n")
	}

	// subsequent Lock's that happen when at least one Lock is
	// already held are permitted...
	time.Sleep(1 * time.Second)

	// something happens here

	select {
	case <-brs.End(): // An empty values is received when the last Unlock happens.
		fmt.Printf("shared mutex end\n")
	}
}
Output:

hello
shared mutex start
#1 is in the locked zone
#2 is in the locked zone
#3 is in the locked zone
shared mutex end
shared mutex start
#4 is in the locked zone
shared mutex end
#4 is in the unlocked zone
shared mutex start
#4 is in the locked zone
shared mutex end
#4 is in the unlocked zone
goodbye

func NewBoundedReadSemaphore

func NewBoundedReadSemaphore() *BoundedReadSemaphore

NewBoundedReadSemaphore creates an initialized object. This must be done before first use, as the empty struct is not a valid BoundedReadSemaphore.

func (*BoundedReadSemaphore) End

func (obj *BoundedReadSemaphore) End() <-chan struct{}

End will return a single signal on this output channel to advise that we've returned to the "unlocked" state.

func (*BoundedReadSemaphore) Lock

func (obj *BoundedReadSemaphore) Lock()

Lock asks for a lock on this mutex. After the first Lock call synchronizes, subsequent calls will succeed quickly. The first "synchronization" waits for the lock start signal, which is a receive on the Start channel.

func (*BoundedReadSemaphore) Start

func (obj *BoundedReadSemaphore) Start() <-chan struct{}

Start will return a single signal on this output channel to advise that we've started the "locked" state.

func (*BoundedReadSemaphore) Unlock

func (obj *BoundedReadSemaphore) Unlock()

Unlock unlocks from a previous Lock operation. If this call is the last paired unlock operation, it blocks until the End() signal is synchronized. If you unlock more times than you lock, then you will cause a panic.

type EasyAck

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

EasyAck is a wrapper to build ack functionality into a simple interface.

func NewEasyAck

func NewEasyAck() *EasyAck

NewEasyAck builds the object. This must be called before use.

func (*EasyAck) Ack

func (obj *EasyAck) Ack()

Ack sends the acknowledgment message. This can only be called once.

func (*EasyAck) Wait

func (obj *EasyAck) Wait() <-chan struct{}

Wait returns a channel that you can wait on for the ack message.

type EasyAckOnce

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

EasyAckOnce is a wrapper to build ack functionality into a simple interface. It is safe because the Ack function can be called multiple times safely.

func NewEasyAckOnce

func NewEasyAckOnce() *EasyAckOnce

NewEasyAckOnce builds the object. This must be called before use.

func (*EasyAckOnce) Ack

func (obj *EasyAckOnce) Ack()

Ack sends the acknowledgment message. This can be called as many times as you like. Only the first Ack is meaningful. Subsequent Ack's are redundant. It is thread-safe.

func (*EasyAckOnce) Wait

func (obj *EasyAckOnce) Wait() <-chan struct{}

Wait returns a channel that you can wait on for the ack message. The return channel closes on the first Ack it receives. Subsequent Ack's have no effect.

type EasyExit

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

EasyExit is a struct that helps you build a close switch and signal which can be called multiple times safely, and used as a signal many times in parallel. It can also provide a context, if you prefer to use that as a signal instead.

func NewEasyExit

func NewEasyExit() *EasyExit

NewEasyExit builds an easy exit struct.

func (*EasyExit) Context

func (obj *EasyExit) Context() context.Context

Context returns a context that is canceled when the Done signal is triggered. This can be used in addition to or instead of the Signal method.

func (*EasyExit) Done

func (obj *EasyExit) Done(err error)

Done triggers the exit signal. It associates an error condition with it too. This is thread-safe.

func (*EasyExit) Error

func (obj *EasyExit) Error() error

Error returns the error condition associated with the Done signal. It blocks until Done is called at least once. It then returns any of the errors or nil. It is only guaranteed to at least return the error from the first Done error.

func (*EasyExit) Signal

func (obj *EasyExit) Signal() <-chan struct{}

Signal returns the channel that we watch for the exit signal on. It will close to signal us when triggered by Exit().

type EasyOnce

type EasyOnce struct {
	Func func()
	// contains filtered or unexported fields
}

EasyOnce is a wrapper for the sync.Once functionality which lets you define and register the associated `run once` function at declaration time. It may be copied at any time.

func (*EasyOnce) Done

func (obj *EasyOnce) Done()

Done runs the function which was defined in `Func` a maximum of once. Please note that this is not currently thread-safe. Wrap calls to this with a mutex.

type FedoraRelease

type FedoraRelease struct {
	Version string `json:"version"`
	Arch    string `json:"arch"`
	Variant string `json:"variant"`
}

FedoraRelease is a partial struct of the available data in the json releases file found. This was determined by inspection.

type FileInfoDirEntry

type FileInfoDirEntry struct {
	fs.FileInfo
}

FileInfoDirEntry provides an adapter from os.FileInfo to fs.DirEntry

func (FileInfoDirEntry) Info

func (obj FileInfoDirEntry) Info() (fs.FileInfo, error)

Info returns the FileInfo for this DirEntry.

func (FileInfoDirEntry) Type

func (obj FileInfoDirEntry) Type() fs.FileMode

Type returns the FileMode for this DirEntry.

type LogWriter

type LogWriter struct {
	Prefix string
	Logf   func(format string, v ...interface{})
}

LogWriter is a simple interface that wraps our logf interface. TODO: Logf should end in (n int, err error) like fmt.Printf does!

func (*LogWriter) Write

func (obj *LogWriter) Write(p []byte) (n int, err error)

Write satisfies the io.Writer interface.

type PathSlice

type PathSlice []string

PathSlice is a type used to implement sort.Interface on a slice of strings, where each string is a path. This allows you to call sort.Sort() on a list of paths, after casting the []string{} to this type. Paths will be sorted by depth in alphabetical order.

func (PathSlice) Len

func (obj PathSlice) Len() int

Len returns the length of obj. It is required to satisfy sort.Interface.

func (PathSlice) Less

func (obj PathSlice) Less(i, j int) bool

Less returns whether obj[i] is less than obj[j]. It performs the logic required to satisfy sort.Interface.

func (PathSlice) Sort

func (obj PathSlice) Sort()

Sort is a convenience method.

func (PathSlice) Swap

func (obj PathSlice) Swap(i, j int)

Swap swaps obj[i] and obj[j]. it is required to satisfy sort.Interface.

type RelPathFile

type RelPathFile struct {
	afero.File
	// contains filtered or unexported fields
}

RelPathFile represents a file node.

func (*RelPathFile) Name

func (obj *RelPathFile) Name() string

Name returns the path of the file.

func (*RelPathFile) ReadDir

func (obj *RelPathFile) ReadDir(n int) ([]fs.DirEntry, error)

ReadDir lists the contents of the directory and returns a list of file info objects for each entry.

type RelPathFs

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

RelPathFs removes a prefix from all operations to a given path within an Fs. The given file name to the operations on this Fs will have a prefix removed before calling the base Fs.

When initializing it with "/", a call to `/foo` turns into `foo`.

Note that it does not clean the error messages on return, so you may reveal the real path on errors.

func (*RelPathFs) Chmod

func (obj *RelPathFs) Chmod(name string, mode os.FileMode) (err error)

Chmod changes the mode of a file.

func (*RelPathFs) Chown

func (obj *RelPathFs) Chown(name string, uid, gid int) (err error)

Chown changes the ownership of a file. It is the equivalent of os.Chown.

func (*RelPathFs) Chtimes

func (obj *RelPathFs) Chtimes(name string, atime, mtime time.Time) (err error)

Chtimes changes the access and modification times of the named file, similar to the Unix utime() or utimes() functions. The underlying filesystem may truncate or round the values to a less precise time unit. If there is an error, it will be of type *PathError.

func (*RelPathFs) Create

func (obj *RelPathFs) Create(name string) (f afero.File, err error)

Create creates a new file.

func (*RelPathFs) LstatIfPossible

func (obj *RelPathFs) LstatIfPossible(name string) (os.FileInfo, bool, error)

LstatIfPossible is for the lstater interface.

func (*RelPathFs) Mkdir

func (obj *RelPathFs) Mkdir(name string, mode os.FileMode) (err error)

Mkdir makes a new directory.

func (*RelPathFs) MkdirAll

func (obj *RelPathFs) MkdirAll(name string, mode os.FileMode) (err error)

MkdirAll creates a directory named path, along with any necessary parents, and returns nil, or else returns an error. The permission bits perm are used for all directories that MkdirAll creates. If path is already a directory, MkdirAll does nothing and returns nil.

func (*RelPathFs) Name

func (obj *RelPathFs) Name() string

Name returns the name of this filesystem.

func (*RelPathFs) Open

func (obj *RelPathFs) Open(name string) (f afero.File, err error)

Open opens a path. It will be opened read-only.

func (*RelPathFs) OpenFile

func (obj *RelPathFs) OpenFile(name string, flag int, mode os.FileMode) (f afero.File, err error)

OpenFile opens a path with a particular flag and permission.

func (*RelPathFs) ReadlinkIfPossible

func (obj *RelPathFs) ReadlinkIfPossible(name string) (string, error)

ReadlinkIfPossible is for the weird Afero readlink API.

func (*RelPathFs) RealPath

func (obj *RelPathFs) RealPath(name string) (string, error)

RealPath returns the correct path with the prefix removed.

func (*RelPathFs) Remove

func (obj *RelPathFs) Remove(name string) (err error)

Remove removes a path.

func (*RelPathFs) RemoveAll

func (obj *RelPathFs) RemoveAll(name string) (err error)

RemoveAll removes path and any children it contains. It removes everything it can but returns the first error it encounters. If the path does not exist, RemoveAll returns nil (no error).

func (*RelPathFs) Rename

func (obj *RelPathFs) Rename(oldname, newname string) (err error)

Rename moves or renames a file or directory.

func (*RelPathFs) Stat

func (obj *RelPathFs) Stat(name string) (fi os.FileInfo, err error)

Stat returns some information about the particular path.

func (*RelPathFs) SymlinkIfPossible

func (obj *RelPathFs) SymlinkIfPossible(oldname, newname string) error

SymlinkIfPossible is for the weird Afero symlink API.

type SubscribedSignal

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

SubscribedSignal represents a synchronized read signal. It doesn't need to be instantiated before it can be used. It must not be copied after first use. It is equivalent to receiving a multicast signal from a closing channel, except that it must be acknowledged by every reader of the signal, and once this is done, it is reset and can be re-used. Readers must obtain a handle to the signal with the Subscribe method, and the signal is sent out with the Done method.

Example
fmt.Println("hello")

x := &SubscribedSignal{}
wg := &sync.WaitGroup{}
ready := &sync.WaitGroup{}

// unit1
wg.Add(1)
ready.Add(1)
go func() {
	defer wg.Done()
	ch, ack := x.Subscribe()
	ready.Done()
	select {
	case <-ch:
		fmt.Println("got signal")
	}
	time.Sleep(1 * time.Second) // wait a bit for fun
	fmt.Println("(1) sending ack...")
	ack() // must call ack
	fmt.Println("done sending ack")
}()

// unit2
wg.Add(1)
ready.Add(1)
go func() {
	defer wg.Done()
	ch, ack := x.Subscribe()
	ready.Done()
	select {
	case <-ch:
		fmt.Println("got signal")
	}
	time.Sleep(2 * time.Second) // wait a bit for fun
	fmt.Println("(2) sending ack...")
	ack() // must call ack
	fmt.Println("done sending ack")
}()

// unit3
wg.Add(1)
ready.Add(1)
go func() {
	defer wg.Done()
	ch, ack := x.Subscribe()
	ready.Done()
	select {
	case <-ch:
		fmt.Println("got signal")
	}
	time.Sleep(3 * time.Second) // wait a bit for fun
	fmt.Println("(3) sending ack...")
	ack() // must call ack
	fmt.Println("done sending ack")
}()

ready.Wait() // wait for all subscribes
fmt.Println("sending signal...")
x.Send()                    // trigger!
time.Sleep(1 * time.Second) // wait a bit so the next print doesn't race
fmt.Println("done sending signal")

wg.Wait() // wait for everyone to exit
fmt.Println("exiting...")
Output:

hello
sending signal...
got signal
got signal
got signal
(1) sending ack...
(2) sending ack...
(3) sending ack...
done sending ack
done sending ack
done sending ack
done sending signal
exiting...

func (*SubscribedSignal) Send

func (obj *SubscribedSignal) Send()

Send is called if you want to multicast the signal to all subscribed parties. It will require all parties to acknowledge the receipt of the signal before it will unblock. Just before returning, it will reset the signal so that it can be called a subsequent time. This is thread safe and can be called multiple times in parallel because this call is protected by a mutex. The mutex also prevents simultaneous calls with the Subscribe method.

func (*SubscribedSignal) Subscribe

func (obj *SubscribedSignal) Subscribe() (<-chan struct{}, func())

Subscribe is used by any reader of the signal. Once this function returns, it means that you're now ready to watch the signal. The signal can be watched as is done normally with any other ready channel. Once you have received the signal or when you are no longer interested in the signal you *must* call the cancel/ack function which is returned by this function on subscribe. If you do not, you will block the Send portion of this subscribed signal indefinitely. This is thread safe and can be called multiple times in parallel because this call is protected by a mutex. The mutex also prevents simultaneous calls with the Send method. the returned cancel/ack method must return before it's safe to call this method a subsequent time for a new signal. One important note: there is a possible race that *you* can cause if you race this Subscribe call, with the Send call. Make sure you run Subscribe and it returns *before* you run Send if you want to be sure to receive the next signal. This should be common sense but it is mentioned here to be helpful. They are protected by a lock, so they can't both run simultaneously.

type UInt64Slice

type UInt64Slice []uint64

UInt64Slice attaches the methods of sort.Interface to []uint64, sorting in increasing order.

func (UInt64Slice) Len

func (obj UInt64Slice) Len() int

Len returns the length of the slice of uint64's.

func (UInt64Slice) Less

func (obj UInt64Slice) Less(i, j int) bool

Less returns the smaller element in the sort order.

func (UInt64Slice) Sort

func (obj UInt64Slice) Sort()

Sort is a convenience method.

func (UInt64Slice) Swap

func (obj UInt64Slice) Swap(i, j int)

Swap swaps two elements in the slice.

Directories

Path Synopsis
Package errwrap contains some error helpers.
Package errwrap contains some error helpers.
Package recwatch provides recursive file watching events via fsnotify.
Package recwatch provides recursive file watching events via fsnotify.
Package safepath implements some types and methods for dealing with POSIX file paths safely.
Package safepath implements some types and methods for dealing with POSIX file paths safely.
Package semaphore contains an implementation of a counting semaphore.
Package semaphore contains an implementation of a counting semaphore.
Package socketset is in API for creating a select style netlink socket to receive events from the kernel.
Package socketset is in API for creating a select style netlink socket to receive events from the kernel.

Jump to

Keyboard shortcuts

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