is

package module
v0.8.66 Latest Latest
Warning

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

Go to latest
Published: Dec 12, 2025 License: Apache-2.0 Imports: 23 Imported by: 18

README

is

Go GitHub go.mod Go version GitHub tag (latest SemVer) go.dev deps.dev

is provides numerous detectors for checking the states of environment (build, executive, ...).

Features

  • is.State(which) bool: the universal detector entry - via RegisterStateGetter(state string, getter func() bool) to add your own ones. Since v0.5.11
  • is.Env() holds a global struct for CLI app basic states, such as: verbose/quiet/debug/trace....
    • DebugMode/DebugLevel, TraceMode/TraceLevel, ColorMode, ...
  • is.InDebugging() bool, is.InTesting() bool, and is.InTracing() bool, ....
  • is.DebugBuild() bool.
  • is.K8sBuild() bool, is.DockerBuild() bool, ....
  • is.ColoredTty() bool, ....
  • is.Color() to get an indexer for the functions in our term/color subpackage, ...
  • Terminal Colorizer, Detector, unescape tools.
    • is/term/color.Color interface
  • stringtool: RandomStringPure, case-converters ...
  • basics: closable, closer, signals.
    • easier Press any key to exit... prompt: is.Signals().Catch()
  • exec: Run, RunWithOutput, Sudo, ...
  • go1.23.7+ required since v0.7.0
  • go 1.24.0+ required
  • go1.24.5 required since v0.8.55

See the above badge to get the exact required go toolchain version.

To using environment detecting utilities better and smoother, some terminal (and stringtool, basics) tools are bundled together.

Since v0.6.0, is.InDebugging() checks if the running process' parent is dlv. The old DebugMode and DebugBuild are still work:

  • InDebugging: checks this process is being debugged by dlv.
  • DebugBuild: -tags=delve is set at building.
  • DebugMode: --debug is specified at command line.

Since v0.8.27, basics.Signals().Catcher().WaitFor() wants ctx param passed in.

Usages

package main

import (
    "context"
    "fmt"
    "log/slog"
    "os"
    "sync"
    "time"

    "github.com/hedzr/is"
    "github.com/hedzr/is/basics"
    "github.com/hedzr/is/term/color"
)

func main() {
    // defer basics.Close() // uncomment if not using Catcher.WaitFor and/or cmdr.v2

    is.RegisterStateGetter("custom", func() bool { return is.InVscodeTerminal() })

    println(is.InTesting())
    println(is.State("in-testing"))
    println(is.State("custom")) // detects a state with custom detector
    println(is.Env().GetDebugLevel())
    if is.InDebugMode() {
        slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{AddSource: true, Level: slog.LevelDebug})))
    }

    // or:
    //    is.Color().GetColorTranslator().Translate("<b>bold</b>")
    fmt.Printf("%v", color.GetCPT().Translate(`<code>code</code> | <kbd>CTRL</kbd>
        <b>bold / strong / em</b>
        <i>italic / cite</i>
        <u>underline</u>
        <mark>inverse mark</mark>
        <del>strike / del </del>
        <font color="green">green text</font>
`, color.FgDefault))

    var cancelled int32
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    catcher := is.Signals().Catch()
    catcher.
        WithPrompt("Press CTRL-C to quit...").
        // WithOnLoopFunc(dbStarter, cacheStarter, mqStarter).
        WithPeripherals(&dbMgr{}).
        WithOnSignalCaught(func(ctx context.Context, sig os.Signal, wg *sync.WaitGroup) {
            println()
            slog.Info("signal caught", "sig", sig)
            cancel() // cancel user's loop, see Wait(...)
        }).
        WaitFor(ctx, func(ctx context.Context, closer func()) {
            slog.Debug("entering looper's loop...")
            defer close() // notify catcher we want to shutdown
            // to terminate this app after a while automatically:
            time.Sleep(10 * time.Second)

            if atomic.CompareAndSwapInt32(&cancelled, 0, 1) {
                is.PressAnyKeyToContinue(os.Stdin)
            }
        })
}

type dbMgr struct{}

func (*dbMgr) Close()                           {}         // before app terminatine
func (*dbMgr) Open(context.Context) (err error) { return } // ran before catcher.WaitFor()

Result is similar with:

image-20240113071930661

NOTE that is.Signals().Catch() will produce a prompt and enter a infinite loop to wait for user's keystroke pressed.

Lists
is.Terminal(os.Stdout)

The partials:

  • is.InDebugging / InDebugMode

  • is.DebuggerAttached (relyes on delve tag)

  • is.InTracing / InTestingT

  • is.InTesting / InTestingT

  • is.InDevelopingTime

  • is.InVscodeTerminal

  • is.InK8s

  • is.InIstio

  • is.InDocker / InDockerEnvSimple

  • Build

    • is.K8sBuild
    • is.IstioBuild
    • is.DockerBuild
    • is.VerboseBuild
    • is.DebugBuild
    • buildtags.IsBuildTagExists
  • States / Env

    • VerboseModeEnabled
    • GetVerboseLevel / SetVerboseMode / SetVerboseLevel
    • QuietModeEnabled
    • GetQuietLevel / SetQuietMode / SetQuietLevel
    • NoColorMode
    • GetNoColorLevel / SetNoColorMode / SetNoColorLevel
    • DebugMode
    • GetDebugLevel / SetDebugMode / SetDebugLevel
    • Tracing
    • TraceMode
    • GetTraceLevel / SetTraceMode / SetTraceLevel
  • Terminal / Tty

    • is.Terminal(file)
    • is.TerminalFd(fd)
    • is.Tty(wr)
    • is.ColoredTty(wr)
    • is.AnsiEscaped(s) (IsTtyEscaped(s))
    • StripEscapes(s)
    • ReadPassword
    • GetTtySize
    • is.GetTtySizeByName(filename) (cols,rows,err)
    • is.GetTtySizeByFile(file) (cols,rows,err)
    • is.GetTtySizeByFd(fd) (cols,rows,err)
    • StartupByDoubleClick() bool
  • [Special] Terminal / Color

    • escaping tools: GetCPT()/GetCPTC()/GetCPTNC()
    • Highlight, Dimf, Text, Dim, ToDim, ToHighlight, ToColor, ...
    • color.Color interface
    • color.New() return a stream-callable color object: color.Cursor.
  • Basics

    • closers
      • Peripheral, Closable, Closer
      • RegisterClosable
      • RegisterClosers
      • RegisterCloseFns
    • is.Signals().Catcher()
    • is.FileExists(filepath)
    • is.ToBool, StringToBool
Build Tags

Some functions want special buildtags presented. These are including:

  • verbose: See VerboseBuild, ...
  • delve: See DebugBuild, ...
  • k8s: See K8sBuild
  • istio: See IstioBuild
  • docker: See DockerBuild
  • ...
  • buildtags.IsBuildTagExists(tag) bool
Colorizes

The test codes:

import "github.com/hedzr/is/term/color"

func TestGetCPT(t *testing.T) {
t.Logf("%v", color.GetCPT().Translate(`<code>code</code> | <kbd>CTRL</kbd>
    <b>bold / strong / em</b>
    <i>italic / cite</i>
    <u>underline</u>
    <mark>inverse mark</mark>
    <del>strike / del </del>
    <font color="green">green text</font>
    `, color.FgDefault))
}

Result:

image-20231107100150520

And more:

func TestStripLeftTabs(t *testing.T) {
t.Logf("%v", color.StripLeftTabs(`
    
        <code>code</code>
    NC Cool
     But it's tight.
      Hold On!
    Hurry Up.
    `))
}

func TestStripHTMLTags(t *testing.T) {
t.Logf("%v", color.StripHTMLTags(`
    
        <code>code</code>
    NC Cool
     But it's tight.
      Hold On!
    Hurry Up.
    `))
}
Cursor

Since v0.8+, A new color.Cursor object can be initialized by color.New(), which support format the colorful text with streaming calls, for console/tty.

See the online docs for more usages.

expand

The examples are:


func ExampleNew() {
 // start a color text builder
 var c = color.New()

 // specially for running on remote ci server
 if states.Env().IsNoColorMode() {
  states.Env().SetNoColorMode(true)
 }

 // paint and get the result (with ansi-color-seq ready)
 var result = c.Println().
  Color16(color.FgRed).
  Printf("hello, %s.", "world").Println().
  SavePos().
  Println("x").
  Color16(color.FgGreen).Printf("hello, %s.\n", "world").
  Color256(160).Printf("[160] hello, %s.\n", "world").
  Color256(161).Printf("[161] hello, %s.\n", "world").
  Color256(162).Printf("[162] hello, %s.\n", "world").
  Color256(163).Printf("[163] hello, %s.\n", "world").
  Color256(164).Printf("[164] hello, %s.\n", "world").
  Color256(165).Printf("[165] hello, %s.\n", "world").
  Up(3).Echo(" ERASED ").
  RGB(211, 211, 33).Printf("[16m] hello, %s.", "world").
  Println().
  RestorePos().
  Println("z").
  Down(8).
  Println("DONE").
  Build()

  // and render the result
 fmt.Println(result)

 // For most of ttys, the output looks like:
 //
 // hello, world.
 // x
 // hello, world.
 // [160] hello, world.
 // [161] hello, world.
 // [162] hello, world.
 // [163] hello, world.
 // [164] hello, world.
 // [165] hello, world.
 //  ERASED [16m] hello, world.
 // z
 // DONE
}

func ExampleCursor_Color16() {
 // another colorful builfer
 var c = color.New()
 fmt.Println(c.Color16(color.FgRed).
  Printf("hello, %s.", "world").Println().Build())
 // Output: hello, world.
}

func ExampleCursor_Color() {
 // another colorful builfer
 var c = color.New()
 fmt.Println(c.Color(color.FgRed, "hello, %s.", "world").Build())
 // Output: hello, world.
}

func ExampleCursor_Bg() {
 // another colorful builfer
 var c = color.New()
 fmt.Println(c.Bg(color.BgRed, "hello, %s.", "world").Build())
 // Output: hello, world.
}

func ExampleCursor_Effect() {
 // another colorful builfer
 var c = color.New()
 fmt.Println(c.Effect(color.BgDim, "hello, %s.", "world").Build())
 // Output: hello, world.
}

func ExampleCursor_Color256() {
 // another colorful builfer
 var c = color.New()
 fmt.Print(c.
  Color256(163).Printf("[163] hello, %s.\n", "world").
  Color256(164).Printf("[164] hello, %s.\n", "world").
  Color256(165).Printf("[165] hello, %s.\n", "world").
  Build())
 // Output:
 // [163] hello, world.
 // [164] hello, world.
 // [165] hello, world.
}

func ExampleCursor_RGB() {
 // another colorful builfer
 var c = color.New()
 fmt.Print(c.
  RGB(211, 211, 33).Printf("[16m] hello, %s.\n", "world").
  BgRGB(211, 211, 33).Printf("[16m] hello, %s.\n", "world").
  Build())
 // Output:
 // [16m] hello, world.
 // [16m] hello, world.
}

func ExampleCursor_EDim() {
 // another colorful builfer
 var c = color.New()
 fmt.Print(c. // Color16(color.FgRed).
   EDim("[DIM] hello, %s.\n", "world").String())
 // Output:
 // [DIM] hello, world.
 // 
}

func ExampleCursor_Black() {
 // another colorful builfer
 var c = color.New()
 fmt.Print(c. // Color16(color.FgRed).
   Black("[BLACK] hello, %s.\n", "world").String())
 // Output:
 // [BLACK] hello, world.
 // 
}

func ExampleCursor_BgBlack() {
 // another colorful builfer
 var c = color.New()
 fmt.Print(c. // Color16(color.FgRed).
   BgBlack("[BGBLACK] hello, %s.\n", "world").String())
 // Output:
 // [BGBLACK] hello, world.
 // 
}

func ExampleCursor_Translate() {
 // another colorful builfer
 var c = color.New()
 fmt.Print(c. // Color16(color.FgRed).
   Translate(`<code>code</code> | <kbd>CTRL</kbd>
  <b>bold / strong / em</b>
  <i>italic / cite</i>
  <u>underline</u>
  <mark>inverse mark</mark>
  <del>strike / del </del>
  <font color="green">green text</font>
  `).String())
 // Output:
 // code | CTRL
 //  bold / strong / em
 //  italic / cite
 //  underline
 //  inverse mark
 //  strike / del 
 //  green text
}

func ExampleCursor_StripLeftTabsColorful() {
 // another colorful builfer
 var c = color.New()
 fmt.Print(c. // Color16(color.FgRed).
   StripLeftTabsColorful(`
  <code>code</code> | <kbd>CTRL</kbd>
  <b>bold / strong / em</b>
  <i>italic / cite</i>
  <u>underline</u>
  <mark>inverse mark</mark>
  <del>strike / del </del>
  <font color="green">green text</font>
  `).String())
 // Output:
 // code | CTRL
 // bold / strong / em
 // italic / cite
 // underline
 // inverse mark
 // strike / del 
 // green text
}

color subpackage

Package color provides a wrapped standard output device like printf but with colored enhancements.

The main types are Cursor and Translator.

Cursor allows formatting colorful text and moving cursor to another coordinate.

New will return a Cursor object.

RowsBlock is another cursor controller, which can treat the current line and following lines as a block and updating these lines repeatedly. This feature will help the progressbar writers or the continuous lines updater.

Translator is a text and tiny HTML tags translator to convert these markup text into colorful console text sequences. GetCPT can return a smart translator which translate colorful text or strip the ansi escaped sequence from result text if states.Env().IsNoColorMode() is true.

Color is an interface type to represent a terminal color object, which can be serialized to ansi escaped sequence directly by [Color.Color].

To create a Color object, there are several ways:

As to v0.8.53, a Color object can wrap itself arroubd the given text:

color.BgBold.Wrap(color.FgRed.Wrap("ERROR!"))
color.BgDim.Wrap(color.FgDarkGray.Wrap("debug message here."))

Integrated with cmdr

Closers

The Closers() collects all closable objects and allow shutting down them at once.

package main

import (
    "os"

    "github.com/hedzr/is/basics"
)

type redisHub struct{}

func (s *redisHub) Close() {
    // close the connections to redis servers
    println("redis connections closed")
}

func main() {
    defer basics.Close()

    tmpFile, _ := os.CreateTemp(os.TempDir(), "1*.log")
    basics.RegisterClosers(tmpFile)

    basics.RegisterCloseFn(func() {
        // do some shutdown operations here
        println("close single functor")
    })

    basics.RegisterPeripheral(&redisHub{})
}
Signals

Signals() could catch OS signals and entering a infinite loop.

For example, a tcp server could be:

package main

import (
    "context"
    "os"
    "sync"

    "github.com/hedzr/go-socketlib/net"
    "github.com/hedzr/is"
    logz "github.com/hedzr/logg/slog"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    logger := logz.New("new-dns")
    server := net.NewServer(":7099",
        net.WithServerOnListening(func(ss net.Server, l stdnet.Listener) {
            go runClient(ctx, ss, l)
        }),
        net.WithServerLogger(logger.WithSkip(1)),
    )
    defer server.Close()

    // make a catcher so that it can catch ths signals,
    catcher := is.Signals().Catch()
    catcher.
        // WithVerboseFn(func(msg string, args ...any) {
        //     logz.WithSkip(2).Verbose(fmt.Sprintf("[verbose] %s", fmt.Sprintf(msg, args...)))
        // }).
        WithOnSignalCaught(func(ctx context.Context, sig os.Signal, wg *sync.WaitGroup) {
            println()
            logz.Debug("signal caught", "sig", sig)
            if err := server.Shutdown(); err != nil {
                logz.Error("server shutdown error", "err", err)
            }
            cancel()
        }).
        WaitFor(ctx, func(ctx context.Context, closer func()) {
            logz.Debug("entering looper's loop...")

            server.WithOnShutdown(func(err error, ss net.Server) { closer() })
            err := server.ListenAndServe(ctx, nil)
            if err != nil {
                logz.Fatal("server serve failed", "err", err)
            } else {
                closer()
            }
        })
}

func runClient(ctx context.Context, ss net.Server, l stdnet.Listener) {
    c := net.NewClient()

    if err := c.Dial("tcp", ":7099"); err != nil {
        logz.Fatal("connecting to server failed", "err", err, "server-endpoint", ":7099")
    }
    logz.Info("[client] connected", "server.addr", c.RemoteAddr())
    c.RunDemo(ctx)
}

Contributions

Kindly welcome, please issue me first for keeping this repo smaller.

License

under Apache 2.0

Documentation

Overview

Package is provides environ detectors, and other basis.

## Environment Detectors

fo runtime modes (debug, trace, verbose, quiet, no-color)

  • `is.State(which) bool`: the universal detector entry

  • via `RegisterStateGetter(state string, getter func() bool)` to add your own ones. *Since v0.5.11*

  • `is.Env()` holds a global struct for CLI app basic states, such as: verbose/quiet/debug/trace....

  • `DebugMode`/`DebugLevel`, `TraceMode`/`TraceLevel`, `ColorMode`, ...

  • `is.InDebugging() bool`, `is.InTesting() bool`, and `is.InTracing() bool`, ....

  • `is.DebugBuild() bool`.

  • `is.K8sBuild() bool`, `is.DockerBuild() bool`, ....

  • `is.ColoredTty() bool`, ....

  • `is.Color()` to get an indexer for the functions in our term/color subpackage, ...

os, shell,

  • `is.Zsh()`, `is.Bash()`

`exec` subpackage: for launching another program, shell command, ...

  • starts from `exec.New()`

`dir`: dir, file operations, dir/file existance detector

`term`: terminal env detectors, operations.

`term/color`: ansi escaped sequences wrapper, simple html tags tranlator (for color tags).

  • starts from `color.New()`
  • `RowsBlock` by `color.NewRowsBlock()`

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AMD64 added in v0.8.47

func AMD64() bool

AMD64 returns true if CPU arch is amd64.

func ARM32 added in v0.8.47

func ARM32() bool

AMD32 returns true if CPU arch is arm32.

func ARM32BE added in v0.8.47

func ARM32BE() bool

AMD32BE returns true if CPU arch is arm32be.

func ARM64 added in v0.8.47

func ARM64() bool

ARM64 returns true if CPU arch is arm64.

func ARM64BE added in v0.8.47

func ARM64BE() bool

ARM64BE returns true if CPU arch is arm64be.

func Aix added in v0.8.47

func Aix() bool

Aix returns true if running under Aix platform.

func Android added in v0.8.47

func Android() bool

Android returns true if running under Android platform.

func AnsiEscaped added in v0.5.9

func AnsiEscaped(s string) bool

AnsiEscaped detects a string if it contains ansi color escaped sequences

func BSD added in v0.8.47

func BSD() bool

BSD returns true if running under Any BSD platform, including FreeBSD, NetBSD and OpenBSD.

func Bash added in v0.5.27

func Bash() bool

Bash returns true if application is running under a Bash shell.

func Closers added in v0.5.7

func Closers() closerS

Closers returns the container includes all registered closable objects.

The simplest ways is using package level Close function:

func main() {
    defer is.Closers().Close()

    // others statements ...

    is.Closers().RegisterCloseFns(func(){ sth.Close() })

    // more statements...
}

func Color added in v0.5.20

func Color() color.Index

Color returns an indexer for term/color subpackage.

For example, call the Translator to convert the html tags to color codes in a string:

is.Color().GetColorTranslator().Translate("<b>bold</b>")

func ColoredTty added in v0.5.1

func ColoredTty(w io.Writer) bool

ColoredTty detects a writer if it is a colorful tty device.

A colorful tty device can receive ANSI escaped sequences and draw its.

func ColorfulTty added in v0.7.23

func ColorfulTty(w io.Writer) bool

ColorfulTty detects a writer if it is a colorful tty device.

A colorful tty device can receive ANSI escaped sequences and draw its.

func CygwinTerminal added in v0.5.27

func CygwinTerminal(fd uintptr) bool

CygwinTerminal return true if the file descriptor is a cygwin or msys2 terminal. This is also always false on this environment.

func Darwin added in v0.5.27

func Darwin() bool

Darwin returns true if running under macOS platform, including both Intel and Silicon.

func DarwinIntel added in v0.5.27

func DarwinIntel() bool

DarwinIntel returns true if running under Apple Intel Machines.

func DarwinSilicon added in v0.5.27

func DarwinSilicon() bool

DarwinSilicon returns true if running under Apple Silicon.

func DebugBuild

func DebugBuild() bool

func DebugMode

func DebugMode() bool

func DebuggerAttached

func DebuggerAttached() bool

DebuggerAttached returns status if debugger attached or is a debug build.

See also InDebugging.

func Detected added in v0.5.11

func Detected(stateName string) (state bool)

Detected returns the detected state associated with the given state name.

= State, see also it.

func DevMode added in v0.8.38

func DevMode() bool

DevMode return the devmode state.

For cmdr app, devmode means a '.devmode' file is detected at work-dir. You could touch a '.devmode' file in your app's src-tree folder to enable this state automatically.

Detecting devmode file and state is invoked at app starting up. If you wanna disable it, using build tag '-tags="nodetectdevmode"'. If you have disabled it but still want it to be invoked manually, try states.DetectDevModeFile or do it youself.

func DevModeFilePresent added in v0.8.38

func DevModeFilePresent() bool

DevModeFilePresent returns a state to identify ".devmode" (or ".dev-mode") file is detected. This state relyes on once states.DetectDevModeFile was invoked.

func DockerBuild

func DockerBuild() bool

func Dragonfly added in v0.8.47

func Dragonfly() bool

Dragonfly returns true if running under Dragonfly platform.

func Env

func Env() states.CmdrMinimal

func FileExists added in v0.5.7

func FileExists(filepath string) bool

FileExists detects if a file or a directory is existed.

func Fish added in v0.5.27

func Fish() bool

Fish returns true if application is running under a Fish shell.

func FreeBSD added in v0.8.47

func FreeBSD() bool

FreeBSD returns true if running under FreeBSD platform.

func FuncPtrSame added in v0.8.38

func FuncPtrSame[T any](fn1, fn2 T) bool

FuncPtrSame compares two functors if they are same, with an unofficial way.

func GetDebugLevel

func GetDebugLevel() int

func GetNoColorLevel

func GetNoColorLevel() int

func GetQuietLevel

func GetQuietLevel() int

func GetTraceLevel

func GetTraceLevel() int

func GetTtySize

func GetTtySize() (cols, rows int)

GetTtySize returns the window size in columns and rows in the active console window. The return value of this function is in the order of cols, rows.

func GetTtySizeByFd added in v0.5.9

func GetTtySizeByFd(fd uintptr) (cols, rows int, err error)

GetTtySizeByFd retrieve terminal window size by fd (file-descriptor). such as [os.Stdout.Fd()]

func GetTtySizeByFile added in v0.5.9

func GetTtySizeByFile(f *os.File) (cols, rows int, err error)

GetTtySizeByFile retrieve terminal window size by *os.File object. such as os.Stdout

func GetTtySizeByName added in v0.5.9

func GetTtySizeByName(fn string) (cols, rows int, err error)

GetTtySizeByName retrieve terminal window size by device name. such as "/dev/tty"

func GetVerboseLevel

func GetVerboseLevel() int

func Hurd added in v0.8.47

func Hurd() bool

Hurd returns true if running under Hurd platform.

func I386 added in v0.8.47

func I386() bool

AMD64 returns true if CPU arch is amd64.

func IOS added in v0.8.47

func IOS() bool

IOS returns true if running under iOS platform.

func Illumos added in v0.8.47

func Illumos() bool

Illumos returns true if running under Illumos platform.

func InBenchmark added in v0.6.2

func InBenchmark() bool

func InDebugMode

func InDebugMode() bool

InDebugMode and DebugMode returns true if:

  • a debug build, see the DebugBuild.
  • SetDebugMode(true) called.

**NOTE** Since v0.6.0, InDebugMode does not check DebuggerAttached.

func InDebugging

func InDebugging() bool

InDebugging and DebuggerAttached returns status if golang debugger 'dlv' is attached.

**Since v0.6.0**, InDebugging checks if the parent process is 'dlv' or not. It supports Linux, Darwin and Windows currently.

If you're looking for old behavior, DebugBuild() returns if the executable is built with delve tag:

 When you runs `go build` with `-tags=delve` options. eg:

	go run -tags=delve ./cli
	go build -tags=delve -o my-app ./cli

 The executable will hold a 'isdelve' tag. For more details please goto
 https://stackoverflow.com/questions/47879070/how-can-i-see-if-the-goland-debugger-is-running-in-the-program

Performance Note:

For security reason InDebugging checks the debuggers lively. It might take unexpected times for detecting.

Debug States:

  1. is.InDebugging, loaded by a golang debugger (dlv) at runtime?
  2. is.DebugBuild, build tags decide it
  3. is.DebugMode, set by command line flag `--debug`

func InDevMode added in v0.8.38

func InDevMode() bool

InDevMode return the devmode state.

For cmdr app, devmode means a '.devmode' file is detected at work-dir. You could touch a '.devmode' file in your app's src-tree folder to enable this state automatically.

Detecting devmode file and state is invoked at app starting up. If you wanna disable it, using build tag '-tags="nodetectdevmode"'. If you have disabled it but still want it to be invoked manually, try states.DetectDevModeFile or do it youself.

func InDevelopingTime

func InDevelopingTime() (status bool)

InDevelopingTime detects whether is in developing time (debugging or testing).

If the main program has been built as an executable binary, we would assume which is not in developing time.

If GetDebugMode() is true, that's in developing time too.

func InDocker

func InDocker() bool

InDocker detects if the service is running under docker environment.

We tests these two conditions:

  1. find if `/.dockerenv` exists or not.
  2. `docker` in buildtags

func InDockerEnvSimple

func InDockerEnvSimple() (status bool)

InDockerEnvSimple detects whether is running within docker container environment.

InDockerEnvSimple finds if `/.dockerenv` exists or not.

func InIstio

func InIstio() bool

InIstio detects if the service is running under istio injected.

### IMPORTANT

To make this detector work properly, you must mount a DownwordAPI volume to your container/pod. See also:

https://kubernetes.io/en/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/

func InK8s

func InK8s() bool

InK8s detects if the service is running under k8s environment.

func InK8sYN

func InK8sYN() bool

InK8sYN is yet another DetectInK8s impl

func InTesting

func InTesting() bool

InTesting detects whether is running under go test mode

func InTestingT

func InTestingT(args []string) bool

InTestingT detects whether is running under 'go test' mode

func InTracing

func InTracing() bool

InTracing tests if trace.IsEnabled() or env.traceMode (cli app trace mode via --trace).

See the github.com/is/states/trace package.

func InVscodeTerminal

func InVscodeTerminal() bool

InVscodeTerminal tests if running under visual studio code integrated terminal

func IstioBuild

func IstioBuild() bool

func JS added in v0.8.47

func JS() bool

JS returns true if running under JS/WASM platform.

func K8sBuild

func K8sBuild() bool

func Linux added in v0.5.27

func Linux() bool

Linux return true for General Linux Distros.

func Nacl added in v0.8.47

func Nacl() bool

Nacl returns true if running under Nacl platform.

func NetBSD added in v0.8.47

func NetBSD() bool

NetBSD returns true if running under NetBSD platform.

func NoColorMode

func NoColorMode() bool

func OpenBSD added in v0.8.47

func OpenBSD() bool

OpenBSD returns true if running under OpenBSD platform.

func Plan9 added in v0.8.47

func Plan9() bool

Plan9 returns true if running under Plan9 platform.

func Powershell added in v0.5.27

func Powershell() bool

Powershell returns true if application is running under a Windows Powershell shell.

Not testing yet.

func PressAnyKeyToContinue added in v0.7.8

func PressAnyKeyToContinue(in io.Reader, msg ...string) (input string)

PressAnyKeyToContinue lets program pause and wait for user's ANY key press in console/terminal

func PressEnterToContinue added in v0.7.8

func PressEnterToContinue(in io.Reader, msg ...string) (input string)

PressEnterToContinue lets program pause and wait for user's ENTER key press in console/terminal

func QuietModeEnabled

func QuietModeEnabled() bool

func ReadFile added in v0.5.7

func ReadFile(filename string) ([]byte, error)

ReadFile reads the file named by filename and returns the contents.

func ReadPassword

func ReadPassword() (text string, err error)

ReadPassword reads the password from stdin with safe protection

func RegisterStateGetter added in v0.5.11

func RegisterStateGetter(state string, getter func() bool)

RegisterStateGetter allows integrating your own detector into State(name) bool.

For example:

func customState() bool { reutrn ... }
is.RegisterStateGetter("custom", customState)
println(is.State("custom"))

func Root added in v0.5.27

func Root() bool

Root returns true if current user is 'root' or user is in sudo mode.

For windows it's always false.

func SetDebugLevel

func SetDebugLevel(hits int)

func SetDebugMode

func SetDebugMode(b bool)

func SetDevMode added in v0.8.38

func SetDevMode(b bool)

func SetNoColorLevel

func SetNoColorLevel(hits int)

func SetNoColorMode

func SetNoColorMode(b bool)

func SetOnDebugChanged added in v0.7.19

func SetOnDebugChanged(funcs ...states.OnChanged)

func SetOnDeeModeChanged added in v0.8.38

func SetOnDeeModeChanged(funcs ...states.OnChanged)

func SetOnNoColorChanged added in v0.7.19

func SetOnNoColorChanged(funcs ...states.OnChanged)

func SetOnQuietChanged added in v0.7.19

func SetOnQuietChanged(funcs ...states.OnChanged)

func SetOnTraceChanged added in v0.7.19

func SetOnTraceChanged(funcs ...states.OnChanged)

func SetOnVerboseChanged added in v0.7.19

func SetOnVerboseChanged(funcs ...states.OnChanged)

func SetQuietLevel

func SetQuietLevel(hits int)

func SetQuietMode

func SetQuietMode(b bool)

func SetTraceLevel

func SetTraceLevel(hits int)

func SetTraceMode

func SetTraceMode(b bool)

func SetVerboseLevel

func SetVerboseLevel(hits int)

func SetVerboseMode

func SetVerboseMode(b bool)

func ShellName added in v0.5.27

func ShellName() string

ShellName returns current SHELL's name.

For Windows, it could be "cmd.exe" or "powershell.exe". For Linux or Unix or Darwin, it returns environment variable $SHELL. Else it's empty "".

func Signals added in v0.5.7

func Signals() signalS

Signals returns a signals-helper so that you can catch them, and raise them later.

Typically, its usage is `catcher := is.Signals().Catch(); ...`.

By default, catcher will listen on standard signals set: os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGINT.

But you can change them with:

is.Signals().Catch(os.Kill, os.Interrupt)

or:

is.Signals().Catch().WithSignals(os.Interrupt, os.Kill)

You should put your long-term codes inside `cb` of WaitFor(cb), and defer call to `closer()` in. The `closer()` is a param of `cb`.

For example:

package main

import (
  "context"
  "fmt"
  "os"
  "sync"

  "github.com/hedzr/env"
  "github.com/hedzr/go-socketlib/net"

  logz "logslog"
)

func main() {
  logz.SetLevel(logz.DebugLevel)

  server := net.NewServer(":7099")
  defer server.Close()

  ctx, cancel := context.WithCancel(context.Background())
  defer cancel()

  catcher := is.Signals().Catch()
  catcher.WithVerboseFn(func(msg string, args ...any) {
    logz.Debug(fmt.Sprintf("[verbose] %s", fmt.Sprintf(msg, args...)))
  }).
  WithOnSignalCaught(func(sig os.Signal, wg *sync.WaitGroup) {
    println()
    logz.Debug("signal caught", "sig", sig)
    if err := server.Shutdown(); err != nil {
    	logz.Error("server shutdown error", "err", err)
    }
    cancel()
  }).
  WaitFor(func(closer func()) {
    logz.Debug("entering looper's loop...")

    server.WithOnShutdown(func(err error) { closer() })
    err := server.StartAndServe(ctx)
    if err != nil {
      logz.Fatal("server serve failed", "err", err)
    }
  })
}

func Solaris added in v0.8.47

func Solaris() bool

Solaris returns true if running under Solaris platform.

func StartupByDoubleClick added in v0.5.9

func StartupByDoubleClick() bool

StartupByDoubleClick detects if windows golang executable file is running via double click or from cmd/shell terminator

func State added in v0.5.11

func State(stateName string) (state bool)

State returns a state with the given state name.

func States

func States() states.CmdrMinimal

States or Env returns a minimal environment settings for a typical CLI app.

See also states.CmdrMinimal.

func StdoutIsNormalFile added in v0.7.23

func StdoutIsNormalFile() bool

func StdoutIsTerminal added in v0.7.23

func StdoutIsTerminal() bool

func StdoutPiped added in v0.7.23

func StdoutPiped() bool

func StdoutRedirected added in v0.7.23

func StdoutRedirected() bool

func StdoutStat added in v0.7.23

func StdoutStat() (normalFile, redirected, piped, terminal bool)

func StringToBool added in v0.5.9

func StringToBool(val string, defaultVal ...bool) (ret bool)

StringToBool converts a string to boolean value.

func StripEscapes

func StripEscapes(str string) (strCleaned string)

StripEscapes removes any ansi color escaped sequences from a string

func Terminal added in v0.5.9

func Terminal(f *os.File) bool

Terminal returns whether the given file descriptor is a terminal. Terminal detects if a file is a terminal device (tty)

func TerminalFd added in v0.5.9

func TerminalFd(fd uintptr) bool

TerminalFd detects if a file-descriptor is a terminal device (tty)

func ToBool added in v0.5.9

func ToBool(val any, defaultVal ...bool) (ret bool)

ToBool converts a value (int, bool, string) to boolean

func TraceMode

func TraceMode() bool

func Tracing

func Tracing() bool

func Tty added in v0.5.1

func Tty(w io.Writer) bool

Tty detects a writer if it is abstracting from a tty (console, terminal) device.

func TtyEscaped added in v0.5.1

func TtyEscaped(s string) bool

TtyEscaped detects a string if it contains ansi color escaped sequences Deprecated v0.5.3, use HasAnsiEscaped

func Unix added in v0.5.27

func Unix() bool

Unix returns true for Linux, Darwin, and Others Unix-like Platforms.

[NOTE] for unix platforms, more assetions and tests needed.

func UpdateEnvWith

func UpdateEnvWith(env states.CmdrMinimal)

func VerboseBuild

func VerboseBuild() bool

func VerboseModeEnabled

func VerboseModeEnabled() bool

func WaitForSeconds added in v0.8.40

func WaitForSeconds(ctx context.Context, cancelFunc context.CancelFunc, duration time.Duration, opts ...CatcherOpt)

WaitForSeconds prompts a msg and waits for seconds, or user's pressing CTRL-C to quit.

package main

import (
	"context"
	"time"

	"github.com/hedzr/is"
	"github.com/hedzr/is/timing"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	p := timing.New()
	defer p.CalcNow()

	is.SignalsEnh().WaitForSeconds(ctx, cancel, 6*time.Second,
		// is.WithCatcherCloser(cancel),
		is.WithCatcherMsg("Press CTRL-C to quit, or waiting for 6s..."),
	)
}

func Wasip1 added in v0.8.47

func Wasip1() bool

Wasip1 returns true if running under Wasip1 platform.

func Windows added in v0.5.27

func Windows() bool

Windows returns true for Microsoft Windows Platform.

func WindowsWSL added in v0.5.27

func WindowsWSL() bool

WindowsWSL return true if running under Windows WSL env.

func Zos added in v0.8.47

func Zos() bool

Zos returns true if running under Zos platform.

func Zsh added in v0.5.27

func Zsh() bool

Zsh returns true if application is running under a Zsh shell.

Types

type CatcherOpt added in v0.8.40

type CatcherOpt func(s *SignalsX)

func WithCatcherCloser added in v0.8.40

func WithCatcherCloser(globalCloser func()) CatcherOpt

func WithCatcherDuration added in v0.8.40

func WithCatcherDuration(dur time.Duration) CatcherOpt

func WithCatcherMsg added in v0.8.40

func WithCatcherMsg(msg string) CatcherOpt

func WithCatcherSignals added in v0.8.40

func WithCatcherSignals(sigs ...os.Signal) CatcherOpt

type SignalsX added in v0.8.40

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

func SignalsEnh added in v0.8.40

func SignalsEnh() *SignalsX

SignalsEnh returns a rich-customized struct for operations.

func (SignalsX) Catch added in v0.8.40

func (s SignalsX) Catch(sig ...os.Signal) basics.Catcher

func (SignalsX) CurrentProcess added in v0.8.40

func (s SignalsX) CurrentProcess() *os.Process

func (SignalsX) Kill added in v0.8.40

func (s SignalsX) Kill() error

func (SignalsX) RaiseSignal added in v0.8.40

func (s SignalsX) RaiseSignal(sig os.Signal) error

RaiseSignal should throw a POSIX signal to current process.

It can work or not, see also the discusses at:

https://github.com/golang/go/issues/19326

In general cases, it works. But in some special scenes it notifies a quiet thread somewhere.

func (SignalsX) Wait added in v0.8.40

func (s SignalsX) Wait() (*os.ProcessState, error)

func (*SignalsX) WaitFor added in v0.8.40

func (s *SignalsX) WaitFor(ctx context.Context, opts ...CatcherOpt)

func (*SignalsX) WaitForContext added in v0.8.40

func (s *SignalsX) WaitForContext(ctx context.Context, cancelFunc context.CancelFunc, opts ...CatcherOpt)

func (*SignalsX) WaitForSeconds added in v0.8.40

func (s *SignalsX) WaitForSeconds(ctx context.Context, cancelFunc context.CancelFunc, duration time.Duration, opts ...CatcherOpt)

Directories

Path Synopsis
_examples
blocks command
color-tool command
colors command
pipe command
prompt command
small command
waitforseconds command
Package dir provides a series of directory/file operations
Package dir provides a series of directory/file operations
Package term provides support functions for dealing with terminals, as commonly found on UNIX systems.
Package term provides support functions for dealing with terminals, as commonly found on UNIX systems.
chk
Package chk provides some checked terminal utilities.
Package chk provides some checked terminal utilities.
color
Package color provides a wrapped standard output device like printf but with colored enhancements.
Package color provides a wrapped standard output device like printf but with colored enhancements.