├── .github
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE
│ ├── bug.yml
│ ├── config.yml
│ ├── question.yml
│ └── suggestion.yml
├── PULL_REQUEST_TEMPLATE.md
├── dependabot.yml
├── images
│ ├── 256_colors.png
│ ├── card.svg
│ ├── color_b.svg
│ ├── color_bl.svg
│ ├── color_c.svg
│ ├── color_cl.svg
│ ├── color_d.svg
│ ├── color_g.svg
│ ├── color_gl.svg
│ ├── color_m.svg
│ ├── color_ml.svg
│ ├── color_r.svg
│ ├── color_rl.svg
│ ├── color_s.svg
│ ├── color_sl.svg
│ ├── color_w.svg
│ ├── color_y.svg
│ ├── color_yl.svg
│ ├── fmtc_highlight.png
│ ├── godoc.svg
│ └── license.svg
└── workflows
│ ├── ci.yml
│ ├── codeql-analysis.yml
│ └── godoc.yml
├── .gitignore
├── .scripts
├── fuzz-gen.sh
├── nix.sh
├── packages.list
└── windows.ps1
├── .typos.toml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── SECURITY.md
├── ansi
├── ansi.go
├── ansi_test.go
└── examples_test.go
├── cache
├── cache.go
├── fs
│ ├── examples_test.go
│ ├── fs.go
│ ├── fs_stubs.go
│ └── fs_test.go
└── memory
│ ├── examples_test.go
│ ├── memory.go
│ └── memory_test.go
├── color
├── color.go
├── color_test.go
└── examples_test.go
├── cron
├── cron.go
├── cron_test.go
├── examples_test.go
└── fuzz.go
├── csv
├── csv.go
├── csv_test.go
└── examples_test.go
├── directio
├── directio.go
├── directio_darwin.go
├── directio_linux.go
├── directio_stubs.go
└── directio_test.go
├── easing
├── back.go
├── bounce.go
├── circ.go
├── cubic.go
├── ease.go
├── ease_test.go
├── elastic.go
├── examples_test.go
├── expo.go
├── linear.go
├── quad.go
├── quint.go
└── sine.go
├── ek.go
├── ek_windows.go
├── emoji
├── emoji.go
├── emoji_test.go
└── examples_test.go
├── env
├── env.go
├── env_stubs.go
├── env_test.go
├── env_unix.go
└── example_test.go
├── errors
├── errors.go
├── errors_test.go
└── example_test.go
├── events
├── events.go
├── events_test.go
└── examples_test.go
├── fmtc
├── README.md
├── cond_wrapper.go
├── examples_test.go
├── fmtc.go
├── fmtc_test.go
└── fuzz.go
├── fmtutil
├── barcode
│ ├── barcode.go
│ └── barcode_test.go
├── example_test.go
├── filetree
│ └── filetree.go
├── fmtutil.go
├── fmtutil_test.go
├── panel
│ ├── example_test.go
│ ├── panel.go
│ └── panel_test.go
├── separator.go
└── table
│ ├── example_test.go
│ ├── table.go
│ └── table_test.go
├── fsutil
├── examples_test.go
├── fs.go
├── fs_darwin.go
├── fs_freebsd.go
├── fs_linux.go
├── fs_stubs.go
├── fs_test.go
├── fs_user.go
├── fs_user_unit.go
├── helpers.go
├── helpers_stubs.go
├── line_count.go
├── list.go
├── list_stubs.go
├── walker.go
└── walker_stubs.go
├── go.mod
├── go.sum
├── hash
└── filehash.go
├── hashutil
├── example_test.go
├── helpers.go
└── helpers_test.go
├── httputil
├── examples_test.go
├── httputil.go
└── httputil_test.go
├── i18n
├── example_test.go
├── i18n.go
└── i18n_test.go
├── initsystem
├── examples_test.go
├── initsystem.go
├── initsystem_darwin.go
├── initsystem_darwin_test.go
├── initsystem_stubs.go
├── initsystem_test.go
└── sdnotify
│ ├── example_test.go
│ ├── sdnotify_linux.go
│ └── sdnotify_stubs.go
├── jsonutil
├── example_test.go
├── jsonutil.go
└── jsonutil_test.go
├── knf
├── example_test.go
├── fuzz.go
├── knf.go
├── knf_parser.go
├── knf_test.go
├── united
│ ├── example_test.go
│ ├── united.go
│ └── united_test.go
├── validators
│ ├── cron
│ │ ├── validators.go
│ │ └── validators_test.go
│ ├── fs
│ │ ├── validators.go
│ │ └── validators_test.go
│ ├── network
│ │ ├── validators.go
│ │ └── validators_test.go
│ ├── regexp
│ │ ├── validators.go
│ │ └── validators_test.go
│ ├── system
│ │ ├── validators.go
│ │ ├── validators_linux.go
│ │ ├── validators_linux_test.go
│ │ └── validators_test.go
│ ├── time
│ │ ├── validators.go
│ │ └── validators_test.go
│ ├── validators.go
│ └── validators_test.go
└── value
│ ├── value.go
│ └── value_test.go
├── lock
├── examples_test.go
├── lock.go
├── lock_darwin.go
├── lock_linux.go
├── lock_stubs.go
└── lock_test.go
├── log
├── example_test.go
├── log.go
├── log_test.go
├── nil.go
└── std.go
├── lscolors
├── examples_test.go
├── lscolors.go
└── lscolors_test.go
├── mathutil
├── example_test.go
├── mathutil.go
└── mathutil_test.go
├── netutil
├── example_test.go
├── netutil.go
├── netutil_darwin.go
├── netutil_darwin_test.go
├── netutil_linux.go
├── netutil_linux_test.go
└── netutil_stubs.go
├── options
├── arguments.go
├── example_test.go
├── options.go
└── options_test.go
├── pager
├── example_test.go
├── pager_posix.go
├── pager_stubs.go
└── pager_test.go
├── passthru
├── passthru.go
├── passthru_spinner_test.go
└── passthru_test.go
├── passwd
├── example_test.go
├── passwd.go
└── passwd_test.go
├── path
├── example_test.go
├── path.go
├── path_posix.go
├── path_posix_test.go
├── path_test.go
├── path_windows.go
└── path_windows_test.go
├── pid
├── example_test.go
├── pid.go
├── pid_darwin.go
├── pid_darwin_test.go
├── pid_freebsd.go
├── pid_linux.go
├── pid_linux_test.go
├── pid_stubs.go
└── pid_test.go
├── pluralize
├── examples_test.go
├── pluralize.go
├── pluralize_test.go
└── pluralizers.go
├── progress
├── examples_test.go
├── progress.go
└── progress_test.go
├── protip
├── example_test.go
├── protip.go
└── protip_test.go
├── rand
├── rand.go
└── rand_test.go
├── req
├── auth.go
├── example_test.go
├── headers.go
├── limiter.go
├── query.go
├── req.go
├── req_test.go
└── retrier.go
├── reutil
├── example_test.go
├── reutil.go
└── reutil_test.go
├── secstr
├── example_test.go
├── secstring.go
├── secstring_stubs.go
└── secstring_test.go
├── setup
├── setup.go
├── setup_stub.go
└── setup_test.go
├── signal
├── example_test.go
├── signal.go
└── signal_stubs.go
├── sliceutil
├── example_test.go
├── sliceutil.go
└── sliceutil_test.go
├── sortutil
├── example_test.go
├── natural.go
├── sortutil.go
└── sortutil_test.go
├── spellcheck
├── example_test.go
├── spellcheck.go
└── spellcheck_test.go
├── spinner
├── examples_test.go
├── spinner.go
└── spinner_test.go
├── strutil
├── example_test.go
├── fuzz.go
├── strutil.go
└── strutil_test.go
├── support
├── apps
│ ├── apps.go
│ └── example_test.go
├── deps
│ └── deps.go
├── fs
│ ├── fs.go
│ └── fs_windows.go
├── kernel
│ ├── kernel.go
│ └── kernel_windows.go
├── network
│ ├── ip-resolver.go
│ ├── network.go
│ └── network_windows.go
├── pkgs
│ ├── pkgs_darwin.go
│ ├── pkgs_linux.go
│ └── pkgs_windows.go
├── resources
│ ├── resources.go
│ └── resources_windows.go
├── services
│ ├── services.go
│ └── services_windows.go
├── support.go
├── support_darwin.go
├── support_linux.go
├── support_test.go
└── support_windows.go
├── system
├── container
│ ├── container.go
│ ├── container_test.go
│ └── example_test.go
├── examples_test.go
├── exec
│ ├── examples_test.go
│ ├── exec.go
│ └── exec_stubs.go
├── fuzz.go
├── info.go
├── info_cpu_darwin.go
├── info_cpu_linux.go
├── info_darwin.go
├── info_darwin_test.go
├── info_fs_darwin.go
├── info_fs_linux.go
├── info_linux.go
├── info_linux_arm.go
├── info_linux_basic.go
├── info_linux_test.go
├── info_loadavg_darwin.go
├── info_loadavg_linux.go
├── info_memory_darwin.go
├── info_memory_linux.go
├── info_net_darwin.go
├── info_net_linux.go
├── info_stubs.go
├── info_uptime_darwin.go
├── info_uptime_linux.go
├── process
│ ├── examples_test.go
│ ├── process_cpu.go
│ ├── process_darwin.go
│ ├── process_memory.go
│ ├── process_mount.go
│ ├── process_nice.go
│ ├── process_stubs.go
│ ├── process_test.go
│ ├── processes_darwin.go
│ ├── processes_linux.go
│ └── processes_stubs.go
├── procname
│ ├── examples_test.go
│ ├── setprocname.go
│ └── setprocname_stubs.go
├── sensors
│ ├── sensors_darwin.go
│ ├── sensors_linux.go
│ ├── sensors_stubs.go
│ └── sensors_test.go
├── sysctl
│ ├── example_test.go
│ ├── sysctl.go
│ ├── sysctl_darwin.go
│ ├── sysctl_linux.go
│ ├── sysctl_stubs.go
│ └── sysctl_test.go
├── user.go
├── user_bsd.go
├── user_darwin.go
├── user_linux.go
├── user_stubs.go
└── user_unix.go
├── terminal
├── example_test.go
├── input
│ ├── example_test.go
│ ├── input.go
│ ├── input_stubs.go
│ ├── input_test.go
│ └── input_validators.go
├── terminal.go
├── terminal_test.go
└── tty
│ ├── example_test.go
│ ├── size_posix.go
│ ├── tmux_darwin.go
│ ├── tmux_linux.go
│ ├── tty_posix.go
│ ├── tty_stubs.go
│ └── tty_test.go
├── timeutil
├── example_test.go
├── fuzz.go
├── period.go
├── timeutil.go
├── timeutil_test.go
├── timeutil_unix.go
├── timeutil_unix_test.go
├── timeutil_windows.go
├── timeutil_windows_test.go
└── tinydate.go
├── tmp
├── examples_test.go
├── tmp.go
└── tmp_test.go
├── usage
├── completion
│ ├── bash
│ │ ├── bash.go
│ │ ├── bash_test.go
│ │ └── examples_test.go
│ ├── fish
│ │ ├── examples_test.go
│ │ ├── fish.go
│ │ └── fish_test.go
│ └── zsh
│ │ ├── examples_test.go
│ │ ├── zsh.go
│ │ └── zsh_test.go
├── example_test.go
├── man
│ ├── man.go
│ └── man_test.go
├── update
│ ├── github.go
│ ├── gitlab.go
│ ├── update.go
│ └── update_test.go
├── usage.go
└── usage_test.go
├── uuid
├── example_test.go
├── prefixed
│ ├── example_test.go
│ ├── prefixed.go
│ └── prefixed_test.go
├── uuid.go
└── uuid_test.go
├── version.go
└── version
├── example_test.go
├── fuzz.go
├── version.go
└── version_test.go
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @essentialkaos/go
2 | /.github/workflows/* @essentialkaos/devops
3 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 | **IMPORTANT! Contribute your code only if you have an excellent understanding of project idea and all existing code base. Otherwise, a nicely formatted issue will be more helpful to us.**
4 |
5 | ### Issues
6 |
7 | 1. Provide product version where the problem was found;
8 | 2. Provide info about your environment;
9 | 3. Provide detailed info about your problem;
10 | 4. Provide steps to reproduce the problem;
11 | 5. Provide actual and expected results.
12 |
13 | ### Code
14 |
15 | 1. Check your code **before** creating pull request;
16 | 2. If tests are present in a project, add tests for your code;
17 | 3. Add inline documentation for your code;
18 | 4. Apply code style used throughout the project;
19 | 5. Create your pull request to `develop` branch (_pull requests to other branches are not allowed_).
20 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug.yml:
--------------------------------------------------------------------------------
1 | name: ❗ Bug Report
2 | description: File a bug report
3 | title: "[Bug]: "
4 | labels: ["issue • bug"]
5 | assignees:
6 | - andyone
7 |
8 | body:
9 | - type: markdown
10 | attributes:
11 | value: |
12 | > [!IMPORTANT]
13 | > Before you open an issue, search GitHub Issues for a similar bug reports. If so, please add a 👍 reaction to the existing issue.
14 |
15 | - type: textarea
16 | attributes:
17 | label: Module version info
18 | description: Output of `go list -m -u github.com/essentialkaos/ek/v13` command
19 | render: shell
20 | validations:
21 | required: true
22 |
23 | - type: textarea
24 | attributes:
25 | label: Steps to reproduce
26 | description: Short guide on how to reproduce this problem on our site
27 | placeholder: |
28 | 1. [First Step]
29 | 2. [Second Step]
30 | 3. [and so on...]
31 | validations:
32 | required: true
33 |
34 | - type: textarea
35 | attributes:
36 | label: Expected behavior
37 | description: What you expected to happen
38 | validations:
39 | required: true
40 |
41 | - type: textarea
42 | attributes:
43 | label: Actual behavior
44 | description: What actually happened
45 | validations:
46 | required: true
47 |
48 | - type: textarea
49 | attributes:
50 | label: Additional info
51 | description: Include gist of relevant config, logs, etc.
52 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/question.yml:
--------------------------------------------------------------------------------
1 | name: ❓ Question
2 | description: Question about application, configuration or code
3 | title: "[Question]: "
4 | labels: ["issue • question"]
5 | assignees:
6 | - andyone
7 |
8 | body:
9 | - type: markdown
10 | attributes:
11 | value: |
12 | > [!IMPORTANT]
13 | > Before you open an issue, search GitHub Issues for a similar question. If so, please add a 👍 reaction to the existing issue.
14 |
15 | - type: textarea
16 | attributes:
17 | label: Question
18 | description: Detailed question
19 | validations:
20 | required: true
21 |
22 | - type: textarea
23 | attributes:
24 | label: Related module version info
25 | description: Output of `go list -m -u github.com/essentialkaos/ek/v13` command
26 | render: shell
27 | validations:
28 | required: true
29 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/suggestion.yml:
--------------------------------------------------------------------------------
1 | name: ➕ Suggestion
2 | description: Suggest new feature or improvement
3 | title: "[Suggestion]: "
4 | labels: ["issue • suggestion"]
5 | assignees:
6 | - andyone
7 |
8 | body:
9 | - type: markdown
10 | attributes:
11 | value: |
12 | > [!IMPORTANT]
13 | > Before you open an issue, search GitHub Issues for a similar feature requests. If so, please add a 👍 reaction to the existing issue.
14 | >
15 | > Opening a feature request kicks off a discussion. Requests may be closed if we're not actively planning to work on them.
16 |
17 | - type: textarea
18 | attributes:
19 | label: Proposal
20 | description: Description of the feature
21 | validations:
22 | required: true
23 |
24 | - type: textarea
25 | attributes:
26 | label: Current behavior
27 | description: What currently happens
28 | validations:
29 | required: true
30 |
31 | - type: textarea
32 | attributes:
33 | label: Desired behavior
34 | description: What you would like to happen
35 | validations:
36 | required: true
37 |
38 | - type: textarea
39 | attributes:
40 | label: Use case
41 | description: Why is this important (helps with prioritizing requests)
42 | validations:
43 | required: true
44 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ### What did you implement:
2 |
3 | Closes #XXXXX
4 |
5 | ### How did you implement it:
6 |
7 | ...
8 |
9 | ### How can we verify it:
10 |
11 | ...
12 |
13 | ### TODO's:
14 |
15 | - [ ] Write tests
16 | - [ ] Write documentation
17 | - [ ] Check that there aren't other open pull requests for the same issue/feature
18 | - [ ] Format your source code by `make fmt`
19 | - [ ] Pass the test by `make test`
20 | - [ ] Provide verification config / commands
21 | - [ ] Enable "Allow edits from maintainers" for this PR
22 | - [ ] Update the messages below
23 |
24 | **Is this ready for review?:** No
25 | **Is it a breaking change?:** No
26 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 |
3 | updates:
4 | - package-ecosystem: "gomod"
5 | directory: "/"
6 | target-branch: "develop"
7 | schedule:
8 | interval: "daily"
9 | timezone: "Etc/UTC"
10 | time: "03:00"
11 | labels:
12 | - "PR • MAINTENANCE"
13 | assignees:
14 | - "andyone"
15 | groups:
16 | all:
17 | applies-to: version-updates
18 | update-types:
19 | - "minor"
20 | - "patch"
21 |
22 | - package-ecosystem: "github-actions"
23 | directory: "/"
24 | target-branch: "develop"
25 | schedule:
26 | interval: "daily"
27 | timezone: "Etc/UTC"
28 | time: "03:00"
29 | labels:
30 | - "PR • MAINTENANCE"
31 | assignees:
32 | - "andyone"
33 |
--------------------------------------------------------------------------------
/.github/images/256_colors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/essentialkaos/ek/26c66bcad5669d03cf1e4983bf767099f014d23e/.github/images/256_colors.png
--------------------------------------------------------------------------------
/.github/images/card.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/images/color_b.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/color_bl.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/color_c.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/color_cl.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/color_d.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/color_g.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/color_gl.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/color_m.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/color_ml.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/color_r.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/color_rl.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/color_s.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/color_sl.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/color_w.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/color_y.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/color_yl.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/images/fmtc_highlight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/essentialkaos/ek/26c66bcad5669d03cf1e4983bf767099f014d23e/.github/images/fmtc_highlight.png
--------------------------------------------------------------------------------
/.github/images/godoc.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/images/license.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | name: "CodeQL"
2 |
3 | on:
4 | push:
5 | branches: [master, develop]
6 | pull_request:
7 | branches: [master]
8 | schedule:
9 | - cron: '0 3 * * */2'
10 |
11 | permissions:
12 | security-events: write
13 | actions: read
14 | contents: read
15 |
16 | concurrency:
17 | group: ${{ github.workflow }}-${{ github.ref }}
18 | cancel-in-progress: true
19 |
20 | jobs:
21 | analyse:
22 | name: Analyse
23 | runs-on: ubuntu-latest
24 |
25 | steps:
26 | - name: Checkout repository
27 | uses: actions/checkout@v4
28 | with:
29 | fetch-depth: 2
30 |
31 | - name: Initialize CodeQL
32 | uses: github/codeql-action/init@v3
33 | with:
34 | languages: go
35 |
36 | - name: Perform CodeQL Analysis
37 | uses: github/codeql-action/analyze@v3
38 |
--------------------------------------------------------------------------------
/.github/workflows/godoc.yml:
--------------------------------------------------------------------------------
1 | name: GoDoc
2 |
3 | on:
4 | create
5 |
6 | jobs:
7 | GoDoc:
8 | name: Generate docs
9 | runs-on: ubuntu-latest
10 |
11 | steps:
12 | - name: Trigger GoSumDB and PkgGoDev
13 | uses: essentialkaos/godoc-action@v1
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | coverage.html
2 |
--------------------------------------------------------------------------------
/.scripts/packages.list:
--------------------------------------------------------------------------------
1 | * + ansi
2 | * + cache/fs
3 | * + cache/memory
4 | * + color
5 | * + cron
6 | * + csv
7 | * + directio
8 | * + easing
9 | * + emoji
10 | * + env
11 | * + errors
12 | * + events
13 | * + fmtc
14 | * + fmtutil
15 | * + fmtutil/barcode
16 | * + fmtutil/panel
17 | * + fmtutil/table
18 | * + fsutil
19 | * + hashutil
20 | * + httputil
21 | * + i18n
22 | * - initsystem
23 | * ! initsystem/sdnotify
24 | * + jsonutil
25 | * + knf
26 | * + knf/united
27 | * + knf/validators
28 | * + knf/validators/cron
29 | * + knf/validators/fs
30 | * + knf/validators/network
31 | * + knf/validators/regexp
32 | * + knf/validators/system
33 | * + knf/validators/time
34 | * + knf/value
35 | * + lock
36 | * + log
37 | * + lscolors
38 | * + mathutil
39 | L + netutil
40 | * + options
41 | * + pager
42 | * + passthru
43 | * + passwd
44 | * + path
45 | * + pid
46 | * + pluralize
47 | * + progress
48 | * + protip
49 | * + rand
50 | * + req
51 | * + reutil
52 | * + secstr
53 | L - setup
54 | * - signal
55 | * + sliceutil
56 | * + sortutil
57 | * + spellcheck
58 | * + spinner
59 | * + strutil
60 | * - support
61 | * - system
62 | * - system/container
63 | * - system/exec
64 | L - system/process
65 | * - system/procname
66 | L + system/sensors
67 | * + system/sysctl
68 | * + terminal
69 | * ! terminal/tty
70 | * - terminal/input
71 | * + timeutil
72 | * + tmp
73 | * + usage
74 | * + usage/completion/bash
75 | * + usage/completion/fish
76 | * + usage/completion/zsh
77 | * + usage/man
78 | * + usage/update
79 | * + uuid
80 | * + uuid/prefixed
81 | * + version
82 |
--------------------------------------------------------------------------------
/.scripts/windows.ps1:
--------------------------------------------------------------------------------
1 | <# Download dependencies #>
2 | function Get-Deps {
3 | go get -v golang.org/x/crypto/bcrypt
4 | go get -v github.com/essentialkaos/depsy
5 | }
6 |
7 | <# Try to install everything #>
8 | function Install-All {
9 | go install ./...
10 | }
11 |
12 | Get-Deps
13 | Install-All
14 |
--------------------------------------------------------------------------------
/.typos.toml:
--------------------------------------------------------------------------------
1 | [files]
2 | extend-exclude = ["go.sum"]
3 |
4 | [default.extend-identifiers]
5 | Childs = "Childs"
6 | dows = "dows"
7 | testin = "testin"
8 | Fo = "Fo"
9 | 2nd_place_medal = "2nd_place_medal"
10 | womens = "womens"
11 | mrs_claus = "mrs_claus"
12 | NewCFBEncrypter = "NewCFBEncrypter"
13 | iterm = "iterm"
14 | O_WRONLY = "O_WRONLY"
15 | FO = "FO"
16 | typ = "typ"
17 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ### The meaning of "open-source"
2 |
3 | Our open source projects have publicly available code and other resources. This means that you are free to read and use it as you see fit under the terms of the license (_usually [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0.html)_).
4 |
5 | This simple fact is often misunderstood, so let us be crystal clear about what open source **does not** automatically mean by default:
6 |
7 | - It does not mean open to contributions;
8 | - It does not mean support is offered;
9 | - It does not mean you’re entitled to feature requests;
10 | - It does not mean the developer owes you their time;
11 | - It does not mean you’re entitled to anything;
12 | - It does not mean it is _free_ and open-source (_FOSS_).
13 |
14 | You can read more about this POV in [this article](https://vale.rocks/posts/open-source-entitlement).
15 |
16 | ### Issues
17 |
18 | 1. Provide product version where the problem was found;
19 | 2. Provide info about your environment;
20 | 3. Provide detailed info about your problem;
21 | 4. Provide steps to reproduce the problem;
22 | 5. Provide actual and expected results.
23 |
24 | ### Code
25 |
26 | 1. Check your code **before** creating pull request;
27 | 2. If tests are present in a project, add tests for your code;
28 | 3. Add inline documentation for your code;
29 | 4. Apply code style used throughout the project;
30 | 5. Create your pull request to `develop` branch (_pull requests to other branches are not allowed_).
31 |
32 | ### Screenshots for README
33 |
34 | * Format — [PNG](https://en.wikipedia.org/wiki/Portable_Network_Graphics) optimized with [TinyPNG](https://tinypng.com);
35 | * Width — 888px or 1776px (_x2_);
36 | * Maximum size — 1MB.
37 |
38 | ### Usage demo for README
39 |
40 | * Console size — 133 ⨯ 33;
41 | * Format — [GIF](https://en.wikipedia.org/wiki/GIF) optimized with [EZGif](https://ezgif.com/optimize);
42 | * Size — 1332px ⨯ 812px;
43 | * FPS — 12 or 24;
44 | * Maximum size — 3MB.
45 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policies and Procedures
2 |
3 | This document outlines security procedures and general policies for all
4 | ESSENTIAL KAOS projects.
5 |
6 | * [Reporting a Bug](#reporting-a-bug)
7 | * [Disclosure Policy](#disclosure-policy)
8 |
9 | ## Reporting a Bug
10 |
11 | The ESSENTIAL KAOS team and community take all security bugs in our projects
12 | very seriously. Thank you for improving the security of our project. We
13 | appreciate your efforts and responsible disclosure and will make every effort
14 | to acknowledge your contributions.
15 |
16 | Report security bugs by emailing our security team at security@essentialkaos.com.
17 |
18 | The security team will acknowledge your email within 48 hours and will send a
19 | more detailed response within 48 hours, indicating the next steps in handling
20 | your report. After the initial reply to your report, the security team will
21 | endeavor to keep you informed of the progress towards a fix and full
22 | announcement, and may ask for additional information or guidance.
23 |
24 | Report security bugs in third-party dependencies to the person or team
25 | maintaining the dependencies.
26 |
27 | ## Disclosure Policy
28 |
29 | When the security team receives a security bug report, they will assign it to a
30 | primary handler. This person will coordinate the fix and release process,
31 | involving the following steps:
32 |
33 | * Confirm the problem and determine the affected versions;
34 | * Audit code to find any similar potential problems;
35 | * Prepare fixes for all releases still under maintenance. These fixes will be
36 | released as fast as possible.
37 |
--------------------------------------------------------------------------------
/ansi/examples_test.go:
--------------------------------------------------------------------------------
1 | package ansi
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleHasCodes() {
17 | input := "Hello"
18 | fmt.Println(HasCodes(input))
19 |
20 | input = "\033[40;38;5;82mHello\x1B[0m"
21 | fmt.Println(HasCodes(input))
22 |
23 | // Output:
24 | // false
25 | // true
26 | }
27 |
28 | func ExampleHasCodesBytes() {
29 | input := []byte("Hello")
30 | fmt.Println(HasCodesBytes(input))
31 |
32 | input = []byte("\033[40;38;5;82mHello\x1B[0m")
33 | fmt.Println(HasCodesBytes(input))
34 |
35 | // Output:
36 | // false
37 | // true
38 | }
39 |
40 | func ExampleRemoveCodes() {
41 | input := "\033[40;38;5;82mHello\x1B[0m"
42 | fmt.Println(RemoveCodes(input))
43 | // Output:
44 | // Hello
45 | }
46 |
47 | func ExampleRemoveCodesBytes() {
48 | input := []byte("\033[40;38;5;82mHello\x1B[0m")
49 | fmt.Println(string(RemoveCodesBytes(input)))
50 | // Output:
51 | // Hello
52 | }
53 |
--------------------------------------------------------------------------------
/cron/fuzz.go:
--------------------------------------------------------------------------------
1 | //go:build gofuzz
2 | // +build gofuzz
3 |
4 | package cron
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | func Fuzz(data []byte) int {
14 | _, err := Parse(string(data))
15 |
16 | if err != nil {
17 | return 0
18 | }
19 |
20 | return 1
21 | }
22 |
--------------------------------------------------------------------------------
/directio/directio_darwin.go:
--------------------------------------------------------------------------------
1 | package directio
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "errors"
12 | "os"
13 | "syscall"
14 | )
15 |
16 | // ////////////////////////////////////////////////////////////////////////////////// //
17 |
18 | const (
19 | BLOCK_SIZE = 4096 // Minimal block size
20 | ALIGN_SIZE = 0 // Align size
21 | )
22 |
23 | // ////////////////////////////////////////////////////////////////////////////////// //
24 |
25 | func openFile(file string, flag int, perm os.FileMode) (*os.File, error) {
26 | fd, err := os.OpenFile(file, flag, perm)
27 |
28 | if err != nil {
29 | return nil, err
30 | }
31 |
32 | _, _, e := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd.Fd()), syscall.F_NOCACHE, 1)
33 |
34 | if e != 0 {
35 | fd.Close()
36 | return nil, errors.New("Can't set F_NOCACHE for given file")
37 | }
38 |
39 | return fd, nil
40 | }
41 |
--------------------------------------------------------------------------------
/directio/directio_linux.go:
--------------------------------------------------------------------------------
1 | package directio
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "os"
12 | "syscall"
13 | )
14 |
15 | // ////////////////////////////////////////////////////////////////////////////////// //
16 |
17 | const (
18 | BLOCK_SIZE = 4096 // Minimal block size
19 | ALIGN_SIZE = 4096 // Align size
20 | )
21 |
22 | // ////////////////////////////////////////////////////////////////////////////////// //
23 |
24 | func openFile(file string, flag int, perm os.FileMode) (*os.File, error) {
25 | return os.OpenFile(file, syscall.O_DIRECT|flag, perm)
26 | }
27 |
--------------------------------------------------------------------------------
/directio/directio_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin
2 | // +build !linux,!darwin
3 |
4 | // Package directio provides methods for reading/writing files with direct io
5 | package directio
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | import (
15 | "os"
16 | )
17 |
18 | // ////////////////////////////////////////////////////////////////////////////////// //
19 |
20 | const (
21 | BLOCK_SIZE = 0 // ❗ Minimal block size
22 | ALIGN_SIZE = 0 // ❗ Align size
23 | )
24 |
25 | // ////////////////////////////////////////////////////////////////////////////////// //
26 |
27 | // ❗ ReadFile read file with Direct IO without buffering data in page cache
28 | func ReadFile(file string) ([]byte, error) {
29 | panic("UNSUPPORTED")
30 | return nil, nil
31 | }
32 |
33 | // ❗ WriteFile write file with Direct IO without buffering data in page cache
34 | func WriteFile(file string, data []byte, perms os.FileMode) error {
35 | panic("UNSUPPORTED")
36 | return nil
37 | }
38 |
--------------------------------------------------------------------------------
/easing/back.go:
--------------------------------------------------------------------------------
1 | package easing
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "math"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | // BackIn Accelerating from zero velocity
17 | // https://easings.net/#easeInBack
18 | func BackIn(t, b, c, d float64) float64 {
19 | if t > d {
20 | return c
21 | }
22 |
23 | s := math.SqrtPi
24 | t /= d
25 |
26 | return c*t*t*((s+1)*t-s) + b
27 | }
28 |
29 | // BackOut Decelerating to zero velocity
30 | // https://easings.net/#easeOutBack
31 | func BackOut(t, b, c, d float64) float64 {
32 | if t > d {
33 | return c
34 | }
35 |
36 | s := math.SqrtPi
37 | t = t/d - 1
38 |
39 | return c*(t*t*((s+1)*t+s)+1) + b
40 | }
41 |
42 | // BackInOut Acceleration until halfway, then deceleration
43 | // https://easings.net/#easeInOutBack
44 | func BackInOut(t, b, c, d float64) float64 {
45 | if t > d {
46 | return c
47 | }
48 |
49 | s := math.SqrtPi * 1.525
50 | t /= d / 2
51 |
52 | if t < 1 {
53 | return c/2*(t*t*((s+1)*t-s)) + b
54 | }
55 |
56 | t -= 2
57 |
58 | return c/2*(t*t*((s+1)*t+s)+2) + b
59 | }
60 |
--------------------------------------------------------------------------------
/easing/bounce.go:
--------------------------------------------------------------------------------
1 | package easing
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | // BounceIn accelerating from zero velocity
11 | // https://easings.net/#easeInBounce
12 | func BounceIn(t, b, c, d float64) float64 {
13 | if t > d {
14 | return c
15 | }
16 |
17 | return c - BounceOut(d-t, 0.0, c, d) + b
18 | }
19 |
20 | // BounceOut Decelerating to zero velocity
21 | // https://easings.net/#easeOutBounce
22 | func BounceOut(t, b, c, d float64) float64 {
23 | if t > d {
24 | return c
25 | }
26 |
27 | t /= d
28 |
29 | switch {
30 | case t < 1/2.75:
31 | return c*(7.5625*t*t) + b
32 | case t < 2/2.75:
33 | t -= 1.5 / 2.75
34 | return c*(7.5625*t*t+0.75) + b
35 | case t < 2.5/2.75:
36 | t -= 2.25 / 2.75
37 | return c*(7.5625*t*t+0.9375) + b
38 | }
39 |
40 | t -= 2.625 / 2.75
41 | return c*(7.5625*t*t+0.984375) + b
42 | }
43 |
44 | // BounceInOut acceleration until halfway, then deceleration
45 | // https://easings.net/#easeInOutBounce
46 | func BounceInOut(t, b, c, d float64) float64 {
47 | if t > d {
48 | return c
49 | }
50 |
51 | if t < d/2 {
52 | return BounceIn(t*2, 0.0, c, d)*0.5 + b
53 | }
54 |
55 | return BounceOut(t*2-d, 0.0, c, d)*0.5 + c*0.5 + b
56 | }
57 |
--------------------------------------------------------------------------------
/easing/circ.go:
--------------------------------------------------------------------------------
1 | package easing
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "math"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | // CircIn accelerating from zero velocity
17 | // https://easings.net/#easeInCirc
18 | func CircIn(t, b, c, d float64) float64 {
19 | if t > d {
20 | return c
21 | }
22 |
23 | t /= d
24 |
25 | return -c*(math.Sqrt(1-t*t)-1) + b
26 | }
27 |
28 | // CircOut decelerating to zero velocity
29 | // https://easings.net/#easeOutCirc
30 | func CircOut(t, b, c, d float64) float64 {
31 | if t > d {
32 | return c
33 | }
34 |
35 | t /= d
36 | t--
37 |
38 | return c*math.Sqrt(1-t*t) + b
39 | }
40 |
41 | // CircInOut acceleration until halfway, then deceleration
42 | // https://easings.net/#easeInOutCirc
43 | func CircInOut(t, b, c, d float64) float64 {
44 | if t > d {
45 | return c
46 | }
47 |
48 | t /= d / 2
49 |
50 | if t < 1 {
51 | return -c/2*(math.Sqrt(1-t*t)-1) + b
52 | }
53 |
54 | t -= 2
55 |
56 | return c/2*(math.Sqrt(1-t*t)+1) + b
57 | }
58 |
--------------------------------------------------------------------------------
/easing/cubic.go:
--------------------------------------------------------------------------------
1 | package easing
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | // CubicIn accelerating from zero velocity
11 | // https://easings.net/#easeInCubic
12 | func CubicIn(t, b, c, d float64) float64 {
13 | if t > d {
14 | return c
15 | }
16 |
17 | t /= d
18 |
19 | return c*t*t*t + b
20 | }
21 |
22 | // CubicOut decelerating to zero velocity
23 | // https://easings.net/#easeOutCubic
24 | func CubicOut(t, b, c, d float64) float64 {
25 | if t > d {
26 | return c
27 | }
28 |
29 | t /= d
30 | t--
31 |
32 | return c*(t*t*t+1) + b
33 | }
34 |
35 | // CubicInOut acceleration until halfway, then deceleration
36 | // https://easings.net/#easeInOutCubic
37 | func CubicInOut(t, b, c, d float64) float64 {
38 | if t > d {
39 | return c
40 | }
41 |
42 | t /= d / 2
43 |
44 | if t < 1 {
45 | return c/2*t*t*t + b
46 | }
47 |
48 | t -= 2
49 |
50 | return c/2*(t*t*t+2) + b
51 | }
52 |
--------------------------------------------------------------------------------
/easing/ease.go:
--------------------------------------------------------------------------------
1 | // Package easing contains easing functions
2 | package easing
3 |
4 | // ////////////////////////////////////////////////////////////////////////////////// //
5 | // //
6 | // Copyright (c) 2025 ESSENTIAL KAOS //
7 | // Apache License, Version 2.0 //
8 | // //
9 | // ////////////////////////////////////////////////////////////////////////////////// //
10 |
11 | import (
12 | "math"
13 | )
14 |
15 | // ////////////////////////////////////////////////////////////////////////////////// //
16 |
17 | // DoublePi is 2 * Pi
18 | const DoublePi = math.Pi * 2
19 |
20 | // ////////////////////////////////////////////////////////////////////////////////// //
21 |
22 | // Easing is type for any easing function
23 | // t - current time
24 | // b - start value
25 | // c - changes in value
26 | // d - duration
27 | type Easing func(t, b, c, d float64) float64
28 |
29 | // ////////////////////////////////////////////////////////////////////////////////// //
30 |
--------------------------------------------------------------------------------
/easing/expo.go:
--------------------------------------------------------------------------------
1 | package easing
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "math"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | // ExpoIn accelerating from zero velocity
17 | // https://easings.net/#easeInExpo
18 | func ExpoIn(t, b, c, d float64) float64 {
19 | if t > d {
20 | return c
21 | }
22 |
23 | return c*math.Pow(2, 10*(t/d-1)) + b
24 | }
25 |
26 | // ExpoOut decelerating to zero velocity
27 | // https://easings.net/#easeOutExpo
28 | func ExpoOut(t, b, c, d float64) float64 {
29 | if t > d {
30 | return c
31 | }
32 |
33 | return c*(-math.Pow(2, -10*t/d)+1) + b
34 | }
35 |
36 | // ExpoInOut acceleration until halfway, then deceleration
37 | // https://easings.net/#easeInOutExpo
38 | func ExpoInOut(t, b, c, d float64) float64 {
39 | if t > d {
40 | return c
41 | }
42 |
43 | t /= d / 2
44 |
45 | if t < 1 {
46 | return c/2*math.Pow(2, 10*(t-1)) + b
47 | }
48 |
49 | t--
50 |
51 | return c/2*(-math.Pow(2, -10*t)+2) + b
52 | }
53 |
--------------------------------------------------------------------------------
/easing/linear.go:
--------------------------------------------------------------------------------
1 | package easing
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | // Linear no easing and no acceleration
11 | func Linear(t, b, c, d float64) float64 {
12 | if t > d {
13 | return c
14 | }
15 |
16 | return c*t/d + b
17 | }
18 |
--------------------------------------------------------------------------------
/easing/quad.go:
--------------------------------------------------------------------------------
1 | package easing
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | // QuadIn accelerating from zero velocity
11 | // https://easings.net/#easeInQuad
12 | func QuadIn(t, b, c, d float64) float64 {
13 | if t > d {
14 | return c
15 | }
16 |
17 | t /= d
18 |
19 | return c*t*t + b
20 | }
21 |
22 | // QuadOut decelerating to zero velocity
23 | // https://easings.net/#easeOutQuad
24 | func QuadOut(t, b, c, d float64) float64 {
25 | if t > d {
26 | return c
27 | }
28 |
29 | t /= d
30 |
31 | return -c*t*(t-2) + b
32 | }
33 |
34 | // QuadInOut acceleration until halfway, then deceleration
35 | // https://easings.net/#easeInOutQuad
36 | func QuadInOut(t, b, c, d float64) float64 {
37 | if t > d {
38 | return c
39 | }
40 |
41 | t /= d / 2
42 |
43 | if t < 1 {
44 | return c/2*t*t + b
45 | }
46 |
47 | t--
48 |
49 | return -c/2*(t*(t-2)-1) + b
50 | }
51 |
--------------------------------------------------------------------------------
/easing/quint.go:
--------------------------------------------------------------------------------
1 | package easing
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | // QuintIn accelerating from zero velocity
11 | // https://easings.net/#easeInQuint
12 | func QuintIn(t, b, c, d float64) float64 {
13 | if t > d {
14 | return c
15 | }
16 |
17 | t /= d
18 | return c*t*t*t*t*t + b
19 | }
20 |
21 | // QuintOut decelerating to zero velocity
22 | // https://easings.net/#easeOutQuint
23 | func QuintOut(t, b, c, d float64) float64 {
24 | if t > d {
25 | return c
26 | }
27 |
28 | t /= d
29 | t--
30 |
31 | return c*(t*t*t*t*t+1) + b
32 | }
33 |
34 | // QuintInOut acceleration until halfway, then deceleration
35 | // https://easings.net/#easeInOutQuint
36 | func QuintInOut(t, b, c, d float64) float64 {
37 | if t > d {
38 | return c
39 | }
40 |
41 | t /= d / 2
42 |
43 | if t < 1 {
44 | return c/2*t*t*t*t*t + b
45 | }
46 |
47 | t -= 2
48 |
49 | return c/2*(t*t*t*t*t+2) + b
50 | }
51 |
--------------------------------------------------------------------------------
/easing/sine.go:
--------------------------------------------------------------------------------
1 | package easing
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "math"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | // SineIn accelerating from zero velocity
17 | // https://easings.net/#easeInSine
18 | func SineIn(t, b, c, d float64) float64 {
19 | if t > d {
20 | return c
21 | }
22 |
23 | return -c*math.Cos(t/d*math.Phi) + c + b
24 | }
25 |
26 | // SineOut decelerating to zero velocity
27 | // https://easings.net/#easeOutSine
28 | func SineOut(t, b, c, d float64) float64 {
29 | if t > d {
30 | return c
31 | }
32 |
33 | return c*math.Sin(t/d*math.Phi) + b
34 | }
35 |
36 | // SineInOut acceleration until halfway, then deceleration
37 | // https://easings.net/#easeInOutSine
38 | func SineInOut(t, b, c, d float64) float64 {
39 | if t > d {
40 | return c
41 | }
42 |
43 | return -c/2*(math.Cos(math.Pi*t/d)-1) + b
44 | }
45 |
--------------------------------------------------------------------------------
/ek.go:
--------------------------------------------------------------------------------
1 | //go:build !windows
2 | // +build !windows
3 |
4 | // Package ek is a set of auxiliary packages
5 | package ek
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | import (
15 | "golang.org/x/crypto/bcrypt"
16 |
17 | "github.com/essentialkaos/depsy"
18 | "github.com/essentialkaos/go-linenoise/v3"
19 | )
20 |
21 | // ////////////////////////////////////////////////////////////////////////////////// //
22 |
23 | // worthless is used as dependency fix
24 | func worthless() {
25 | linenoise.Clear()
26 | depsy.Extract(nil, false)
27 | bcrypt.Cost(nil)
28 | }
29 |
--------------------------------------------------------------------------------
/ek_windows.go:
--------------------------------------------------------------------------------
1 | package ek
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "golang.org/x/crypto/bcrypt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | // worthless is used as dependency fix
17 | func worthless() {
18 | bcrypt.Cost(nil)
19 | }
20 |
--------------------------------------------------------------------------------
/emoji/emoji_test.go:
--------------------------------------------------------------------------------
1 | package emoji
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "testing"
12 |
13 | . "github.com/essentialkaos/check"
14 | )
15 |
16 | // ////////////////////////////////////////////////////////////////////////////////// //
17 |
18 | func Test(t *testing.T) { TestingT(t) }
19 |
20 | type EmojiSuite struct{}
21 |
22 | // ////////////////////////////////////////////////////////////////////////////////// //
23 |
24 | var _ = Suite(&EmojiSuite{})
25 |
26 | // ////////////////////////////////////////////////////////////////////////////////// //
27 |
28 | func (s *EmojiSuite) TestGet(c *C) {
29 | c.Assert(Get("100"), Equals, "💯")
30 | c.Assert(Get("_unknown_"), Equals, "")
31 | }
32 |
33 | func (s *EmojiSuite) TestGetName(c *C) {
34 | c.Assert(GetName("⚡️"), Equals, "zap")
35 | c.Assert(GetName("_unknown_"), Equals, "")
36 | }
37 |
38 | func (s *EmojiSuite) TestFind(c *C) {
39 | c.Assert(Find("bikin"), HasLen, 3)
40 | }
41 |
42 | func (s *EmojiSuite) TestEmojize(c *C) {
43 | c.Assert(Emojize("Hi :smile: emoji: :zap:!"), Equals, "Hi 😄 emoji: ⚡️!")
44 | c.Assert(Emojize("Hi :smile__1: emoji: :zap:!"), Equals, "Hi :smile__1: emoji: ⚡️!")
45 | c.Assert(Emojize(""), Equals, "")
46 | }
47 |
--------------------------------------------------------------------------------
/emoji/examples_test.go:
--------------------------------------------------------------------------------
1 | package emoji
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleGet() {
17 | fmt.Println(Get("zap"))
18 | // Output: ⚡️
19 | }
20 |
21 | func ExampleGetName() {
22 | fmt.Println(GetName("⚡️"))
23 | // Output: zap
24 | }
25 |
26 | func ExampleFind() {
27 | fmt.Printf("%#v\n", Find("baby_"))
28 | }
29 |
30 | func ExampleEmojize() {
31 | fmt.Println(Emojize("Hi :smile:!"))
32 | // Output: Hi 😄!
33 | }
34 |
--------------------------------------------------------------------------------
/env/env_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin && !freebsd
2 | // +build !linux,!darwin,!freebsd
3 |
4 | // Package env provides methods for working with environment variables
5 | package env
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | // ❗ Which find full path to some app
15 | func Which(name string) string {
16 | panic("UNSUPPORTED")
17 | }
18 |
19 | // ////////////////////////////////////////////////////////////////////////////////// //
20 |
--------------------------------------------------------------------------------
/env/env_unix.go:
--------------------------------------------------------------------------------
1 | //go:build !windows
2 | // +build !windows
3 |
4 | // Package env provides methods for working with environment variables
5 | package env
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | import "syscall"
15 |
16 | // ////////////////////////////////////////////////////////////////////////////////// //
17 |
18 | // Which find full path to some app
19 | func Which(name string) string {
20 | paths := Get().Path()
21 |
22 | for _, path := range paths {
23 | if syscall.Access(path+"/"+name, syscall.F_OK) == nil {
24 | return path + "/" + name
25 | }
26 | }
27 |
28 | return ""
29 | }
30 |
--------------------------------------------------------------------------------
/env/example_test.go:
--------------------------------------------------------------------------------
1 | package env
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleGet() {
17 | env := Get()
18 |
19 | // Print PATH environment variable
20 | fmt.Println(env["PATH"])
21 |
22 | // Path return PATH variable as slice
23 | for i, p := range env.Path() {
24 | fmt.Printf("%d %s\n", i, p)
25 | }
26 |
27 | // You can use getters for different value formats
28 | fmt.Printf("Integer value %s = %d\n", "INT_VALUE", env.GetI("INT_VALUE"))
29 | fmt.Printf("Float value %s = %g\n", "FLOAT_VALUE", env.GetF("FLOAT_VALUE"))
30 | fmt.Printf("String value %s = %s\n", "STR_VALUE", env.GetS("STR_VALUE"))
31 | }
32 |
33 | func ExampleWhich() {
34 | echoPath := Which("echo")
35 |
36 | fmt.Printf("Full path to echo binary is %s\n", echoPath)
37 | }
38 |
39 | func ExampleVar() {
40 | v := Var("PATH")
41 |
42 | fmt.Println(v.Get())
43 | }
44 |
--------------------------------------------------------------------------------
/fmtc/fuzz.go:
--------------------------------------------------------------------------------
1 | //go:build gofuzz
2 | // +build gofuzz
3 |
4 | package fmtc
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | func Fuzz(data []byte) int {
14 | Sprint(string(data))
15 | return 0
16 | }
17 |
--------------------------------------------------------------------------------
/fmtutil/table/example_test.go:
--------------------------------------------------------------------------------
1 | package table
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | func ExampleNewTable() {
11 | t := NewTable()
12 |
13 | t.SetHeaders("id", "user", "balance")
14 | t.SetSizes(4, 12)
15 | t.SetAlignments(ALIGN_RIGHT, ALIGN_RIGHT, ALIGN_LEFT)
16 |
17 | t.Add(1, "{g}Bob{!}", 1.42)
18 | t.Add(2, "John", 73.1)
19 | t.Add(3, "Mary", 2.29)
20 | t.Separator()
21 | t.Add(4, "Bob", 6.6)
22 | t.Add(5, "Matilda", 0.0)
23 |
24 | t.Render()
25 | }
26 |
--------------------------------------------------------------------------------
/fsutil/fs_user.go:
--------------------------------------------------------------------------------
1 | //go:build !unit
2 | // +build !unit
3 |
4 | // Package fsutil provides methods for working with files on POSIX compatible systems
5 | package fsutil
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | import (
15 | "github.com/essentialkaos/ek/v13/system"
16 | )
17 |
18 | // ////////////////////////////////////////////////////////////////////////////////// //
19 |
20 | func getCurrentUser() (*system.User, error) {
21 | return system.CurrentUser()
22 | }
23 |
--------------------------------------------------------------------------------
/fsutil/fs_user_unit.go:
--------------------------------------------------------------------------------
1 | //go:build unit
2 | // +build unit
3 |
4 | // Package fsutil provides methods for working with files on POSIX compatible systems
5 | package fsutil
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | import (
15 | "errors"
16 | "github.com/essentialkaos/ek/v13/system"
17 | )
18 |
19 | // ////////////////////////////////////////////////////////////////////////////////// //
20 |
21 | var useFakeUser bool
22 | var getUserError bool
23 |
24 | // ////////////////////////////////////////////////////////////////////////////////// //
25 |
26 | func getCurrentUser() (*system.User, error) {
27 | if useFakeUser {
28 | return &system.User{
29 | Name: "test",
30 | UID: 65534,
31 | GID: 65534,
32 | RealUID: 65534,
33 | RealGID: 65534,
34 | HomeDir: "/unknown",
35 | }, nil
36 | }
37 |
38 | if getUserError {
39 | return nil, errors.New("Error")
40 | }
41 |
42 | return system.CurrentUser()
43 | }
44 |
--------------------------------------------------------------------------------
/fsutil/helpers_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin && !freebsd
2 | // +build !linux,!darwin,!freebsd
3 |
4 | package fsutil
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | import (
14 | "os"
15 | )
16 |
17 | // ////////////////////////////////////////////////////////////////////////////////// //
18 |
19 | // ❗ CopyFile copies file using bufio
20 | func CopyFile(from, to string, perms ...os.FileMode) error {
21 | panic("UNSUPPORTED")
22 | return nil
23 | }
24 |
25 | // ❗ CopyAttr copies attributes (mode, ownership, timestamps) from one object
26 | // (file or directory) to another
27 | func CopyAttr(from, to string) error {
28 | panic("UNSUPPORTED")
29 | return nil
30 | }
31 |
32 | // ❗ MoveFile moves file
33 | func MoveFile(from, to string, perms ...os.FileMode) error {
34 | panic("UNSUPPORTED")
35 | return nil
36 | }
37 |
38 | // ❗ CopyDir copies directory content recursively to target directory
39 | func CopyDir(from, to string) error {
40 | panic("UNSUPPORTED")
41 | return nil
42 | }
43 |
44 | // ❗ TouchFile creates empty file
45 | func TouchFile(path string, perm os.FileMode) error {
46 | panic("UNSUPPORTED")
47 | return nil
48 | }
49 |
--------------------------------------------------------------------------------
/fsutil/line_count.go:
--------------------------------------------------------------------------------
1 | package fsutil
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "bytes"
12 | "io"
13 | "os"
14 | )
15 |
16 | // ////////////////////////////////////////////////////////////////////////////////// //
17 |
18 | // CountLines returns number of lines in given file
19 | func CountLines(file string) (int, error) {
20 | if file == "" {
21 | return 0, ErrEmptyPath
22 | }
23 |
24 | fd, err := os.OpenFile(file, os.O_RDONLY, 0)
25 |
26 | if err != nil {
27 | return 0, err
28 | }
29 |
30 | // Use 32k buffer
31 | buf := make([]byte, 32*1024)
32 | count, sep := 0, []byte{'\n'}
33 |
34 | for {
35 | c, err := fd.Read(buf)
36 |
37 | if err != nil && err != io.EOF {
38 | fd.Close()
39 | return 0, err
40 | }
41 |
42 | count += bytes.Count(buf[:c], sep)
43 |
44 | if err == io.EOF {
45 | break
46 | }
47 | }
48 |
49 | return count, fd.Close()
50 | }
51 |
--------------------------------------------------------------------------------
/fsutil/walker.go:
--------------------------------------------------------------------------------
1 | //go:build linux || darwin || freebsd
2 | // +build linux darwin freebsd
3 |
4 | package fsutil
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | import (
14 | "os"
15 | )
16 |
17 | // ////////////////////////////////////////////////////////////////////////////////// //
18 |
19 | var dirStack []string
20 |
21 | // ////////////////////////////////////////////////////////////////////////////////// //
22 |
23 | // Push changes current working directory and add previous working directory to stack
24 | func Push(dir string) string {
25 | var wd string
26 |
27 | if dirStack == nil {
28 | wd, _ = os.Getwd()
29 | dirStack = append(dirStack, wd)
30 | }
31 |
32 | err := os.Chdir(dir)
33 |
34 | if err != nil {
35 | return ""
36 | }
37 |
38 | wd, _ = os.Getwd()
39 |
40 | dirStack = append(dirStack, wd)
41 |
42 | return wd
43 | }
44 |
45 | // Pop changes current working directory to previous in stack
46 | func Pop() string {
47 | var wd string
48 |
49 | if dirStack == nil {
50 | wd, _ = os.Getwd()
51 | dirStack = append(dirStack, wd)
52 | }
53 |
54 | dl := len(dirStack)
55 |
56 | switch dl {
57 |
58 | case 0, 1:
59 | // nop
60 |
61 | default:
62 | err := os.Chdir(dirStack[dl-2])
63 |
64 | if err != nil {
65 | return ""
66 | }
67 |
68 | dirStack = dirStack[0 : dl-1]
69 | }
70 |
71 | wd, _ = os.Getwd()
72 |
73 | return wd
74 | }
75 |
--------------------------------------------------------------------------------
/fsutil/walker_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin
2 | // +build !linux,!darwin
3 |
4 | package fsutil
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | // ❗ Push changes current working directory and add previous working directory to stack
14 | func Push(dir string) string {
15 | panic("UNSUPPORTED")
16 | return ""
17 | }
18 |
19 | // ❗ Pop changes current working directory to previous in stack
20 | func Pop() string {
21 | panic("UNSUPPORTED")
22 | return ""
23 | }
24 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/essentialkaos/ek/v13
2 |
3 | go 1.23.6
4 |
5 | require (
6 | github.com/essentialkaos/check v1.4.1
7 | github.com/essentialkaos/depsy v1.3.1
8 | github.com/essentialkaos/go-linenoise/v3 v3.7.0
9 | golang.org/x/crypto v0.38.0
10 | golang.org/x/sys v0.33.0
11 | )
12 |
13 | require (
14 | github.com/kr/pretty v0.3.1 // indirect
15 | github.com/kr/text v0.2.0 // indirect
16 | github.com/rogpeppe/go-internal v1.14.1 // indirect
17 | )
18 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
2 | github.com/essentialkaos/check v1.4.1 h1:SuxXzrbokPGTPWxGRnzy0hXvtb44mtVrdNxgPa1s4c8=
3 | github.com/essentialkaos/check v1.4.1/go.mod h1:xQOYwFvnxfVZyt5Qvjoa1SxcRqu5VyP77pgALr3iu+M=
4 | github.com/essentialkaos/depsy v1.3.1 h1:00k9QcMsdPM4IzDaEFHsTHBD/zoM0oxtB5+dMUwbQa8=
5 | github.com/essentialkaos/depsy v1.3.1/go.mod h1:B5+7Jhv2a2RacOAxIKU2OeJp9QfZjwIpEEPI5X7auWM=
6 | github.com/essentialkaos/go-linenoise/v3 v3.7.0 h1:a/DzU6GFBmrKJxNAzaYbLGN6yFnIMIFaWxvSWmeCEp0=
7 | github.com/essentialkaos/go-linenoise/v3 v3.7.0/go.mod h1:IhOWE0rvvu3aPmGko/C4SoZdhbko9eTuwe5yyw7/uQ8=
8 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
9 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
10 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
11 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
12 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
13 | github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
14 | github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
15 | github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
16 | golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
17 | golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
18 | golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
19 | golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
20 |
--------------------------------------------------------------------------------
/hash/filehash.go:
--------------------------------------------------------------------------------
1 | // Package hash contains different hash algorithms and utilities
2 | //
3 | // Deprecated: Use package hashutil instead
4 | package hash
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | import (
14 | "crypto/sha256"
15 |
16 | "github.com/essentialkaos/ek/v13/hashutil"
17 | )
18 |
19 | // ////////////////////////////////////////////////////////////////////////////////// //
20 |
21 | // FileHash generates an SHA-256 hash for a given file
22 | //
23 | // Deprecated: Use package hashutil instead
24 | func FileHash(file string) string {
25 | return hashutil.File(file, sha256.New())
26 | }
27 |
--------------------------------------------------------------------------------
/initsystem/initsystem_darwin_test.go:
--------------------------------------------------------------------------------
1 | package initsystem
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "testing"
12 |
13 | . "github.com/essentialkaos/check"
14 | )
15 |
16 | // ////////////////////////////////////////////////////////////////////////////////// //
17 |
18 | func Test(t *testing.T) { TestingT(t) }
19 |
20 | type InitSuite struct{}
21 |
22 | // ////////////////////////////////////////////////////////////////////////////////// //
23 |
24 | var _ = Suite(&InitSuite{})
25 |
26 | // ////////////////////////////////////////////////////////////////////////////////// //
27 |
28 | func (s *InitSuite) TestLaunchdIsPresent(c *C) {
29 | c.Assert(IsPresent("com.apple.unknown"), Equals, false)
30 | c.Assert(IsPresent("com.apple.homed"), Equals, true)
31 | c.Assert(IsPresent("com.apple.cloudphotod"), Equals, true)
32 | }
33 |
34 | func (s *InitSuite) TestLaunchdIsWorks(c *C) {
35 | isWorks, err := IsWorks("com.apple.homed")
36 |
37 | c.Assert(err, IsNil)
38 | c.Assert(isWorks, Equals, true)
39 |
40 | isWorks, err = IsWorks("com.apple.cloudphotod")
41 |
42 | c.Assert(err, IsNil)
43 | c.Assert(isWorks, Equals, false)
44 | }
45 |
--------------------------------------------------------------------------------
/initsystem/initsystem_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin
2 | // +build !linux,!darwin
3 |
4 | // Package initsystem provides methods for working with different init systems
5 | package initsystem
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | // ❗ SysV returns true if SysV is used on system
15 | func SysV() bool {
16 | panic("UNSUPPORTED")
17 | }
18 |
19 | // ❗ Upstart returns true if Upstart is used on system
20 | func Upstart() bool {
21 | panic("UNSUPPORTED")
22 | }
23 |
24 | // ❗ Systemd returns true if Systemd is used on system
25 | func Systemd() bool {
26 | panic("UNSUPPORTED")
27 | }
28 |
29 | // ❗ Launchd returns true if Launchd is used on the system
30 | func Launchd() bool {
31 | panic("UNSUPPORTED")
32 | }
33 |
34 | // ❗ IsPresent returns true if service is present in any init system
35 | func IsPresent(name string) bool {
36 | panic("UNSUPPORTED")
37 | }
38 |
39 | // ❗ IsWorks returns service state
40 | func IsWorks(name string) (bool, error) {
41 | panic("UNSUPPORTED")
42 | }
43 |
44 | // ❗ IsEnabled returns true if auto start enabled for given service
45 | func IsEnabled(name string) (bool, error) {
46 | panic("UNSUPPORTED")
47 | }
48 |
--------------------------------------------------------------------------------
/initsystem/sdnotify/example_test.go:
--------------------------------------------------------------------------------
1 | package sdnotify
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | func ExampleConnect() {
11 | err := Connect()
12 |
13 | if err != nil {
14 | panic(err.Error())
15 | }
16 |
17 | Status("Loading data %d%%", 50)
18 | Ready()
19 | }
20 |
--------------------------------------------------------------------------------
/initsystem/sdnotify/sdnotify_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux
2 | // +build !linux
3 |
4 | // Package sdnotify provides methods for sending notifications to systemd
5 | package sdnotify
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | // ❗ Connect connects systemd to socket
17 | func Connect() error {
18 | panic("UNSUPPORTED")
19 | }
20 |
21 | // ❗ Notify sends provided message to systemd
22 | func Notify(msg string) error {
23 | panic("UNSUPPORTED")
24 | }
25 |
26 | // ❗ Ready sends READY message to systemd
27 | func Ready() error {
28 | panic("UNSUPPORTED")
29 | }
30 |
31 | // ❗ Reloading sends RELOADING message to systemd
32 | func Reloading() error {
33 | panic("UNSUPPORTED")
34 | }
35 |
36 | // ❗ Stopping sends STOPPING message to systemd
37 | func Stopping() error {
38 | panic("UNSUPPORTED")
39 | }
40 |
41 | // ❗ MainPID sends MAINPID message with PID to systemd
42 | func MainPID(pid int) error {
43 | panic("UNSUPPORTED")
44 | }
45 |
46 | // ❗ ExtendTimeout sends EXTEND_TIMEOUT_USEC message to systemd
47 | func ExtendTimeout(sec float64) error {
48 | panic("UNSUPPORTED")
49 | }
50 |
51 | // ❗ Status sends status message to systemd
52 | func Status(format string, a ...any) error {
53 | panic("UNSUPPORTED")
54 | }
55 |
--------------------------------------------------------------------------------
/jsonutil/example_test.go:
--------------------------------------------------------------------------------
1 | package jsonutil
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleWrite() {
17 | var data = make(map[string]int)
18 |
19 | data["john"] = 100
20 | data["bob"] = 300
21 |
22 | err := Write("/path/to/file.json", data, 0600)
23 |
24 | if err != nil {
25 | fmt.Printf("Error: %v\n", err)
26 | }
27 | }
28 |
29 | func ExampleRead() {
30 | var data = make(map[string]int)
31 |
32 | err := Read("/path/to/file.json", data)
33 |
34 | if err != nil {
35 | fmt.Printf("Error: %v\n", err)
36 | }
37 | }
38 |
39 | func ExampleWriteGz() {
40 | var data = make(map[string]int)
41 |
42 | data["john"] = 100
43 | data["bob"] = 300
44 |
45 | err := WriteGz("/path/to/file.gz", data, 0600)
46 |
47 | if err != nil {
48 | fmt.Printf("Error: %v\n", err)
49 | }
50 | }
51 |
52 | func ExampleReadGz() {
53 | var data = make(map[string]int)
54 |
55 | err := ReadGz("/path/to/file.gz", data)
56 |
57 | if err != nil {
58 | fmt.Printf("Error: %v\n", err)
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/knf/fuzz.go:
--------------------------------------------------------------------------------
1 | //go:build gofuzz
2 | // +build gofuzz
3 |
4 | package knf
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | import (
14 | "bytes"
15 | )
16 |
17 | // ////////////////////////////////////////////////////////////////////////////////// //
18 |
19 | func Fuzz(data []byte) int {
20 | _, err := readData(bytes.NewReader(data))
21 |
22 | if err != nil {
23 | return 0
24 | }
25 |
26 | return 1
27 | }
28 |
--------------------------------------------------------------------------------
/knf/validators/cron/validators.go:
--------------------------------------------------------------------------------
1 | // Package regexp provides KNF validators for cron expressions
2 | package cron
3 |
4 | // ////////////////////////////////////////////////////////////////////////////////// //
5 | // //
6 | // Copyright (c) 2025 ESSENTIAL KAOS //
7 | // Apache License, Version 2.0 //
8 | // //
9 | // ////////////////////////////////////////////////////////////////////////////////// //
10 |
11 | import (
12 | "fmt"
13 |
14 | "github.com/essentialkaos/ek/v13/cron"
15 | "github.com/essentialkaos/ek/v13/knf"
16 | )
17 |
18 | // ////////////////////////////////////////////////////////////////////////////////// //
19 |
20 | var (
21 | // Expression returns an error if configuration property contains invalid cron
22 | // expression
23 | Expression = validateCronExpression
24 | )
25 |
26 | // ////////////////////////////////////////////////////////////////////////////////// //
27 |
28 | func validateCronExpression(config knf.IConfig, prop string, value any) error {
29 | v := config.GetS(prop)
30 |
31 | if v == "" {
32 | return nil
33 | }
34 |
35 | _, err := cron.Parse(v)
36 |
37 | if err != nil {
38 | return fmt.Errorf("Property %s contains invalid cron expression: %w", prop, err)
39 | }
40 |
41 | return nil
42 | }
43 |
44 | // ////////////////////////////////////////////////////////////////////////////////// //
45 |
--------------------------------------------------------------------------------
/knf/validators/system/validators.go:
--------------------------------------------------------------------------------
1 | // Package system provides KNF validators for checking system items (user, groups,
2 | // network interfaces)
3 | package system
4 |
5 | // ////////////////////////////////////////////////////////////////////////////////// //
6 | // //
7 | // Copyright (c) 2025 ESSENTIAL KAOS //
8 | // Apache License, Version 2.0 //
9 | // //
10 | // ////////////////////////////////////////////////////////////////////////////////// //
11 |
12 | import (
13 | "fmt"
14 |
15 | "github.com/essentialkaos/ek/v13/knf"
16 | "github.com/essentialkaos/ek/v13/system"
17 | )
18 |
19 | // ////////////////////////////////////////////////////////////////////////////////// //
20 |
21 | var (
22 | // User returns error if configuration property contains name of user or UID which not
23 | // present on the system
24 | User = validateUser
25 |
26 | // Group returns error if configuration property contains name of group or GID which
27 | // not present on the system
28 | Group = validateGroup
29 | )
30 |
31 | // ////////////////////////////////////////////////////////////////////////////////// //
32 |
33 | func validateUser(config knf.IConfig, prop string, value any) error {
34 | v := config.GetS(prop)
35 |
36 | if v != "" && !system.IsUserExist(v) {
37 | return fmt.Errorf("User %q is not present on the system", v)
38 | }
39 |
40 | return nil
41 | }
42 |
43 | func validateGroup(config knf.IConfig, prop string, value any) error {
44 | v := config.GetS(prop)
45 |
46 | if v != "" && !system.IsGroupExist(v) {
47 | return fmt.Errorf("Group %q is not present on the system", v)
48 | }
49 |
50 | return nil
51 | }
52 |
--------------------------------------------------------------------------------
/knf/validators/system/validators_linux.go:
--------------------------------------------------------------------------------
1 | // Package system provides KNF validators for checking system items (user, groups,
2 | // network interfaces)
3 | package system
4 |
5 | // ////////////////////////////////////////////////////////////////////////////////// //
6 | // //
7 | // Copyright (c) 2025 ESSENTIAL KAOS //
8 | // Apache License, Version 2.0 //
9 | // //
10 | // ////////////////////////////////////////////////////////////////////////////////// //
11 |
12 | import (
13 | "fmt"
14 |
15 | "github.com/essentialkaos/ek/v13/knf"
16 | "github.com/essentialkaos/ek/v13/system"
17 | )
18 |
19 | // ////////////////////////////////////////////////////////////////////////////////// //
20 |
21 | var (
22 | // Interface returns error if configuration property contains name of network
23 | // interface which not present on the system
24 | Interface = validateInterface
25 | )
26 |
27 | // ////////////////////////////////////////////////////////////////////////////////// //
28 |
29 | func validateInterface(config knf.IConfig, prop string, value any) error {
30 | v := config.GetS(prop)
31 |
32 | if v == "" {
33 | return nil
34 | }
35 |
36 | stats, err := system.GetInterfacesStats()
37 |
38 | if err != nil {
39 | return fmt.Errorf("Can't get interfaces info: %v", err)
40 | }
41 |
42 | _, isPresent := stats[v]
43 |
44 | if !isPresent {
45 | return fmt.Errorf("Interface %q is not present on the system", v)
46 | }
47 |
48 | return nil
49 | }
50 |
--------------------------------------------------------------------------------
/knf/validators/system/validators_linux_test.go:
--------------------------------------------------------------------------------
1 | package system
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "github.com/essentialkaos/ek/v13/knf"
12 |
13 | . "github.com/essentialkaos/check"
14 | )
15 |
16 | // ////////////////////////////////////////////////////////////////////////////////// //
17 |
18 | func (s *ValidatorSuite) TestInterfaceValidator(c *C) {
19 | configFile := createConfig(c, _CONFIG_DATA)
20 |
21 | err := knf.Global(configFile)
22 | c.Assert(err, IsNil)
23 |
24 | errs := knf.Validate(knf.Validators{
25 | {"interface:test0", Interface, nil},
26 | {"interface:test1", Interface, nil},
27 | })
28 |
29 | c.Assert(errs, HasLen, 0)
30 |
31 | errs = knf.Validate(knf.Validators{
32 | {"interface:test2", Interface, nil},
33 | })
34 |
35 | c.Assert(errs, HasLen, 1)
36 | c.Assert(errs[0].Error(), Equals, `Interface "abc" is not present on the system`)
37 | }
38 |
--------------------------------------------------------------------------------
/lock/examples_test.go:
--------------------------------------------------------------------------------
1 | package lock
2 |
3 | import "time"
4 |
5 | // ////////////////////////////////////////////////////////////////////////////////// //
6 | // //
7 | // Copyright (c) 2025 ESSENTIAL KAOS //
8 | // Apache License, Version 2.0 //
9 | // //
10 | // ////////////////////////////////////////////////////////////////////////////////// //
11 |
12 | func ExampleCreate() {
13 | err := Create("my_app")
14 |
15 | if err != nil {
16 | panic(err.Error())
17 | }
18 |
19 | // do some stuff
20 |
21 | err = Remove("my_app")
22 |
23 | if err != nil {
24 | panic(err.Error())
25 | }
26 | }
27 |
28 | func ExampleRemove() {
29 | err := Create("my_app")
30 |
31 | if err != nil {
32 | panic(err.Error())
33 | }
34 |
35 | // do your stuff
36 |
37 | err = Remove("my_app")
38 |
39 | if err != nil {
40 | panic(err.Error())
41 | }
42 | }
43 |
44 | func ExampleHas() {
45 | if Has("my_app") {
46 | panic("Can't start application due to lock file")
47 | }
48 | }
49 |
50 | func ExampleWait() {
51 | ok := Wait("my_app", time.Now().Add(time.Minute))
52 |
53 | if !ok {
54 | panic("Can't start application due to lock file")
55 | }
56 |
57 | // do your stuff
58 | }
59 |
60 | func ExampleIsExpired() {
61 | if Has("my_app") {
62 | if IsExpired("my_app", time.Hour) {
63 | // looks like lock file was created long time ago, so delete it
64 | Remove("my_app")
65 | } else {
66 | panic("Can't start application due to lock file")
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/lock/lock_darwin.go:
--------------------------------------------------------------------------------
1 | package lock
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | // Dir is a path to directory with lock files
11 | var Dir = "/var/tmp"
12 |
13 | // ////////////////////////////////////////////////////////////////////////////////// //
14 |
--------------------------------------------------------------------------------
/lock/lock_linux.go:
--------------------------------------------------------------------------------
1 | package lock
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | // Dir is a path to directory with lock files
11 | var Dir = "/var/tmp"
12 |
13 | // ////////////////////////////////////////////////////////////////////////////////// //
14 |
--------------------------------------------------------------------------------
/lock/lock_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin
2 | // +build !linux,!darwin
3 |
4 | // Package lock provides methods for working with lock files
5 | package lock
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | import (
15 | "time"
16 | )
17 |
18 | // ////////////////////////////////////////////////////////////////////////////////// //
19 |
20 | // Dir is a path to directory with lock files
21 | var Dir = ""
22 |
23 | // ////////////////////////////////////////////////////////////////////////////////// //
24 |
25 | // ❗ Create creates new lock file
26 | func Create(name string) error {
27 | panic("UNSUPPORTED")
28 | return nil
29 | }
30 |
31 | // ❗ Remove deletes lock file
32 | func Remove(name string) error {
33 | panic("UNSUPPORTED")
34 | return nil
35 | }
36 |
37 | // ❗ Has returns true if lock file exists
38 | func Has(name string) bool {
39 | panic("UNSUPPORTED")
40 | return false
41 | }
42 |
43 | // ❗ Expired returns true if lock file reached TTL
44 | func Expired(name string, ttl time.Duration) bool {
45 | panic("UNSUPPORTED")
46 | return false
47 | }
48 |
49 | // ////////////////////////////////////////////////////////////////////////////////// //
50 |
--------------------------------------------------------------------------------
/log/nil.go:
--------------------------------------------------------------------------------
1 | package log
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | // NilLogger is Logger (ILogger) compatible logger that doesn't print anything
11 | type NilLogger struct{}
12 |
13 | // ////////////////////////////////////////////////////////////////////////////////// //
14 |
15 | // Aux do nothing
16 | func (l *NilLogger) Aux(f string, a ...any) error {
17 | return nil
18 | }
19 |
20 | // Debug do nothing
21 | func (l *NilLogger) Debug(f string, a ...any) error {
22 | return nil
23 | }
24 |
25 | // Info do nothing
26 | func (l *NilLogger) Info(f string, a ...any) error {
27 | return nil
28 | }
29 |
30 | // Warn do nothing
31 | func (l *NilLogger) Warn(f string, a ...any) error {
32 | return nil
33 | }
34 |
35 | // Error do nothing
36 | func (l *NilLogger) Error(f string, a ...any) error {
37 | return nil
38 | }
39 |
40 | // Crit do nothing
41 | func (l *NilLogger) Crit(f string, a ...any) error {
42 | return nil
43 | }
44 |
45 | // Print do nothing
46 | func (l *NilLogger) Print(level uint8, f string, a ...any) error {
47 | return nil
48 | }
49 |
--------------------------------------------------------------------------------
/lscolors/examples_test.go:
--------------------------------------------------------------------------------
1 | package lscolors
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleGetColor() {
17 | file := "myfile.txt"
18 | dir := "/home/john"
19 |
20 | colorSeq := GetColor(file)
21 |
22 | fmt.Printf(
23 | "%s/"+colorSeq+"%s"+GetColor(RESET)+"\n",
24 | dir, file,
25 | )
26 | }
27 |
28 | func ExampleColorize() {
29 | file := "myfile.txt"
30 | fmt.Println(Colorize(file))
31 | }
32 |
33 | func ExampleColorizePath() {
34 | path := "/home/john/myfile.txt"
35 | fmt.Println(ColorizePath(path))
36 | }
37 |
--------------------------------------------------------------------------------
/netutil/example_test.go:
--------------------------------------------------------------------------------
1 | package netutil
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleGetIP() {
17 | ip := GetIP()
18 |
19 | if ip != "" {
20 | fmt.Printf("Your IPv4 is %s\n", ip)
21 | }
22 | }
23 |
24 | func ExampleGetIP6() {
25 | ip := GetIP6()
26 |
27 | if ip != "" {
28 | fmt.Printf("Your IPv6 is %s\n", ip)
29 | }
30 | }
31 |
32 | func ExampleGetAllIP() {
33 | ips := GetAllIP()
34 |
35 | if len(ips) > 0 {
36 | fmt.Printf("All IPv4: %v\n", ips)
37 | }
38 | }
39 |
40 | func ExampleGetAllIP6() {
41 | ips := GetAllIP6()
42 |
43 | if len(ips) > 0 {
44 | fmt.Printf("All IPv6: %v\n", ips)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/netutil/netutil_darwin.go:
--------------------------------------------------------------------------------
1 | package netutil
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | func getDefaultRouteInterface() string {
11 | return ""
12 | }
13 |
--------------------------------------------------------------------------------
/netutil/netutil_darwin_test.go:
--------------------------------------------------------------------------------
1 | package netutil
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "os"
12 | "testing"
13 |
14 | . "github.com/essentialkaos/check"
15 | )
16 |
17 | // ////////////////////////////////////////////////////////////////////////////////// //
18 |
19 | func Test(t *testing.T) { TestingT(t) }
20 |
21 | type NetUtilSuite struct{}
22 |
23 | // ////////////////////////////////////////////////////////////////////////////////// //
24 |
25 | var _ = Suite(&NetUtilSuite{})
26 |
27 | // ////////////////////////////////////////////////////////////////////////////////// //
28 |
29 | func (s *NetUtilSuite) TestGetIP(c *C) {
30 | c.Assert(GetIP(), Not(Equals), "")
31 | }
32 |
33 | func (s *NetUtilSuite) TestGetIP6(c *C) {
34 | if os.Getenv("CI") == "" {
35 | c.Assert(GetIP6(), Not(Equals), "")
36 | }
37 | }
38 |
39 | func (s *NetUtilSuite) TestGetAllIP(c *C) {
40 | c.Assert(GetAllIP(), Not(HasLen), 0)
41 | }
42 |
43 | func (s *NetUtilSuite) TestGetAllIP6(c *C) {
44 | if os.Getenv("CI") == "" {
45 | c.Assert(GetAllIP6(), Not(HasLen), 0)
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/netutil/netutil_linux.go:
--------------------------------------------------------------------------------
1 | package netutil
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "bufio"
12 | "os"
13 |
14 | "github.com/essentialkaos/ek/v13/strutil"
15 | )
16 |
17 | // ////////////////////////////////////////////////////////////////////////////////// //
18 |
19 | // Path to file with routes info in procfs
20 | var procRouteFile = "/proc/net/route"
21 |
22 | // ////////////////////////////////////////////////////////////////////////////////// //
23 |
24 | func getDefaultRouteInterface() string {
25 | fd, err := os.OpenFile(procRouteFile, os.O_RDONLY, 0)
26 |
27 | if err != nil {
28 | return ""
29 | }
30 |
31 | defer fd.Close()
32 |
33 | r := bufio.NewReader(fd)
34 | s := bufio.NewScanner(r)
35 |
36 | var header bool
37 |
38 | for s.Scan() {
39 | if !header {
40 | header = true
41 | continue
42 | }
43 |
44 | if strutil.ReadField(s.Text(), 1, true) == "00000000" {
45 | return strutil.ReadField(s.Text(), 0, true)
46 | }
47 | }
48 |
49 | return ""
50 | }
51 |
--------------------------------------------------------------------------------
/netutil/netutil_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin
2 | // +build !linux,!darwin
3 |
4 | // Package netutil provides methods for working with network
5 | package netutil
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | // ❗ GetIP returns main IPv4 address
15 | func GetIP() string {
16 | panic("UNSUPPORTED")
17 | return ""
18 | }
19 |
20 | // ❗ GetIP6 returns main IPv6 address
21 | func GetIP6() string {
22 | panic("UNSUPPORTED")
23 | return ""
24 | }
25 |
26 | // ❗ GetAllIP returns all IPv4 addresses
27 | func GetAllIP() []string {
28 | panic("UNSUPPORTED")
29 | return nil
30 | }
31 |
32 | // ❗ GetAllIP6 returns all IPv6 addresses
33 | func GetAllIP6() []string {
34 | panic("UNSUPPORTED")
35 | return nil
36 | }
37 |
--------------------------------------------------------------------------------
/pager/example_test.go:
--------------------------------------------------------------------------------
1 | package pager
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | func ExampleSetup() {
11 | // Use pager from PAGER env var or default (more -f)
12 | Setup()
13 |
14 | // Or provide specific command.
15 | Setup("less -MQR")
16 |
17 | // Complete must be called at the end of the program work. You can call it with defer
18 | // in your main function.
19 | defer Complete()
20 | }
21 |
--------------------------------------------------------------------------------
/pager/pager_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin && !freebsd
2 | // +build !linux,!darwin,!freebsd
3 |
4 | // Package pager provides methods for pager setup (more/less)
5 | package pager
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | import "errors"
15 |
16 | // ////////////////////////////////////////////////////////////////////////////////// //
17 |
18 | var (
19 | ErrAlreadySet = errors.New("Pager already set")
20 | ErrNoPager = errors.New("There is no pager on the system")
21 | ErrStdinPipe = errors.New("Can't get pager stdin")
22 | )
23 |
24 | // AllowEnv is a flag that allows to user to define pager binary using PAGER environment
25 | // variable
26 | var AllowEnv bool
27 |
28 | // ////////////////////////////////////////////////////////////////////////////////// //
29 |
30 | // ❗ Setup set up pager for work. After calling this method, any data sent to Stdout and
31 | // Stderr (using fmt, fmtc, or terminal packages) will go to the pager.
32 | func Setup(pager ...string) error {
33 | return nil
34 | }
35 |
36 | // ❗ Complete finishes output redirect to pager
37 | func Complete() {
38 | return
39 | }
40 |
--------------------------------------------------------------------------------
/path/path_posix.go:
--------------------------------------------------------------------------------
1 | //go:build !windows
2 | // +build !windows
3 |
4 | package path
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | import "strings"
14 |
15 | // ////////////////////////////////////////////////////////////////////////////////// //
16 |
17 | // unsafePaths is slice with unsafe paths
18 | var unsafePaths = []string{
19 | "/lost+found",
20 | "/bin",
21 | "/boot",
22 | "/etc",
23 | "/dev",
24 | "/lib",
25 | "/lib64",
26 | "/proc",
27 | "/root",
28 | "/sbin",
29 | "/selinux",
30 | "/sys",
31 | "/usr/bin",
32 | "/usr/lib",
33 | "/usr/lib64",
34 | "/usr/libexec",
35 | "/usr/sbin",
36 | "/usr/include",
37 | "/var/cache",
38 | "/var/db",
39 | "/var/lib",
40 | }
41 |
42 | // ////////////////////////////////////////////////////////////////////////////////// //
43 |
44 | // DirN returns first N elements of path
45 | func DirN(path string, n int) string {
46 | if strings.Count(path, pathSeparator) < 2 || n == 0 {
47 | return path
48 | }
49 |
50 | if n > 0 {
51 | return dirNRight(path, n)
52 | }
53 |
54 | return dirNLeft(path, n*-1)
55 | }
56 |
57 | // ////////////////////////////////////////////////////////////////////////////////// //
58 |
59 | func isSafePath(path string) bool {
60 | for _, p := range unsafePaths {
61 | if strings.HasPrefix(path, p) {
62 | return false
63 | }
64 | }
65 |
66 | return true
67 | }
68 |
69 | // ////////////////////////////////////////////////////////////////////////////////// //
70 |
--------------------------------------------------------------------------------
/path/path_test.go:
--------------------------------------------------------------------------------
1 | package path
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "testing"
12 |
13 | . "github.com/essentialkaos/check"
14 | )
15 |
16 | // ////////////////////////////////////////////////////////////////////////////////// //
17 |
18 | func Test(t *testing.T) { TestingT(t) }
19 |
20 | type PathUtilSuite struct{}
21 |
22 | // ////////////////////////////////////////////////////////////////////////////////// //
23 |
24 | var _ = Suite(&PathUtilSuite{})
25 |
26 | // ////////////////////////////////////////////////////////////////////////////////// //
27 |
--------------------------------------------------------------------------------
/path/path_windows.go:
--------------------------------------------------------------------------------
1 | package path
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import "strings"
11 |
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | // unsafePaths is slice with unsafe paths
15 | var unsafePaths = []string{
16 | `\Recovery`,
17 | `\Windows`,
18 | `\ProgramData`,
19 | `\Program Files (x86)`,
20 | `\Program Files`,
21 | }
22 |
23 | // ////////////////////////////////////////////////////////////////////////////////// //
24 |
25 | // DirN returns first N elements of path
26 | func DirN(path string, n int) string {
27 | if strings.Count(path, pathSeparator) < 2 || n == 0 {
28 | return path
29 | }
30 |
31 | disk, p, ok := strings.Cut(path, ":")
32 |
33 | if !ok {
34 | p = path
35 | disk = ""
36 | } else {
37 | disk += ":"
38 | }
39 |
40 | if n > 0 {
41 | return disk + dirNRight(p, n)
42 | }
43 |
44 | return disk + dirNLeft(p, n*-1)
45 | }
46 |
47 | // ////////////////////////////////////////////////////////////////////////////////// //
48 |
49 | func isSafePath(path string) bool {
50 | for _, p := range unsafePaths {
51 | if strings.ContainsRune(path, ':') {
52 | _, path, _ = strings.Cut(path, ":")
53 | }
54 |
55 | if strings.HasPrefix(path, p) {
56 | return false
57 | }
58 | }
59 |
60 | return true
61 | }
62 |
--------------------------------------------------------------------------------
/pid/example_test.go:
--------------------------------------------------------------------------------
1 | package pid
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleCreate() {
17 | // You can set default directory for pid files
18 | Dir = "/home/user/my-pids"
19 |
20 | err := Create("servicename")
21 |
22 | if err != nil {
23 | fmt.Printf("Error: %v\n", err)
24 | }
25 |
26 | fmt.Println("PID file created!")
27 | }
28 |
29 | func ExampleRemove() {
30 | err := Remove("servicename")
31 |
32 | if err != nil {
33 | fmt.Printf("Error: %v\n", err)
34 | }
35 |
36 | fmt.Println("PID file removed!")
37 | }
38 |
39 | func ExampleGet() {
40 | pid := Get("servicename")
41 |
42 | if pid == -1 {
43 | fmt.Println("Can't read PID from PID file")
44 | }
45 |
46 | fmt.Printf("PID is %d\n", pid)
47 | }
48 |
49 | func ExampleRead() {
50 | pid := Read("/var/run/httpd.pid")
51 |
52 | if pid == -1 {
53 | fmt.Println("Can't read PID from PID file")
54 | }
55 |
56 | fmt.Printf("PID is %d\n", pid)
57 | }
58 |
59 | func ExampleIsProcessWorks() {
60 | pid := 1234
61 |
62 | if IsProcessWorks(pid) {
63 | fmt.Printf("Process with PID %d is works\n", pid)
64 | } else {
65 | fmt.Printf("Process with PID %d isn't working\n", pid)
66 | }
67 | }
68 |
69 | func ExampleIsWorks() {
70 | if IsWorks("servicename") {
71 | fmt.Println("Process is works")
72 | } else {
73 | fmt.Println("Process isn't working")
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/pid/pid_darwin.go:
--------------------------------------------------------------------------------
1 | package pid
2 |
3 | import (
4 | "os"
5 | "syscall"
6 | )
7 |
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 | // //
10 | // Copyright (c) 2025 ESSENTIAL KAOS //
11 | // Apache License, Version 2.0 //
12 | // //
13 | // ////////////////////////////////////////////////////////////////////////////////// //
14 |
15 | // IsWorks returns true if process with PID from PID file is works
16 | func IsWorks(name string) bool {
17 | pid := Get(name)
18 |
19 | if pid == -1 {
20 | return false
21 | }
22 |
23 | return IsProcessWorks(pid)
24 | }
25 |
26 | // IsProcessWorks returns true if process with given PID is works
27 | func IsProcessWorks(pid int) bool {
28 | // On Unix systems, FindProcess always succeeds and returns a Process
29 | // for the given pid, regardless of whether the process exists.
30 | pr, _ := os.FindProcess(pid)
31 | return pr.Signal(syscall.Signal(0)) == nil
32 | }
33 |
--------------------------------------------------------------------------------
/pid/pid_darwin_test.go:
--------------------------------------------------------------------------------
1 | //go:build darwin
2 | // +build darwin
3 |
4 | package pid
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | import (
14 | "os"
15 |
16 | . "github.com/essentialkaos/check"
17 | )
18 |
19 | // ////////////////////////////////////////////////////////////////////////////////// //
20 |
21 | func (s *PidSuite) TestIsWorks(c *C) {
22 | Dir = s.Dir
23 |
24 | err := Create("test")
25 |
26 | c.Assert(err, IsNil)
27 |
28 | c.Assert(IsWorks("test"), Equals, true)
29 |
30 | Remove("test")
31 |
32 | c.Assert(IsWorks("test"), Equals, false)
33 |
34 | // Write fake pid to pid file
35 | os.WriteFile(s.Dir+"/test.pid", []byte("999999\n"), 0644)
36 |
37 | c.Assert(IsWorks("test"), Equals, false)
38 | }
39 |
40 | func (s *PidSuite) TestIsProcessWorks(c *C) {
41 | c.Assert(IsProcessWorks(os.Getpid()), Equals, true)
42 | c.Assert(IsProcessWorks(999999), Equals, false)
43 | }
44 |
--------------------------------------------------------------------------------
/pid/pid_freebsd.go:
--------------------------------------------------------------------------------
1 | package pid
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "os/exec"
12 | "strconv"
13 | )
14 |
15 | // ////////////////////////////////////////////////////////////////////////////////// //
16 |
17 | // IsWorks returns true if process with PID from PID file is works
18 | func IsWorks(name string) bool {
19 | pid := Get(name)
20 |
21 | if pid == -1 {
22 | return false
23 | }
24 |
25 | return IsProcessWorks(pid)
26 | }
27 |
28 | // IsProcessWorks returns true if process with given PID is works
29 | func IsProcessWorks(pid int) bool {
30 | return exec.Command("/usr/bin/procstat", strconv.Itoa(pid)).Run() == nil
31 | }
32 |
--------------------------------------------------------------------------------
/pid/pid_linux.go:
--------------------------------------------------------------------------------
1 | package pid
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | "os"
13 | "syscall"
14 |
15 | "github.com/essentialkaos/ek/v13/fsutil"
16 | )
17 |
18 | // ////////////////////////////////////////////////////////////////////////////////// //
19 |
20 | // procfsDir is path to procfs directory
21 | var procfsDir = "/proc"
22 |
23 | // ////////////////////////////////////////////////////////////////////////////////// //
24 |
25 | // IsWorks returns true if process with PID from PID file is works
26 | func IsWorks(name string) bool {
27 | pid := Get(name)
28 |
29 | if pid == -1 {
30 | return false
31 | }
32 |
33 | if !fsutil.IsExist(fmt.Sprintf("%s/%d", procfsDir, pid)) {
34 | return false
35 | }
36 |
37 | _, _, initCDate, _ := fsutil.GetTimestamps(fmt.Sprintf("%s/%d", procfsDir, 1))
38 | _, _, procCDate, _ := fsutil.GetTimestamps(fmt.Sprintf("%s/%d", procfsDir, pid))
39 |
40 | if initCDate != -1 && procCDate != -1 && initCDate > procCDate {
41 | return false
42 | }
43 |
44 | return IsProcessWorks(pid)
45 | }
46 |
47 | // IsProcessWorks returns true if process with given PID is works
48 | func IsProcessWorks(pid int) bool {
49 | // On Unix systems, FindProcess always succeeds and returns a Process
50 | // for the given pid, regardless of whether the process exists.
51 | pr, _ := os.FindProcess(pid)
52 | return pr.Signal(syscall.Signal(0)) == nil
53 | }
54 |
--------------------------------------------------------------------------------
/pid/pid_linux_test.go:
--------------------------------------------------------------------------------
1 | //go:build linux || freebsd
2 | // +build linux freebsd
3 |
4 | package pid
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | import (
14 | "fmt"
15 | "os"
16 | "time"
17 |
18 | . "github.com/essentialkaos/check"
19 | )
20 |
21 | // ////////////////////////////////////////////////////////////////////////////////// //
22 |
23 | func (s *PidSuite) TestIsWorks(c *C) {
24 | Dir = s.Dir
25 |
26 | err := Create("test")
27 |
28 | c.Assert(err, IsNil)
29 | c.Assert(IsWorks("test"), Equals, true)
30 |
31 | Remove("test")
32 |
33 | c.Assert(IsWorks("test"), Equals, false)
34 |
35 | // Write fake pid to pid file
36 | os.WriteFile(s.Dir+"/test.pid", []byte("69999\n"), 0644)
37 |
38 | c.Assert(IsWorks("test"), Equals, false)
39 |
40 | procfsDir = c.MkDir()
41 | err = os.Mkdir(procfsDir+"/69999", 0755)
42 |
43 | if err != nil {
44 | c.Fatal(fmt.Sprintf("Can't create directory %s", procfsDir+"/69999"))
45 | }
46 |
47 | time.Sleep(2 * time.Second)
48 |
49 | err = os.Mkdir(procfsDir+"/1", 0755)
50 |
51 | if err != nil {
52 | c.Fatal(fmt.Sprintf("Can't create directory %s", procfsDir+"/1"))
53 | }
54 |
55 | c.Assert(IsWorks("test"), Equals, false)
56 | }
57 |
58 | func (s *PidSuite) TestIsProcessWorks(c *C) {
59 | c.Assert(IsProcessWorks(os.Getpid()), Equals, true)
60 | c.Assert(IsProcessWorks(999999), Equals, false)
61 | }
62 |
--------------------------------------------------------------------------------
/pid/pid_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin && !freebsd
2 | // +build !linux,!darwin,!freebsd
3 |
4 | // Package pid provides methods for working with PID files
5 | package pid
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | // ❗ IsWorks returns true if process with PID from PID file is works
15 | func IsWorks(name string) bool {
16 | panic("UNSUPPORTED")
17 | return false
18 | }
19 |
20 | // ❗ IsProcessWorks returns true if process with given PID is works
21 | func IsProcessWorks(pid int) bool {
22 | panic("UNSUPPORTED")
23 | return false
24 | }
25 |
--------------------------------------------------------------------------------
/pluralize/examples_test.go:
--------------------------------------------------------------------------------
1 | package pluralize
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleP() {
17 | fmt.Println(P("I have %d %s", 1, "apple", "apples"))
18 | fmt.Println(P("I have %d %s", 5, "apple", "apples"))
19 | // Output: I have 1 apple
20 | // I have 5 apples
21 | }
22 |
23 | func ExamplePS() {
24 | fmt.Println(PS(Ru, "У меня %d %s", 1, "яблоко", "яблока", "яблок"))
25 | fmt.Println(PS(Ru, "У меня %d %s", 5, "яблоко", "яблока", "яблок"))
26 | // Output: У меня 1 яблоко
27 | // У меня 5 яблок
28 | }
29 |
30 | func ExamplePluralize() {
31 | fmt.Println(Pluralize(1, "apple", "apples"))
32 | fmt.Println(Pluralize(5, "apple", "apples"))
33 | // Output: apple
34 | // apples
35 | }
36 | func ExamplePluralizeSpecial() {
37 | fmt.Println(PluralizeSpecial(Ru, 1, "яблоко", "яблока", "яблок"))
38 | fmt.Println(PluralizeSpecial(Ru, 5, "яблоко", "яблока", "яблок"))
39 | // Output: яблоко
40 | // яблок
41 | }
42 |
--------------------------------------------------------------------------------
/protip/example_test.go:
--------------------------------------------------------------------------------
1 | package protip
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | func ExampleAdd() {
11 | // Add simple tip
12 | Add(&Tip{
13 | Title: "Tip #1",
14 | Message: `Tip message`,
15 | })
16 |
17 | // Add tip with custom weight (≠ 0.5)
18 | Add(&Tip{
19 | Title: "Tip #2",
20 | Message: `Tip message`,
21 | Weight: 0.1,
22 | })
23 |
24 | // Add tip with custom weight (≠ 0.5) and color
25 | Add(&Tip{
26 | Title: "Tip #3",
27 | Message: `Tip message`,
28 | Weight: 0.8,
29 | ColorTag: "{b}",
30 | })
31 | }
32 |
33 | func ExampleShow() {
34 | // Add simple tip
35 | Add(&Tip{
36 | Title: "Tip #1",
37 | Message: `Tip message`,
38 | })
39 |
40 | // Increase default probability to 50%
41 | Probability = 0.5
42 |
43 | // Set default color to green
44 | ColorTag = "{g}"
45 |
46 | // Try to show tip
47 | Show(false)
48 |
49 | // Force show
50 | Show(true)
51 | }
52 |
--------------------------------------------------------------------------------
/rand/rand.go:
--------------------------------------------------------------------------------
1 | // Package rand provides methods for generating random data
2 | package rand
3 |
4 | // ////////////////////////////////////////////////////////////////////////////////// //
5 | // //
6 | // Copyright (c) 2025 ESSENTIAL KAOS //
7 | // Apache License, Version 2.0 //
8 | // //
9 | // ////////////////////////////////////////////////////////////////////////////////// //
10 |
11 | import (
12 | "math/rand"
13 | "time"
14 | )
15 |
16 | // ////////////////////////////////////////////////////////////////////////////////// //
17 |
18 | var symbols = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890"
19 |
20 | // ////////////////////////////////////////////////////////////////////////////////// //
21 |
22 | // String returns string with random chars
23 | func String(length int) string {
24 | if length <= 0 {
25 | return ""
26 | }
27 |
28 | rnd := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
29 | symbolsLength := len(symbols)
30 | result := make([]byte, length)
31 |
32 | for i := range length {
33 | result[i] = symbols[rnd.Intn(symbolsLength)]
34 | }
35 |
36 | return string(result)
37 | }
38 |
39 | // Slice returns slice with random chars
40 | func Slice(length int) []string {
41 | if length == 0 {
42 | return []string{}
43 | }
44 |
45 | rnd := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
46 | symbolsLength := len(symbols)
47 | result := make([]string, length)
48 |
49 | for i := range length {
50 | result[i] = string(symbols[rnd.Intn(symbolsLength)])
51 | }
52 |
53 | return result
54 | }
55 |
56 | // ////////////////////////////////////////////////////////////////////////////////// //
57 |
--------------------------------------------------------------------------------
/rand/rand_test.go:
--------------------------------------------------------------------------------
1 | package rand
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "strings"
12 | "testing"
13 |
14 | . "github.com/essentialkaos/check"
15 | )
16 |
17 | // ////////////////////////////////////////////////////////////////////////////////// //
18 |
19 | func Test(t *testing.T) { TestingT(t) }
20 |
21 | type RandSuite struct{}
22 |
23 | // ////////////////////////////////////////////////////////////////////////////////// //
24 |
25 | var _ = Suite(&RandSuite{})
26 |
27 | // ////////////////////////////////////////////////////////////////////////////////// //
28 |
29 | func (s *RandSuite) TestString(c *C) {
30 | c.Assert(len(String(100)), Equals, 100)
31 | c.Assert(len(String(1)), Equals, 1)
32 | c.Assert(len(String(0)), Equals, 0)
33 | c.Assert(len(String(-100)), Equals, 0)
34 | }
35 |
36 | func (s *RandSuite) TestSlice(c *C) {
37 | t1 := strings.Join(Slice(256), "")
38 | t2 := strings.Join(Slice(256), "")
39 |
40 | c.Assert(t1, Not(Equals), t2)
41 | c.Assert(Slice(0), HasLen, 0)
42 | }
43 |
--------------------------------------------------------------------------------
/req/headers.go:
--------------------------------------------------------------------------------
1 | package req
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | // Headers is a map[string]string used for headers
11 | type Headers map[string]string
12 |
13 | // ////////////////////////////////////////////////////////////////////////////////// //
14 |
15 | // Set sets header value
16 | func (h Headers) Set(name, value string) bool {
17 | if h == nil || name == "" || value == "" {
18 | return false
19 | }
20 |
21 | h[name] = value
22 |
23 | return true
24 | }
25 |
26 | // SetIf sets header value if given condition is true
27 | func (h Headers) SetIf(cond bool, name, value string) bool {
28 | if h == nil || name == "" || !cond {
29 | return false
30 | }
31 |
32 | h[name] = value
33 |
34 | return true
35 | }
36 |
37 | // Get returns header with given name
38 | func (h Headers) Get(name string) string {
39 | if h == nil || name == "" {
40 | return ""
41 | }
42 |
43 | return h[name]
44 | }
45 |
46 | // Delete deletes parameter with given name
47 | func (h Headers) Delete(name string) bool {
48 | if h == nil || name == "" {
49 | return false
50 | }
51 |
52 | delete(h, name)
53 |
54 | return true
55 | }
56 |
57 | // DeleteIf deletes parameter with given name if condition is true
58 | func (h Headers) DeleteIf(cond bool, name string) bool {
59 | if h == nil || name == "" || !cond {
60 | return false
61 | }
62 |
63 | if h[name] != "" {
64 | delete(h, name)
65 | }
66 |
67 | return true
68 | }
69 |
70 | // ////////////////////////////////////////////////////////////////////////////////// //
71 |
--------------------------------------------------------------------------------
/req/limiter.go:
--------------------------------------------------------------------------------
1 | package req
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import "time"
11 |
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | // Limiter is request limiter
15 | type Limiter struct {
16 | lastCall time.Time
17 | delay time.Duration
18 | }
19 |
20 | // ////////////////////////////////////////////////////////////////////////////////// //
21 |
22 | // NewLimiter creates a new limiter. If rps is less than or equal to 0, it returns nil.
23 | func NewLimiter(rps float64) *Limiter {
24 | if rps <= 0 {
25 | return nil
26 | }
27 |
28 | return &Limiter{
29 | delay: time.Duration(float64(time.Second) / rps),
30 | }
31 | }
32 |
33 | // ////////////////////////////////////////////////////////////////////////////////// //
34 |
35 | // Wait blocks current goroutine execution until next time slot become available
36 | func (l *Limiter) Wait() {
37 | if l == nil {
38 | return
39 | }
40 |
41 | if l.lastCall.IsZero() {
42 | l.lastCall = time.Now()
43 | return
44 | }
45 |
46 | w := time.Since(l.lastCall)
47 |
48 | if w < l.delay {
49 | time.Sleep(l.delay - w)
50 | }
51 |
52 | l.lastCall = time.Now()
53 | }
54 |
--------------------------------------------------------------------------------
/reutil/example_test.go:
--------------------------------------------------------------------------------
1 | package reutil
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | "regexp"
13 | )
14 |
15 | // ////////////////////////////////////////////////////////////////////////////////// //
16 |
17 | func ExampleReplace() {
18 | re := regexp.MustCompile(`([a-zA-Z0-9_.]+)@([a-zA-Z0-9-_.]+\.[a-z]{2,3})`)
19 | mails := "jdoe@yahoo.com bob.entus@gmail.com dina@mail.org"
20 | mappings := map[string]string{
21 | "yahoo.com": "YH",
22 | "gmail.com": "GML",
23 | "mail.org": "ML",
24 | }
25 |
26 | repl, err := Replace(re, mails, func(found string, submatch []string) string {
27 | return submatch[0] + ":" + mappings[submatch[1]]
28 | })
29 |
30 | if err != nil {
31 | fmt.Println(err)
32 | return
33 | }
34 |
35 | fmt.Printf("%s → %s\n", mails, repl)
36 |
37 | // Output:
38 | // jdoe@yahoo.com bob.entus@gmail.com dina@mail.org → jdoe:YH bob.entus:GML dina:ML
39 | }
40 |
--------------------------------------------------------------------------------
/secstr/example_test.go:
--------------------------------------------------------------------------------
1 | package secstr
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleNewSecureString() {
17 | passwd := "MySuppaPassword12345"
18 | ss, err := NewSecureString(&passwd)
19 |
20 | if err != nil {
21 | panic(err)
22 | }
23 |
24 | fmt.Printf("Password: %s", string(ss.Data))
25 | }
26 |
--------------------------------------------------------------------------------
/secstr/secstring_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin
2 | // +build !linux,!darwin
3 |
4 | // Package secstr provides methods and structs for working with protected (secure) strings
5 | package secstr
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | // ❗ String contains protected data
15 | type String struct {
16 | Data []byte
17 | }
18 |
19 | // ////////////////////////////////////////////////////////////////////////////////// //
20 |
21 | // ❗ NewSecureString creates new secure string
22 | func NewSecureString(data any) (*String, error) {
23 | panic("UNSUPPORTED")
24 | return nil, nil
25 | }
26 |
27 | // ////////////////////////////////////////////////////////////////////////////////// //
28 |
29 | // ❗ IsEmpty returns false if string is empty
30 | func (s *String) IsEmpty() bool {
31 | panic("UNSUPPORTED")
32 | return false
33 | }
34 |
35 | // ❗ Destroy destroys data
36 | func (s *String) Destroy() error {
37 | panic("UNSUPPORTED")
38 | return nil
39 | }
40 |
--------------------------------------------------------------------------------
/signal/example_test.go:
--------------------------------------------------------------------------------
1 | package signal
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | "time"
13 | )
14 |
15 | // ////////////////////////////////////////////////////////////////////////////////// //
16 |
17 | func ExampleHandlers_Track() {
18 | hupHandler := func() {
19 | fmt.Println("Got HUP signal")
20 | }
21 |
22 | usr1Handler := func() {
23 | fmt.Println("Got USR1 signal")
24 | }
25 |
26 | Handlers{
27 | HUP: hupHandler,
28 | USR1: usr1Handler,
29 | }.Track()
30 | }
31 |
32 | func ExampleHandlers_TrackAsync() {
33 | hupHandler := func() {
34 | fmt.Println("Got HUP signal")
35 | }
36 |
37 | usr1Handler := func() {
38 | fmt.Println("Got USR1 signal")
39 | }
40 |
41 | Handlers{
42 | HUP: hupHandler,
43 | USR1: usr1Handler,
44 | }.TrackAsync()
45 |
46 | time.Sleep(time.Hour)
47 | }
48 |
--------------------------------------------------------------------------------
/sortutil/example_test.go:
--------------------------------------------------------------------------------
1 | package sortutil
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleVersions() {
17 | versionSlice := []string{
18 | "2.0-5",
19 | "1.3b",
20 | "1.1",
21 | "1.3",
22 | "1.1.6",
23 | "1",
24 | "2.0",
25 | "2.0-1",
26 | }
27 |
28 | Versions(versionSlice)
29 |
30 | fmt.Println(versionSlice)
31 |
32 | // Output:
33 | // [1 1.1 1.1.6 1.3 1.3b 2.0 2.0-1 2.0-5]
34 | }
35 |
36 | func ExampleStrings() {
37 | stringSlice := []string{
38 | "Alisa",
39 | "Luna",
40 | "remedios",
41 | "Ona",
42 | "Eugene",
43 | "lorriane",
44 | "Zachariah",
45 | "cecily",
46 | "eleonora",
47 | "Dotty",
48 | }
49 |
50 | // Case insensitive sorting
51 | Strings(stringSlice, false)
52 |
53 | fmt.Println(stringSlice)
54 |
55 | // Case sensitive sorting
56 | Strings(stringSlice, true)
57 |
58 | fmt.Println(stringSlice)
59 |
60 | // Output:
61 | // [Alisa Dotty Eugene Luna Ona Zachariah cecily eleonora lorriane remedios]
62 | // [Alisa cecily Dotty eleonora Eugene lorriane Luna Ona remedios Zachariah]
63 | }
64 |
--------------------------------------------------------------------------------
/spellcheck/example_test.go:
--------------------------------------------------------------------------------
1 | package spellcheck
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleTrain() {
17 | name := "Frida"
18 | names := []string{"Jakalyn", "Freda", "Micayla", "Knightley", "Shun"}
19 |
20 | model := Train(names)
21 |
22 | fmt.Printf("%s → %s\n", name, model.Correct(name))
23 | // Output: Frida → Freda
24 | }
25 |
26 | func ExampleModel_Correct() {
27 | name := "Frida"
28 | names := []string{"Jakalyn", "Freda", "Micayla", "Knightley", "Shun"}
29 |
30 | model := Train(names)
31 |
32 | fmt.Printf("%s → %s\n", name, model.Correct(name))
33 | // Output: Frida → Freda
34 | }
35 |
36 | func ExampleModel_Suggest() {
37 | name := "azi"
38 | names := []string{"Thorin", "Akhai", "Payden", "Ghazi", "Rey", "Axel", "Sahily", "Azriel"}
39 |
40 | model := Train(names)
41 |
42 | fmt.Printf("%s → %s\n", name, model.Suggest(name, 3))
43 | }
44 |
--------------------------------------------------------------------------------
/spinner/examples_test.go:
--------------------------------------------------------------------------------
1 | package spinner
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "time"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleShow() {
17 | file := "file.txt"
18 |
19 | // Customize design
20 | OkSymbol = "🤟" // Set success status symbol
21 | OkColorTag = "{b}" // Set success status symbol color
22 |
23 | Show("Removing file %s", file)
24 | time.Sleep(time.Second)
25 | Done(true)
26 | }
27 |
28 | func ExampleUpdate() {
29 | Show("My long running task")
30 | time.Sleep(time.Second)
31 | Show("My long running task still working")
32 | time.Sleep(time.Second)
33 | Done(true)
34 | }
35 |
36 | func ExampleDone() {
37 | Show("My long running task with good result")
38 | time.Sleep(time.Second)
39 | Done(true)
40 |
41 | Show("My long running task with bad result")
42 | time.Sleep(time.Second)
43 | Done(false)
44 | }
45 |
46 | func ExampleSkip() {
47 | Show("My skipped running task")
48 | time.Sleep(time.Second)
49 | Skip()
50 | }
51 |
--------------------------------------------------------------------------------
/spinner/spinner_test.go:
--------------------------------------------------------------------------------
1 | package spinner
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "testing"
12 | "time"
13 |
14 | . "github.com/essentialkaos/check"
15 | )
16 |
17 | // ////////////////////////////////////////////////////////////////////////////////// //
18 |
19 | func Test(t *testing.T) { TestingT(t) }
20 |
21 | type SpinnerSuite struct{}
22 |
23 | // ////////////////////////////////////////////////////////////////////////////////// //
24 |
25 | var _ = Suite(&SpinnerSuite{})
26 |
27 | // ////////////////////////////////////////////////////////////////////////////////// //
28 |
29 | func (s *SpinnerSuite) TestSpinner(c *C) {
30 | Done(true) // skipped
31 | Show("ABCD")
32 | Show("ABCD") // skipped
33 | time.Sleep(time.Millisecond * 800)
34 | Update("ABCD")
35 | time.Sleep(time.Millisecond * 100)
36 | Done(true)
37 | Update("ABCD") // skipped
38 | Show("ABCD")
39 | time.Sleep(time.Millisecond * 10)
40 | Done(false)
41 | Show("ABCD")
42 | time.Sleep(time.Millisecond * 10)
43 | Skip()
44 |
45 | DisableAnimation = true
46 | Show("ABCD")
47 | Done(true)
48 |
49 | Skip()
50 | }
51 |
--------------------------------------------------------------------------------
/strutil/fuzz.go:
--------------------------------------------------------------------------------
1 | //go:build gofuzz
2 | // +build gofuzz
3 |
4 | package strutil
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | func Fuzz(data []byte) int {
14 | Fields(string(data))
15 | return 0
16 | }
17 |
--------------------------------------------------------------------------------
/support/apps/example_test.go:
--------------------------------------------------------------------------------
1 | package apps
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import "fmt"
11 |
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | func ExampleExtractVersion() {
15 | // Get Ruby version from 'ruby --version' command (line: 0, field: 1)
16 | rubyVersion := ExtractVersion("ruby --version", 0, 1)
17 | fmt.Println(rubyVersion)
18 |
19 | // Get Java version from 'java -version' command (line: 1, field: 3)
20 | javaVersion := ExtractVersion("java -version", 1, 3)
21 | fmt.Println(javaVersion)
22 | }
23 |
--------------------------------------------------------------------------------
/support/fs/fs.go:
--------------------------------------------------------------------------------
1 | //go:build !windows
2 | // +build !windows
3 |
4 | // Package pkgs provides methods for collecting information about filesystem
5 | package fs
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | import (
15 | "github.com/essentialkaos/ek/v13/system"
16 |
17 | "github.com/essentialkaos/ek/v13/support"
18 | )
19 |
20 | // ////////////////////////////////////////////////////////////////////////////////// //
21 |
22 | // Collect collects info about filesystem
23 | func Collect() []support.FSInfo {
24 | fsInfo, err := system.GetFSUsage()
25 |
26 | if err != nil {
27 | return nil
28 | }
29 |
30 | var info []support.FSInfo
31 |
32 | for mPath, mInfo := range fsInfo {
33 | info = append(info, support.FSInfo{
34 | Path: mPath,
35 | Device: mInfo.Device,
36 | Type: mInfo.Type,
37 | Used: mInfo.Used,
38 | Free: mInfo.Free,
39 | })
40 | }
41 |
42 | return info
43 | }
44 |
--------------------------------------------------------------------------------
/support/fs/fs_windows.go:
--------------------------------------------------------------------------------
1 | // Package pkgs provides methods for collecting information about filesystem
2 | package fs
3 |
4 | // ////////////////////////////////////////////////////////////////////////////////// //
5 | // //
6 | // Copyright (c) 2025 ESSENTIAL KAOS //
7 | // Apache License, Version 2.0 //
8 | // //
9 | // ////////////////////////////////////////////////////////////////////////////////// //
10 |
11 | import (
12 | "github.com/essentialkaos/ek/v13/support"
13 | )
14 |
15 | // ////////////////////////////////////////////////////////////////////////////////// //
16 |
17 | // Collect collects info about filesystem
18 | func Collect() []support.FSInfo {
19 | return nil
20 | }
21 |
--------------------------------------------------------------------------------
/support/kernel/kernel.go:
--------------------------------------------------------------------------------
1 | //go:build linux || darwin
2 | // +build linux darwin
3 |
4 | // Package kernel provides methods for collecting information from OS kernel
5 | package kernel
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | import (
15 | "strings"
16 |
17 | "github.com/essentialkaos/ek/v13/strutil"
18 | "github.com/essentialkaos/ek/v13/support"
19 | "github.com/essentialkaos/ek/v13/system/sysctl"
20 | )
21 |
22 | // ////////////////////////////////////////////////////////////////////////////////// //
23 |
24 | // Collect collects info from OS kernel
25 | func Collect(params ...string) []support.KernelParam {
26 | kernelParams, err := sysctl.All()
27 |
28 | if err != nil {
29 | return nil
30 | }
31 |
32 | var result []support.KernelParam
33 |
34 | for _, param := range params {
35 | isGlob := strings.HasSuffix(param, "*")
36 | param = strings.TrimRight(param, "*")
37 |
38 | for k, v := range kernelParams {
39 | if isGlob {
40 | if !strings.HasPrefix(k, param) {
41 | continue
42 | }
43 | } else {
44 | if k != param {
45 | continue
46 | }
47 | }
48 |
49 | value := strings.ReplaceAll(v, "\t", " ")
50 | value = strutil.SqueezeRepeats(value, " ")
51 |
52 | result = append(result, support.KernelParam{
53 | Key: k,
54 | Value: value,
55 | })
56 | }
57 | }
58 |
59 | return result
60 | }
61 |
--------------------------------------------------------------------------------
/support/kernel/kernel_windows.go:
--------------------------------------------------------------------------------
1 | // Package kernel provides methods for collecting information from OS kernel
2 | package kernel
3 |
4 | // ////////////////////////////////////////////////////////////////////////////////// //
5 | // //
6 | // Copyright (c) 2025 ESSENTIAL KAOS //
7 | // Apache License, Version 2.0 //
8 | // //
9 | // ////////////////////////////////////////////////////////////////////////////////// //
10 |
11 | import "github.com/essentialkaos/ek/v13/support"
12 |
13 | // ////////////////////////////////////////////////////////////////////////////////// //
14 |
15 | // Collect collects info from OS kernel
16 | func Collect(params ...string) []support.KernelParam {
17 | return nil
18 | }
19 |
--------------------------------------------------------------------------------
/support/network/network_windows.go:
--------------------------------------------------------------------------------
1 | // Package network provides methods for collecting information about machine network
2 | package network
3 |
4 | // ////////////////////////////////////////////////////////////////////////////////// //
5 | // //
6 | // Copyright (c) 2025 ESSENTIAL KAOS //
7 | // Apache License, Version 2.0 //
8 | // //
9 | // ////////////////////////////////////////////////////////////////////////////////// //
10 |
11 | import (
12 | "github.com/essentialkaos/ek/v13/support"
13 |
14 | "golang.org/x/sys/windows"
15 | )
16 |
17 | // ////////////////////////////////////////////////////////////////////////////////// //
18 |
19 | // Collect collects network info
20 | func Collect(ipResolverURL ...string) *support.NetworkInfo {
21 | info := &support.NetworkInfo{}
22 |
23 | info.Hostname, _ = windows.ComputerName()
24 |
25 | if len(ipResolverURL) != 0 {
26 | info.PublicIP = resolvePublicIP(ipResolverURL[0])
27 | }
28 |
29 | if info.Hostname == "" && info.PublicIP == "" {
30 | return nil
31 | }
32 |
33 | return info
34 | }
35 |
--------------------------------------------------------------------------------
/support/pkgs/pkgs_darwin.go:
--------------------------------------------------------------------------------
1 | // Package pkgs provides methods for collecting information about installed packages
2 | package pkgs
3 |
4 | // ////////////////////////////////////////////////////////////////////////////////// //
5 | // //
6 | // Copyright (c) 2025 ESSENTIAL KAOS //
7 | // Apache License, Version 2.0 //
8 | // //
9 | // ////////////////////////////////////////////////////////////////////////////////// //
10 |
11 | import "github.com/essentialkaos/ek/v13/support"
12 |
13 | // ////////////////////////////////////////////////////////////////////////////////// //
14 |
15 | // Collect collect info about packages
16 | func Collect(pkgs ...string) []support.Pkg {
17 | return nil
18 | }
19 |
--------------------------------------------------------------------------------
/support/pkgs/pkgs_windows.go:
--------------------------------------------------------------------------------
1 | // Package pkgs provides methods for collecting information about installed packages
2 | package pkgs
3 |
4 | // ////////////////////////////////////////////////////////////////////////////////// //
5 | // //
6 | // Copyright (c) 2025 ESSENTIAL KAOS //
7 | // Apache License, Version 2.0 //
8 | // //
9 | // ////////////////////////////////////////////////////////////////////////////////// //
10 |
11 | import (
12 | "github.com/essentialkaos/ek/v13/support"
13 | )
14 |
15 | // ////////////////////////////////////////////////////////////////////////////////// //
16 |
17 | // Collect collect info about packages
18 | func Collect(pkgs ...string) []support.Pkg {
19 | return nil
20 | }
21 |
--------------------------------------------------------------------------------
/support/resources/resources.go:
--------------------------------------------------------------------------------
1 | //go:build linux || darwin
2 | // +build linux darwin
3 |
4 | // Package resources provides methods for collecting information about system
5 | // resources (cpu/memory)
6 | package resources
7 |
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 | // //
10 | // Copyright (c) 2025 ESSENTIAL KAOS //
11 | // Apache License, Version 2.0 //
12 | // //
13 | // ////////////////////////////////////////////////////////////////////////////////// //
14 |
15 | import (
16 | "github.com/essentialkaos/ek/v13/support"
17 | "github.com/essentialkaos/ek/v13/system"
18 | )
19 |
20 | // ////////////////////////////////////////////////////////////////////////////////// //
21 |
22 | // Collect collects info about CPU and memory
23 | func Collect() *support.ResourcesInfo {
24 | result := &support.ResourcesInfo{}
25 |
26 | cpuInfo, err1 := system.GetCPUInfo()
27 |
28 | if err1 == nil {
29 | for _, p := range cpuInfo {
30 | result.CPU = append(result.CPU, support.CPUInfo{
31 | Model: p.Model,
32 | Cores: p.Cores,
33 | Threads: p.Siblings / p.Cores,
34 | })
35 | }
36 | }
37 |
38 | memInfo, err2 := system.GetMemUsage()
39 |
40 | if err2 == nil {
41 | result.MemTotal = memInfo.MemTotal
42 | result.MemFree = memInfo.MemFree
43 | result.MemUsed = memInfo.MemUsed
44 | result.SwapTotal = memInfo.SwapTotal
45 | result.SwapFree = memInfo.SwapFree
46 | result.SwapUsed = memInfo.SwapUsed
47 | }
48 |
49 | if err1 != nil && err2 != nil {
50 | return nil
51 | }
52 |
53 | return result
54 | }
55 |
--------------------------------------------------------------------------------
/support/resources/resources_windows.go:
--------------------------------------------------------------------------------
1 | // Package resources provides methods for collecting information about system
2 | // resources (cpu/memory)
3 | package resources
4 |
5 | // ////////////////////////////////////////////////////////////////////////////////// //
6 | // //
7 | // Copyright (c) 2025 ESSENTIAL KAOS //
8 | // Apache License, Version 2.0 //
9 | // //
10 | // ////////////////////////////////////////////////////////////////////////////////// //
11 |
12 | import (
13 | "github.com/essentialkaos/ek/v13/support"
14 | )
15 |
16 | // ////////////////////////////////////////////////////////////////////////////////// //
17 |
18 | // Collect collects info about CPU and memory
19 | func Collect() *support.ResourcesInfo {
20 | return nil
21 | }
22 |
--------------------------------------------------------------------------------
/support/services/services.go:
--------------------------------------------------------------------------------
1 | //go:build !windows
2 | // +build !windows
3 |
4 | // Package services provides methods for collecting information about system services
5 | package services
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | import (
15 | "github.com/essentialkaos/ek/v13/initsystem"
16 | "github.com/essentialkaos/ek/v13/support"
17 | )
18 |
19 | // ////////////////////////////////////////////////////////////////////////////////// //
20 |
21 | // Collect collects info about services
22 | func Collect(services ...string) []support.Service {
23 | var result []support.Service
24 |
25 | for _, s := range services {
26 | service := support.Service{Name: s, Status: support.STATUS_UNKNOWN}
27 |
28 | if initsystem.IsPresent(s) {
29 | service.IsPresent = true
30 | service.IsEnabled, _ = initsystem.IsEnabled(s)
31 |
32 | isWorks, err := initsystem.IsWorks(s)
33 |
34 | switch {
35 | case err == nil && isWorks:
36 | service.Status = support.STATUS_WORKS
37 | case err == nil && !isWorks:
38 | service.Status = support.STATUS_STOPPED
39 | }
40 | }
41 |
42 | result = append(result, service)
43 | }
44 |
45 | return result
46 | }
47 |
--------------------------------------------------------------------------------
/support/services/services_windows.go:
--------------------------------------------------------------------------------
1 | // Package services provides methods for collecting information about system services
2 | package services
3 |
4 | // ////////////////////////////////////////////////////////////////////////////////// //
5 | // //
6 | // Copyright (c) 2025 ESSENTIAL KAOS //
7 | // Apache License, Version 2.0 //
8 | // //
9 | // ////////////////////////////////////////////////////////////////////////////////// //
10 |
11 | import "github.com/essentialkaos/ek/v13/support"
12 |
13 | // ////////////////////////////////////////////////////////////////////////////////// //
14 |
15 | // Collect collect info about services
16 | func Collect(services ...string) []support.Service {
17 | return nil
18 | }
19 |
--------------------------------------------------------------------------------
/support/support_darwin.go:
--------------------------------------------------------------------------------
1 | package support
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import "github.com/essentialkaos/ek/v13/system"
11 |
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | // appendSystemInfo appends system info
15 | func (i *Info) appendSystemInfo() {
16 | systemInfo, err := system.GetSystemInfo()
17 |
18 | if err != nil {
19 | return
20 | }
21 |
22 | i.System = &SystemInfo{
23 | Name: systemInfo.OS,
24 | ID: systemInfo.ID,
25 | Arch: systemInfo.Arch,
26 | Kernel: systemInfo.Kernel,
27 | }
28 | }
29 |
30 | // appendOSInfo appends OS info
31 | func (i *Info) appendOSInfo() {
32 | osInfo, err := system.GetOSInfo()
33 |
34 | if err != nil {
35 | return
36 | }
37 |
38 | i.OS = &OSInfo{
39 | Name: osInfo.Name,
40 | Version: osInfo.VersionID,
41 | Build: osInfo.Build,
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/support/support_linux.go:
--------------------------------------------------------------------------------
1 | package support
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "github.com/essentialkaos/ek/v13/system"
12 | "github.com/essentialkaos/ek/v13/system/container"
13 | )
14 |
15 | // ////////////////////////////////////////////////////////////////////////////////// //
16 |
17 | // appendSystemInfo appends system info
18 | func (i *Info) appendSystemInfo() {
19 | systemInfo, err := system.GetSystemInfo()
20 |
21 | if err != nil {
22 | return
23 | }
24 |
25 | i.System = &SystemInfo{
26 | Name: systemInfo.OS,
27 | ID: systemInfo.ID,
28 | Arch: systemInfo.Arch,
29 | Kernel: systemInfo.Kernel,
30 | }
31 |
32 | if i.OS != nil {
33 | i.System.Name = i.OS.Name
34 | }
35 |
36 | i.System.ContainerEngine = container.GetEngine()
37 | }
38 |
39 | // appendOSInfo appends OS info
40 | func (i *Info) appendOSInfo() {
41 | osInfo, err := system.GetOSInfo()
42 |
43 | if err != nil {
44 | return
45 | }
46 |
47 | i.OS = &OSInfo{
48 | Name: osInfo.Name,
49 | PrettyName: osInfo.PrettyName,
50 | Version: osInfo.Version,
51 | ID: osInfo.ID,
52 | IDLike: osInfo.IDLike,
53 | VersionID: osInfo.VersionID,
54 | VersionCode: osInfo.VersionCodename,
55 | PlatformID: osInfo.PlatformID,
56 | CPE: osInfo.CPEName,
57 |
58 | coloredName: osInfo.ColoredName(),
59 | coloredPrettyName: osInfo.ColoredPrettyName(),
60 | }
61 | }
62 |
63 | // ////////////////////////////////////////////////////////////////////////////////// //
64 |
--------------------------------------------------------------------------------
/system/container/example_test.go:
--------------------------------------------------------------------------------
1 | package container
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleGetEngine() {
17 | fmt.Printf("Container engine: %s\n", GetEngine())
18 | }
19 |
20 | func ExampleIsContainer() {
21 | if !IsContainer() {
22 | fmt.Println("It's not containerized")
23 | } else {
24 | fmt.Printf("It's containerized using %s engine\n", GetEngine())
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/system/exec/examples_test.go:
--------------------------------------------------------------------------------
1 | package exec
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleRun() {
17 | err := Run("/bin/echo", "abc", "123")
18 |
19 | if err != nil {
20 | fmt.Printf("Error: %v", err)
21 | }
22 | }
23 |
24 | func ExampleSudo() {
25 | err := Sudo("/bin/echo", "abc", "123")
26 |
27 | if err != nil {
28 | fmt.Printf("Error: %v", err)
29 | }
30 | }
31 |
32 | func ExampleRunAsUser() {
33 | // run echo as user some user and redirect output to /var/log/output.log
34 | err := RunAsUser("someuser", "/var/log/output.log", "/bin/echo", "abc", "123")
35 |
36 | if err != nil {
37 | fmt.Printf("Error: %v", err)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/system/exec/exec_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin && !freebsd
2 | // +build !linux,!darwin,!freebsd
3 |
4 | // Package exec provides methods for executing commands
5 | package exec
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | // ❗ Sudo executes command with sudo
15 | func Sudo(user string, args ...string) error {
16 | panic("UNSUPPORTED")
17 | return nil
18 | }
19 |
20 | // ❗ Run executes command
21 | func Run(command string, args ...string) error {
22 | panic("UNSUPPORTED")
23 | return nil
24 | }
25 |
26 | // ❗ RunAsUser runs command as a given user
27 | func RunAsUser(user, logFile string, command string, args ...string) error {
28 | panic("UNSUPPORTED")
29 | return nil
30 | }
31 |
32 | // ////////////////////////////////////////////////////////////////////////////////// //
33 |
--------------------------------------------------------------------------------
/system/info_fs_darwin.go:
--------------------------------------------------------------------------------
1 | package system
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "time"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | // ❗ GetFSUsage returns info about mounted filesystems
17 | func GetFSUsage() (map[string]*FSUsage, error) {
18 | panic("UNSUPPORTED")
19 | return map[string]*FSUsage{"/": {}}, nil
20 | }
21 |
22 | // ❗ GetIOStats returns I/O stats
23 | func GetIOStats() (map[string]*IOStats, error) {
24 | panic("UNSUPPORTED")
25 | return map[string]*IOStats{"/dev/sda1": {}}, nil
26 | }
27 |
28 | // ❗ GetIOUtil returns IO utilization
29 | func GetIOUtil(duration time.Duration) (map[string]float64, error) {
30 | panic("UNSUPPORTED")
31 | return map[string]float64{"/": 0}, nil
32 | }
33 |
34 | // ❗ CalculateIOUtil calculates IO utilization for all devices
35 | func CalculateIOUtil(io1, io2 map[string]*IOStats, duration time.Duration) map[string]float64 {
36 | panic("UNSUPPORTED")
37 | return map[string]float64{"/": 0}
38 | }
39 |
--------------------------------------------------------------------------------
/system/info_linux_arm.go:
--------------------------------------------------------------------------------
1 | //go:build linux && arm
2 | // +build linux,arm
3 |
4 | package system
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | // byteSliceToString convert byte slice to string
14 | func byteSliceToString(s [65]uint8) string {
15 | result := ""
16 |
17 | for _, r := range s {
18 | if r == 0 {
19 | break
20 | }
21 |
22 | result += string(rune(r))
23 | }
24 |
25 | return result
26 | }
27 |
--------------------------------------------------------------------------------
/system/info_linux_basic.go:
--------------------------------------------------------------------------------
1 | //go:build linux && (386 || arm64 || amd64)
2 | // +build linux
3 | // +build 386 arm64 amd64
4 |
5 | package system
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | // byteSliceToString convert byte slice to string
15 | func byteSliceToString(s [65]int8) string {
16 | result := ""
17 |
18 | for _, r := range s {
19 | if r == 0 {
20 | break
21 | }
22 |
23 | result += string(rune(r))
24 | }
25 |
26 | return result
27 | }
28 |
--------------------------------------------------------------------------------
/system/info_net_darwin.go:
--------------------------------------------------------------------------------
1 | package system
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "time"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | // ❗ GetInterfacesStats returns info about network interfaces
17 | func GetInterfacesStats() (map[string]*InterfaceStats, error) {
18 | panic("UNSUPPORTED")
19 | return map[string]*InterfaceStats{"eth0": {}}, nil
20 | }
21 |
22 | // ❗ GetNetworkSpeed returns input/output speed in bytes per second
23 | func GetNetworkSpeed(duration time.Duration) (uint64, uint64, error) {
24 | panic("UNSUPPORTED")
25 | return 0, 0, nil
26 | }
27 |
28 | // ❗ CalculateNetworkSpeed calculates network input/output speed in bytes per second for
29 | // all network interfaces
30 | func CalculateNetworkSpeed(ii1, ii2 map[string]*InterfaceStats, duration time.Duration) (uint64, uint64) {
31 | panic("UNSUPPORTED")
32 | return 0, 0
33 | }
34 |
--------------------------------------------------------------------------------
/system/info_uptime_darwin.go:
--------------------------------------------------------------------------------
1 | package system
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "golang.org/x/sys/unix"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | // GetUptime returns uptime in seconds from 1/1/1970
17 | func GetUptime() (uint64, error) {
18 | tv, err := unix.SysctlTimeval("kern.boottime")
19 |
20 | if err != nil {
21 | return 0, err
22 | }
23 |
24 | return uint64(tv.Sec), nil
25 | }
26 |
--------------------------------------------------------------------------------
/system/info_uptime_linux.go:
--------------------------------------------------------------------------------
1 | package system
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "syscall"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | // GetUptime returns system uptime in seconds
17 | func GetUptime() (uint64, error) {
18 | info := &syscall.Sysinfo_t{}
19 | err := syscall.Sysinfo(info)
20 |
21 | return uint64(info.Uptime), err
22 | }
23 |
--------------------------------------------------------------------------------
/system/process/processes_darwin.go:
--------------------------------------------------------------------------------
1 | package process
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | // ❗ ProcessInfo contains basic info about process
11 | type ProcessInfo struct {
12 | Command string // ❗ Full command
13 | User string // ❗ Username
14 | PID int // ❗ PID
15 | IsThread bool // ❗ True if process is thread
16 | Parent int // ❗ Parent process PID
17 | Children []*ProcessInfo // ❗ Slice with child processes
18 | }
19 |
20 | // ////////////////////////////////////////////////////////////////////////////////// //
21 |
22 | // ❗ GetTree returns root process with all subprocesses on the system
23 | func GetTree(pid ...int) (*ProcessInfo, error) {
24 | panic("UNSUPPORTED")
25 | return nil, nil
26 | }
27 |
28 | // ❗ GetList returns slice with all active processes on the system
29 | func GetList() ([]*ProcessInfo, error) {
30 | panic("UNSUPPORTED")
31 | return nil, nil
32 | }
33 |
--------------------------------------------------------------------------------
/system/process/processes_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin
2 | // +build !linux,!darwin
3 |
4 | package process
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | // ❗ ProcessInfo contains basic info about process
14 | type ProcessInfo struct {
15 | Command string // ❗ Full command
16 | User string // ❗ Username
17 | PID int // ❗ PID
18 | IsThread bool // ❗ True if process is thread
19 | Parent int // ❗ Parent process PID
20 | Children []*ProcessInfo // ❗ Slice with child processes
21 | }
22 |
23 | // ////////////////////////////////////////////////////////////////////////////////// //
24 |
25 | // ❗ GetTree returns root process with all subprocesses on the system
26 | func GetTree(pid ...int) (*ProcessInfo, error) {
27 | panic("UNSUPPORTED")
28 | return nil, nil
29 | }
30 |
31 | // ❗ GetList returns slice with all active processes on the system
32 | func GetList() ([]*ProcessInfo, error) {
33 | panic("UNSUPPORTED")
34 | return nil, nil
35 | }
36 |
--------------------------------------------------------------------------------
/system/procname/examples_test.go:
--------------------------------------------------------------------------------
1 | package procname
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | "os"
13 | "strings"
14 | )
15 |
16 | // ////////////////////////////////////////////////////////////////////////////////// //
17 |
18 | func ExampleSet() {
19 | args := os.Args
20 |
21 | // Mask first argument
22 | args[1] = strings.Repeat("*", len(args[1]))
23 |
24 | err := Set(args)
25 |
26 | if err != nil {
27 | fmt.Printf("Error: %v\n", err)
28 | }
29 | }
30 |
31 | func ExampleReplace() {
32 | password := "mySuppaPass"
33 |
34 | // Replacing known password to asterisks
35 | err := Replace(password, "*****************")
36 |
37 | if err != nil {
38 | fmt.Printf("Error: %v\n", err)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/system/procname/setprocname_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin
2 | // +build !linux,!darwin
3 |
4 | package procname
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | import (
14 | "errors"
15 | )
16 |
17 | // ////////////////////////////////////////////////////////////////////////////////// //
18 |
19 | var (
20 | // ❗ ErrWrongSize is returned if given slice have the wrong size
21 | ErrWrongSize = errors.New("Given slice must have same size as os.Arg")
22 |
23 | // ❗ ErrWrongArguments is returned if one of given arguments is empty
24 | ErrWrongArguments = errors.New("Arguments can't be empty")
25 | )
26 |
27 | // ////////////////////////////////////////////////////////////////////////////////// //
28 |
29 | // ❗ Set changes current process command in process tree
30 | func Set(args []string) error {
31 | panic("UNSUPPORTED")
32 | return nil
33 | }
34 |
35 | // ❗ Replace replaces one argument in process command
36 | //
37 | // WARNING: Be careful with using os.Args or options.Parse result
38 | // as 'from' argument. After using this method given variable content
39 | // will be replaced. Use strutil.Copy method in this case.
40 | func Replace(from, to string) error {
41 | panic("UNSUPPORTED")
42 | return nil
43 | }
44 |
--------------------------------------------------------------------------------
/system/sensors/sensors_darwin.go:
--------------------------------------------------------------------------------
1 | // Package sensors provide methods for collecting sensors information
2 | package sensors
3 |
4 | // ////////////////////////////////////////////////////////////////////////////////// //
5 | // //
6 | // Copyright (c) 2025 ESSENTIAL KAOS //
7 | // Apache License, Version 2.0 //
8 | // //
9 | // ////////////////////////////////////////////////////////////////////////////////// //
10 |
11 | // ❗ Device contains info from different device sensors
12 | type Device struct {
13 | Name string
14 | TempSensors []TempSensor
15 | }
16 |
17 | // ❗ TempSensor contains info from temperature sensor
18 | type TempSensor struct {
19 | Name string
20 | Cur float64
21 | Min float64
22 | Max float64
23 | Crit float64
24 | }
25 |
26 | // ////////////////////////////////////////////////////////////////////////////////// //
27 |
28 | // ❗ Collect collects sensors information
29 | func Collect() ([]*Device, error) {
30 | panic("UNSUPPORTED")
31 | return nil, nil
32 | }
33 |
34 | // ////////////////////////////////////////////////////////////////////////////////// //
35 |
36 | // ❗ Temperature returns min, max and average temperature
37 | func (d *Device) Temperature() (float64, float64, float64) {
38 | panic("UNSUPPORTED")
39 | return 0.0, 0.0, 0.0
40 | }
41 |
42 | // ❗ String formats sensor data as a string
43 | func (s TempSensor) String() string {
44 | panic("UNSUPPORTED")
45 | return ""
46 | }
47 |
48 | // ////////////////////////////////////////////////////////////////////////////////// //
49 |
--------------------------------------------------------------------------------
/system/sensors/sensors_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin
2 | // +build !linux,!darwin
3 |
4 | // Package sensors provide methods for collecting sensors information
5 | package sensors
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | // ❗ Device contains info from different device sensors
15 | type Device struct {
16 | Name string
17 | TempSensors []TempSensor
18 | }
19 |
20 | // ❗ TempSensor contains info from temperature sensor
21 | type TempSensor struct {
22 | Name string
23 | Cur float64
24 | Min float64
25 | Max float64
26 | Crit float64
27 | }
28 |
29 | // ////////////////////////////////////////////////////////////////////////////////// //
30 |
31 | // ❗ Collect collects sensors information
32 | func Collect() ([]*Device, error) {
33 | panic("UNSUPPORTED")
34 | return nil, nil
35 | }
36 |
37 | // ////////////////////////////////////////////////////////////////////////////////// //
38 |
39 | // ❗ Temperature returns min, max and average temperature
40 | func (d *Device) Temperature() (float64, float64, float64) {
41 | panic("UNSUPPORTED")
42 | return 0.0, 0.0, 0.0
43 | }
44 |
45 | // ❗ String formats sensor data as a string
46 | func (s TempSensor) String() string {
47 | panic("UNSUPPORTED")
48 | return ""
49 | }
50 |
51 | // ////////////////////////////////////////////////////////////////////////////////// //
52 |
--------------------------------------------------------------------------------
/system/sysctl/sysctl_darwin.go:
--------------------------------------------------------------------------------
1 | package sysctl
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "bytes"
12 | "fmt"
13 | "os/exec"
14 | "strings"
15 | )
16 |
17 | // ////////////////////////////////////////////////////////////////////////////////// //
18 |
19 | // getParam reads kernel parameter from procfs
20 | func getParam(param string) (string, error) {
21 | output, err := exec.Command(binary, "-n", param).Output()
22 |
23 | if err != nil {
24 | return "", fmt.Errorf("Can't get kernel parameters from sysctl")
25 | }
26 |
27 | return strings.Trim(string(output), "\n\r"), err
28 | }
29 |
30 | // getParams reads all kernel parameters
31 | func getParams() (Params, error) {
32 | output, err := exec.Command(binary, "-a").Output()
33 |
34 | if err != nil {
35 | return nil, fmt.Errorf("Can't get kernel parameters from sysctl")
36 | }
37 |
38 | params := make(Params)
39 | buf := bytes.NewBuffer(output)
40 |
41 | for {
42 | line, err := buf.ReadString('\n')
43 |
44 | if err != nil {
45 | break
46 | }
47 |
48 | name, value, ok := strings.Cut(strings.Trim(line, "\n\r"), ": ")
49 |
50 | if ok {
51 | params[name] = value
52 | }
53 | }
54 |
55 | return params, nil
56 | }
57 |
--------------------------------------------------------------------------------
/system/sysctl/sysctl_linux.go:
--------------------------------------------------------------------------------
1 | package sysctl
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "bytes"
12 | "fmt"
13 | "os"
14 | "os/exec"
15 | "strings"
16 |
17 | "github.com/essentialkaos/ek/v13/path"
18 | )
19 |
20 | // ////////////////////////////////////////////////////////////////////////////////// //
21 |
22 | // getParam reads kernel parameter from procfs
23 | func getParam(param string) (string, error) {
24 | p, err := os.ReadFile(path.Clean(path.Join(
25 | procFS, strings.ReplaceAll(param, ".", "/"),
26 | )))
27 |
28 | if err != nil {
29 | return "", fmt.Errorf("Can't read parameter %q: %w", param, err)
30 | }
31 |
32 | return strings.Trim(string(p), "\n\r"), nil
33 | }
34 |
35 | // getParams reads all kernel parameters
36 | func getParams() (Params, error) {
37 | output, err := exec.Command(binary, "-a").Output()
38 |
39 | if err != nil {
40 | return nil, fmt.Errorf("Can't get kernel parameters from sysctl")
41 | }
42 |
43 | params := make(Params)
44 | buf := bytes.NewBuffer(output)
45 |
46 | for {
47 | line, err := buf.ReadString('\n')
48 |
49 | if err != nil {
50 | break
51 | }
52 |
53 | name, value, ok := strings.Cut(strings.Trim(line, "\n\r"), " = ")
54 |
55 | if ok {
56 | params[name] = value
57 | }
58 | }
59 |
60 | return params, nil
61 | }
62 |
--------------------------------------------------------------------------------
/system/sysctl/sysctl_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin
2 | // +build !linux,!darwin
3 |
4 | // Package sysctl provides methods for reading kernel parameters
5 | package sysctl
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | // Params contains all kernel parameters
15 | type Params map[string]string
16 |
17 | // ////////////////////////////////////////////////////////////////////////////////// //
18 |
19 | // All returns all kernel parameters
20 | func All() (Params, error) {
21 | return nil, nil
22 | }
23 |
24 | // Get returns kernel parameter value as a string
25 | func Get(param string) (string, error) {
26 | return "", nil
27 | }
28 |
29 | // GetI returns kernel parameter value as an int
30 | func GetI(param string) (int, error) {
31 | return 0, nil
32 | }
33 |
34 | // GetI64 returns kernel parameter value as an int64
35 | func GetI64(param string) (int64, error) {
36 | return 0, nil
37 | }
38 |
39 | // ////////////////////////////////////////////////////////////////////////////////// //
40 |
41 | // Get returns kernel parameter value as a string
42 | func (p Params) Get(name string) string {
43 | return ""
44 | }
45 |
46 | // GetI returns kernel parameter value as an int
47 | func (p Params) GetI(param string) (int, error) {
48 | return 0, nil
49 | }
50 |
51 | // GetI64 returns kernel parameter value as an int64
52 | func (p Params) GetI64(param string) (int64, error) {
53 | return 0, nil
54 | }
55 |
--------------------------------------------------------------------------------
/system/user_bsd.go:
--------------------------------------------------------------------------------
1 | //go:build darwin || freebsd
2 | // +build darwin freebsd
3 |
4 | package system
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | import (
14 | "syscall"
15 | "time"
16 | )
17 |
18 | // ////////////////////////////////////////////////////////////////////////////////// //
19 |
20 | // getTimes is copy of fsutil.GetTimes
21 | func getTimes(path string) (time.Time, time.Time, time.Time, error) {
22 | if path == "" {
23 | return time.Time{}, time.Time{}, time.Time{}, ErrEmptyPath
24 | }
25 |
26 | var stat = &syscall.Stat_t{}
27 |
28 | err := syscall.Stat(path, stat)
29 |
30 | if err != nil {
31 | return time.Time{}, time.Time{}, time.Time{}, err
32 | }
33 |
34 | return time.Unix(int64(stat.Atimespec.Sec), int64(stat.Atimespec.Nsec)),
35 | time.Unix(int64(stat.Mtimespec.Sec), int64(stat.Mtimespec.Nsec)),
36 | time.Unix(int64(stat.Ctimespec.Sec), int64(stat.Ctimespec.Nsec)),
37 | nil
38 | }
39 |
--------------------------------------------------------------------------------
/system/user_linux.go:
--------------------------------------------------------------------------------
1 | package system
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "syscall"
12 | "time"
13 | )
14 |
15 | // ////////////////////////////////////////////////////////////////////////////////// //
16 |
17 | // getTimes is copy of fsutil.GetTimes
18 | func getTimes(path string) (time.Time, time.Time, time.Time, error) {
19 | if path == "" {
20 | return time.Time{}, time.Time{}, time.Time{}, ErrEmptyPath
21 | }
22 |
23 | var stat = &syscall.Stat_t{}
24 |
25 | err := syscall.Stat(path, stat)
26 |
27 | if err != nil {
28 | return time.Time{}, time.Time{}, time.Time{}, err
29 | }
30 |
31 | return time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)),
32 | time.Unix(int64(stat.Mtim.Sec), int64(stat.Mtim.Nsec)),
33 | time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec)),
34 | nil
35 | }
36 |
--------------------------------------------------------------------------------
/terminal/terminal_test.go:
--------------------------------------------------------------------------------
1 | package terminal
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | "testing"
13 |
14 | . "github.com/essentialkaos/check"
15 | )
16 |
17 | // ////////////////////////////////////////////////////////////////////////////////// //
18 |
19 | func Test(t *testing.T) { TestingT(t) }
20 |
21 | type TerminalSuite struct{}
22 |
23 | // ////////////////////////////////////////////////////////////////////////////////// //
24 |
25 | var _ = Suite(&TerminalSuite{})
26 |
27 | // ////////////////////////////////////////////////////////////////////////////////// //
28 |
29 | func (s *TerminalSuite) TestMessage(c *C) {
30 | Error("Test %s", "Error")
31 | Warn("Test %s", "Warn")
32 | Info("Test %s", "Info")
33 |
34 | Error(fmt.Errorf("Error"))
35 | Error([]string{"Error"})
36 | }
37 |
38 | func (s *TerminalSuite) TestMessageWithPrefix(c *C) {
39 | ErrorPrefix = "▲ "
40 | WarnPrefix = "▲ "
41 | InfoPrefix = "▲ "
42 |
43 | Error("Test %s\nMessage\n", "Error")
44 | Warn("Test %s\nMessage\n", "Warn")
45 | Info("Test %s\nMessage\n", "Info")
46 |
47 | ErrorPrefix = ""
48 | WarnPrefix = ""
49 | InfoPrefix = ""
50 | }
51 |
52 | func (s *TerminalSuite) TestAction(c *C) {
53 | PrintActionMessage("Testing")
54 | PrintActionStatus(0)
55 |
56 | PrintActionMessage("Testing")
57 | PrintActionStatus(1)
58 |
59 | PrintActionMessage("Testing")
60 | PrintActionStatus(2)
61 |
62 | PrintActionMessage("Testing")
63 | PrintActionStatus(3)
64 | }
65 |
--------------------------------------------------------------------------------
/terminal/tty/example_test.go:
--------------------------------------------------------------------------------
1 | package tty
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleIsTTY() {
17 | if IsTTY() {
18 | fmt.Println("Output is TTY")
19 | } else {
20 | fmt.Println("Output is not TTY")
21 | }
22 | }
23 |
24 | func ExampleIsTMUX() {
25 | isTmux, err := IsTMUX()
26 |
27 | if err != nil {
28 | panic(err.Error())
29 | }
30 |
31 | if isTmux {
32 | fmt.Println("App works in tmux")
33 | } else {
34 | fmt.Println("App works in bare terminal")
35 | }
36 | }
37 |
38 | func ExampleIsSystemd() {
39 | if IsSystemd() {
40 | fmt.Println("This process started by systemd")
41 | }
42 | }
43 |
44 | func ExampleGetSize() {
45 | width, height := GetSize()
46 |
47 | if width == -1 && height == -1 {
48 | fmt.Println("Can't detect window size")
49 | return
50 | }
51 |
52 | fmt.Printf("Window size: %d x %d\n", width, height)
53 | }
54 |
55 | func ExampleGetWidth() {
56 | width := GetWidth()
57 |
58 | if width == -1 {
59 | fmt.Println("Can't detect window size")
60 | return
61 | }
62 |
63 | fmt.Printf("Window width: %d\n", width)
64 | }
65 |
66 | func ExampleGetHeight() {
67 | height := GetHeight()
68 |
69 | if height == -1 {
70 | fmt.Println("Can't detect window size")
71 | return
72 | }
73 |
74 | fmt.Printf("Window height: %d\n", height)
75 | }
76 |
--------------------------------------------------------------------------------
/terminal/tty/size_posix.go:
--------------------------------------------------------------------------------
1 | //go:build !windows
2 | // +build !windows
3 |
4 | package tty
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | import (
14 | "os"
15 | "syscall"
16 | "unsafe"
17 | )
18 |
19 | // ////////////////////////////////////////////////////////////////////////////////// //
20 |
21 | type winsize struct {
22 | rows uint16
23 | cols uint16
24 | xpixels uint16
25 | ypixels uint16
26 | }
27 |
28 | // ////////////////////////////////////////////////////////////////////////////////// //
29 |
30 | // tty is a path to TTY device file
31 | var tty = "/dev/tty"
32 |
33 | // ////////////////////////////////////////////////////////////////////////////////// //
34 |
35 | // GetSize returns window width and height
36 | func GetSize() (int, int) {
37 | t, err := os.OpenFile(tty, syscall.O_RDONLY, 0)
38 |
39 | if err != nil {
40 | return -1, -1
41 | }
42 |
43 | var sz winsize
44 |
45 | _, _, _ = syscall.Syscall(
46 | syscall.SYS_IOCTL, t.Fd(),
47 | uintptr(syscall.TIOCGWINSZ),
48 | uintptr(unsafe.Pointer(&sz)),
49 | )
50 |
51 | return int(sz.cols), int(sz.rows)
52 | }
53 |
54 | // GetWidth returns window width
55 | func GetWidth() int {
56 | w, _ := GetSize()
57 | return w
58 | }
59 |
60 | // GetHeight returns window height
61 | func GetHeight() int {
62 | _, h := GetSize()
63 | return h
64 | }
65 |
--------------------------------------------------------------------------------
/terminal/tty/tmux_darwin.go:
--------------------------------------------------------------------------------
1 | //go:build darwin
2 | // +build darwin
3 |
4 | package tty
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | // isTmuxAncestor returns true if the current process is an ancestor of tmux
14 | func isTmuxAncestor() (bool, error) {
15 | return false, nil
16 | }
17 |
--------------------------------------------------------------------------------
/terminal/tty/tmux_linux.go:
--------------------------------------------------------------------------------
1 | //go:build linux
2 | // +build linux
3 |
4 | package tty
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | import (
14 | "errors"
15 | "os"
16 | "strconv"
17 | "strings"
18 |
19 | "github.com/essentialkaos/ek/v13/strutil"
20 | )
21 |
22 | // ////////////////////////////////////////////////////////////////////////////////// //
23 |
24 | var procFS = "/proc"
25 |
26 | // ////////////////////////////////////////////////////////////////////////////////// //
27 |
28 | // isTmuxAncestor returns true if the current process is an ancestor of tmux
29 | func isTmuxAncestor() (bool, error) {
30 | pid := strconv.Itoa(os.Getppid())
31 |
32 | for {
33 | statFile := procFS + "/" + pid + "/stat"
34 | statData, err := os.ReadFile(statFile)
35 |
36 | if err != nil {
37 | return false, errors.New("Can't check process tree for tmux server")
38 | }
39 |
40 | statString := string(statData)
41 | processName := strutil.ReadField(statString, 1, false, ' ')
42 |
43 | if strings.HasPrefix(processName, "(tmux:") {
44 | return true, nil
45 | }
46 |
47 | parentPID := strutil.ReadField(statString, 3, false, ' ')
48 |
49 | if parentPID == "1" || parentPID == "0" {
50 | break
51 | }
52 |
53 | pid = parentPID
54 | }
55 |
56 | return false, nil
57 | }
58 |
--------------------------------------------------------------------------------
/terminal/tty/tty_posix.go:
--------------------------------------------------------------------------------
1 | //go:build !windows
2 | // +build !windows
3 |
4 | // Package tty provides methods for working with TTY
5 | package tty
6 |
7 | // ////////////////////////////////////////////////////////////////////////////////// //
8 | // //
9 | // Copyright (c) 2025 ESSENTIAL KAOS //
10 | // Apache License, Version 2.0 //
11 | // //
12 | // ////////////////////////////////////////////////////////////////////////////////// //
13 |
14 | import (
15 | "os"
16 | )
17 |
18 | // ////////////////////////////////////////////////////////////////////////////////// //
19 |
20 | var stdout, _ = os.Stdout.Stat()
21 |
22 | // ////////////////////////////////////////////////////////////////////////////////// //
23 |
24 | // IsTTY returns true if current output device is TTY
25 | func IsTTY() bool {
26 | if stdout.Mode()&os.ModeCharDevice == 0 && !IsFakeTTY() {
27 | return false
28 | }
29 |
30 | return true
31 | }
32 |
33 | // IsTMUX returns true if we are currently working in tmux
34 | func IsTMUX() (bool, error) {
35 | if os.Getenv("TMUX") != "" {
36 | return true, nil
37 | }
38 |
39 | return isTmuxAncestor()
40 | }
41 |
42 | // IsFakeTTY returns true is fake TTY is used
43 | func IsFakeTTY() bool {
44 | return os.Getenv("FAKETTY") != ""
45 | }
46 |
47 | // IsSystemd returns true if process started by systemd
48 | func IsSystemd() bool {
49 | return os.Getppid() == 1
50 | }
51 |
52 | // ////////////////////////////////////////////////////////////////////////////////// //
53 |
--------------------------------------------------------------------------------
/terminal/tty/tty_stubs.go:
--------------------------------------------------------------------------------
1 | //go:build !linux && !darwin
2 | // +build !linux,!darwin
3 |
4 | package tty
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | // ❗ IsTTY returns true if current output device is TTY
14 | func IsTTY() bool {
15 | panic("UNSUPPORTED")
16 | }
17 |
18 | // ❗ IsFakeTTY returns true is fake TTY is used
19 | func IsFakeTTY() bool {
20 | panic("UNSUPPORTED")
21 | }
22 |
23 | // ❗ IsTMUX returns true if we are currently working in tmux
24 | func IsTMUX() (bool, error) {
25 | panic("UNSUPPORTED")
26 | }
27 |
28 | // ❗ IsSystemd returns true if process started by systemd
29 | func IsSystemd() bool {
30 | panic("UNSUPPORTED")
31 | }
32 |
33 | // ❗ GetSize returns window width and height
34 | func GetSize() (int, int) {
35 | panic("UNSUPPORTED")
36 | }
37 |
38 | // ❗ GetWidth returns window width
39 | func GetWidth() int {
40 | panic("UNSUPPORTED")
41 | }
42 |
43 | // ❗ GetHeight returns window height
44 | func GetHeight() int {
45 | panic("UNSUPPORTED")
46 | }
47 |
--------------------------------------------------------------------------------
/timeutil/fuzz.go:
--------------------------------------------------------------------------------
1 | //go:build gofuzz
2 | // +build gofuzz
3 |
4 | package timeutil
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | import (
14 | "time"
15 | )
16 |
17 | // ////////////////////////////////////////////////////////////////////////////////// //
18 |
19 | var fuzzTestDate = time.Now()
20 |
21 | // ////////////////////////////////////////////////////////////////////////////////// //
22 |
23 | func Fuzz(data []byte) int {
24 | f := Format(fuzzTestDate, string(data))
25 |
26 | if f != "" {
27 | return 0
28 | }
29 |
30 | return 1
31 | }
32 |
--------------------------------------------------------------------------------
/timeutil/timeutil_unix.go:
--------------------------------------------------------------------------------
1 | //go:build linux || freebsd || darwin
2 | // +build linux freebsd darwin
3 |
4 | package timeutil
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | import (
14 | "os"
15 | "strings"
16 | )
17 |
18 | // ////////////////////////////////////////////////////////////////////////////////// //
19 |
20 | // localZoneFile is path to link to current tz info file
21 | var localZoneFile = "/etc/localtime"
22 |
23 | // ////////////////////////////////////////////////////////////////////////////////// //
24 |
25 | // LocalTimezone returns name of local timezone
26 | func LocalTimezone() string {
27 | tzName := os.Getenv("TZ")
28 |
29 | if tzName != "" {
30 | return tzName
31 | }
32 |
33 | zoneFile, err := os.Readlink(localZoneFile)
34 |
35 | if err != nil {
36 | return "Local"
37 | }
38 |
39 | index := strings.Index(zoneFile, "zoneinfo/")
40 |
41 | if index == -1 {
42 | return "Local"
43 | }
44 |
45 | return zoneFile[index+9:]
46 | }
47 |
--------------------------------------------------------------------------------
/timeutil/timeutil_unix_test.go:
--------------------------------------------------------------------------------
1 | //go:build linux || freebsd || darwin
2 | // +build linux freebsd darwin
3 |
4 | package timeutil
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | import (
14 | "os"
15 |
16 | . "github.com/essentialkaos/check"
17 | )
18 |
19 | // ////////////////////////////////////////////////////////////////////////////////// //
20 |
21 | func (s *TimeUtilSuite) TestLocalTimezone(c *C) {
22 | os.Unsetenv("TZ")
23 | c.Assert(LocalTimezone(), Not(Equals), "Local")
24 |
25 | os.Setenv("TZ", "Europe/Zurich")
26 | c.Assert(LocalTimezone(), Equals, "Europe/Zurich")
27 | os.Unsetenv("TZ")
28 |
29 | testDir := c.MkDir()
30 | os.Symlink("/usr/share/unknown", testDir+"/localtime")
31 | localZoneFile = testDir + "/localtime"
32 |
33 | c.Assert(LocalTimezone(), Equals, "Local")
34 |
35 | localZoneFile = "/_unknown_"
36 | c.Assert(LocalTimezone(), Equals, "Local")
37 | }
38 |
--------------------------------------------------------------------------------
/timeutil/timeutil_windows.go:
--------------------------------------------------------------------------------
1 | package timeutil
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "golang.org/x/sys/windows/registry"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | // registryKey is key of registry record with TZ data
17 | var registryKey = `SYSTEM\CurrentControlSet\Control\TimeZoneInformation`
18 |
19 | // registryKeyName is name of registry key record
20 | var registryKeyName = "TimeZoneKeyName"
21 |
22 | // ////////////////////////////////////////////////////////////////////////////////// //
23 |
24 | // LocalTimezone returns name of local timezone
25 | func LocalTimezone() string {
26 | key, err := registry.OpenKey(registry.LOCAL_MACHINE, registryKey, registry.QUERY_VALUE)
27 |
28 | if err != nil {
29 | return "Local"
30 | }
31 |
32 | tzName, _, err := key.GetStringValue(registryKeyName)
33 |
34 | if err != nil {
35 | return "Local"
36 | }
37 |
38 | return tzName
39 | }
40 |
--------------------------------------------------------------------------------
/timeutil/timeutil_windows_test.go:
--------------------------------------------------------------------------------
1 | //go:build windows
2 | // +build windows
3 |
4 | package timeutil
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | import (
14 | . "github.com/essentialkaos/check"
15 | )
16 |
17 | // ////////////////////////////////////////////////////////////////////////////////// //
18 |
19 | func (s *TimeUtilSuite) TestLocalTimezone(c *C) {
20 | c.Assert(LocalTimezone(), Not(Equals), "Local")
21 |
22 | registryKeyName = "Unknown"
23 | c.Assert(LocalTimezone(), Equals, "Local")
24 |
25 | registryKey = "Unknown"
26 | c.Assert(LocalTimezone(), Equals, "Local")
27 | }
28 |
--------------------------------------------------------------------------------
/timeutil/tinydate.go:
--------------------------------------------------------------------------------
1 | package timeutil
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "time"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | // Date is tiny date
17 | type Date uint32
18 |
19 | // ////////////////////////////////////////////////////////////////////////////////// //
20 |
21 | // StartDate contains start date timestamp
22 | var StartDate = uint32(1322611200)
23 |
24 | // ////////////////////////////////////////////////////////////////////////////////// //
25 |
26 | // TinyDate creates tiny date struct by timestamp
27 | func TinyDate(t int64) Date {
28 | return Date(uint32(t) - StartDate)
29 | }
30 |
31 | // Unix returns unix timestamp
32 | func (d Date) Unix() int64 {
33 | return int64(StartDate + uint32(d))
34 | }
35 |
36 | // Time returns time struct
37 | func (d Date) Time() time.Time {
38 | return time.Unix(int64(uint32(d)+StartDate), 0)
39 | }
40 |
--------------------------------------------------------------------------------
/usage/completion/bash/examples_test.go:
--------------------------------------------------------------------------------
1 | package bash
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 |
13 | "github.com/essentialkaos/ek/v13/usage"
14 | )
15 |
16 | // ////////////////////////////////////////////////////////////////////////////////// //
17 |
18 | func ExampleGenerate() {
19 | info := usage.NewInfo()
20 |
21 | info.AddCommand("test", "Test data")
22 | info.AddCommand("clean", "Clean data")
23 |
24 | info.AddOption("d:dir", "Path to working directory", "dir")
25 |
26 | info.BoundOptions("test", "d:dir")
27 | info.BoundOptions("clean", "d:dir")
28 |
29 | info.AddOption("nc:no-color", "Disable colors in output")
30 | info.AddOption("h:help", "Show this help message")
31 | info.AddOption("v:version", "Show version")
32 |
33 | fmt.Println(Generate(info, "app", "txt"))
34 | }
35 |
--------------------------------------------------------------------------------
/usage/completion/fish/examples_test.go:
--------------------------------------------------------------------------------
1 | package fish
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 |
13 | "github.com/essentialkaos/ek/v13/usage"
14 | )
15 |
16 | // ////////////////////////////////////////////////////////////////////////////////// //
17 |
18 | func ExampleGenerate() {
19 | info := usage.NewInfo()
20 |
21 | info.AddCommand("test", "Test data")
22 | info.AddCommand("clean", "Clean data")
23 |
24 | info.AddOption("d:dir", "Path to working directory", "dir")
25 |
26 | info.BoundOptions("test", "d:dir")
27 | info.BoundOptions("clean", "d:dir")
28 |
29 | info.AddOption("nc:no-color", "Disable colors in output")
30 | info.AddOption("h:help", "Show this help message")
31 | info.AddOption("v:version", "Show version")
32 |
33 | fmt.Println(Generate(info, "app"))
34 | }
35 |
--------------------------------------------------------------------------------
/usage/completion/zsh/examples_test.go:
--------------------------------------------------------------------------------
1 | package zsh
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 |
13 | "github.com/essentialkaos/ek/v13/options"
14 | "github.com/essentialkaos/ek/v13/usage"
15 | )
16 |
17 | // ////////////////////////////////////////////////////////////////////////////////// //
18 |
19 | func ExampleGenerate() {
20 | info := usage.NewInfo()
21 |
22 | info.AddCommand("test", "Test data")
23 | info.AddCommand("clean", "Clean data")
24 |
25 | info.AddOption("d:dir", "Path to working directory", "dir")
26 |
27 | info.BoundOptions("test", "d:dir")
28 | info.BoundOptions("clean", "d:dir")
29 |
30 | info.AddOption("nc:no-color", "Disable colors in output")
31 | info.AddOption("h:help", "Show this help message")
32 | info.AddOption("v:version", "Show version")
33 |
34 | opts := options.Map{
35 | "d:dir": {},
36 | "nc:no-color": {Type: options.BOOL},
37 | "h:help": {Type: options.BOOL},
38 | "v:version": {Type: options.BOOL},
39 | }
40 |
41 | fmt.Println(Generate(info, opts, "app", "*.txt"))
42 | }
43 |
--------------------------------------------------------------------------------
/uuid/example_test.go:
--------------------------------------------------------------------------------
1 | package uuid
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // ////////////////////////////////////////////////////////////////////////////////// //
15 |
16 | func ExampleUUID4() {
17 | fmt.Printf("UUID v4: %s\n", UUID4().String())
18 | }
19 |
20 | func ExampleUUID5() {
21 | fmt.Printf("UUID v5: %s\n", UUID5(NsURL, "http://www.domain.com").String())
22 | }
23 |
24 | func ExampleUUID7() {
25 | fmt.Printf("UUID v7: %s\n", UUID7().String())
26 | }
27 |
--------------------------------------------------------------------------------
/uuid/prefixed/example_test.go:
--------------------------------------------------------------------------------
1 | package prefixed
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "fmt"
12 |
13 | "github.com/essentialkaos/ek/v13/uuid"
14 | )
15 |
16 | // ////////////////////////////////////////////////////////////////////////////////// //
17 |
18 | func ExampleEncode() {
19 | pu := Encode("user", uuid.UUID7())
20 |
21 | fmt.Printf("UUID: %s\n", pu)
22 | }
23 |
24 | func ExampleDecode() {
25 | prefix, u, err := Decode("user.AZXm2EAle0im2Nloa94Wjg")
26 |
27 | fmt.Printf("Prefix: %s | UUID: %s | Error: %v\n", prefix, u, err)
28 | }
29 |
--------------------------------------------------------------------------------
/uuid/prefixed/prefixed.go:
--------------------------------------------------------------------------------
1 | // Package prefixed contains methods for encoding/decoding prefixed UUID
2 | package prefixed
3 |
4 | // ////////////////////////////////////////////////////////////////////////////////// //
5 | // //
6 | // Copyright (c) 2025 ESSENTIAL KAOS //
7 | // Apache License, Version 2.0 //
8 | // //
9 | // ////////////////////////////////////////////////////////////////////////////////// //
10 |
11 | import (
12 | "encoding/base64"
13 | "errors"
14 | "strings"
15 |
16 | "github.com/essentialkaos/ek/v13/uuid"
17 | )
18 |
19 | // ////////////////////////////////////////////////////////////////////////////////// //
20 |
21 | // encoder is Base64 encoder
22 | var encoder = base64.StdEncoding.WithPadding(base64.NoPadding)
23 |
24 | // ////////////////////////////////////////////////////////////////////////////////// //
25 |
26 | // Encode creates Base64-encoded prefixed UUID
27 | func Encode(prefix string, uuid uuid.UUID) string {
28 | if prefix == "" || uuid.IsZero() {
29 | return ""
30 | }
31 |
32 | return prefix + "." + encoder.EncodeToString(uuid)
33 | }
34 |
35 | // Decode decodes prefixed UUID
36 | func Decode(prefixedUUID string) (string, uuid.UUID, error) {
37 | prefix, data, ok := strings.Cut(prefixedUUID, ".")
38 |
39 | switch {
40 | case !ok:
41 | return "", nil, errors.New("Prefixed UUID has no prefix")
42 | case prefix == "":
43 | return "", nil, errors.New("Prefixed UUID has empty prefix")
44 | case data == "":
45 | return "", nil, errors.New("Prefixed UUID has no UUID data")
46 | }
47 |
48 | u, err := encoder.DecodeString(data)
49 |
50 | if err != nil {
51 | return "", nil, errors.New("Can't decode UUID data: " + err.Error())
52 | }
53 |
54 | return prefix, uuid.UUID(u), nil
55 | }
56 |
--------------------------------------------------------------------------------
/uuid/uuid_test.go:
--------------------------------------------------------------------------------
1 | package uuid
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | import (
11 | "testing"
12 |
13 | . "github.com/essentialkaos/check"
14 | )
15 |
16 | // ////////////////////////////////////////////////////////////////////////////////// //
17 |
18 | func Test(t *testing.T) { TestingT(t) }
19 |
20 | type UUIDSuite struct{}
21 |
22 | // ////////////////////////////////////////////////////////////////////////////////// //
23 |
24 | var _ = Suite(&UUIDSuite{})
25 |
26 | // ////////////////////////////////////////////////////////////////////////////////// //
27 |
28 | func (s *UUIDSuite) TestUUID4(c *C) {
29 | c.Assert(UUID4(), HasLen, 16)
30 | c.Assert(UUID4().String(), Not(Equals), "00000000-0000-0000-0000-000000000000")
31 | c.Assert(UUID4().IsZero(), Equals, false)
32 | }
33 |
34 | func (s *UUIDSuite) TestUUID5(c *C) {
35 | c.Assert(UUID5(NsURL, "TEST"), HasLen, 16)
36 | c.Assert(UUID5(NsURL, "TEST").String(), Not(Equals), "00000000-0000-0000-0000-000000000000")
37 | c.Assert(UUID5(NsURL, "TEST").IsZero(), Equals, false)
38 | }
39 |
40 | func (s *UUIDSuite) TestUUID7(c *C) {
41 | c.Assert(UUID7(), HasLen, 16)
42 | c.Assert(UUID7().String(), Not(Equals), "00000000-0000-0000-0000-000000000000")
43 | c.Assert(UUID7().IsZero(), Equals, false)
44 | }
45 |
46 | func (s *UUIDSuite) BenchmarkUUID4(c *C) {
47 | for range c.N {
48 | UUID4()
49 | }
50 | }
51 |
52 | func (s *UUIDSuite) BenchmarkUUID5(c *C) {
53 | for range c.N {
54 | UUID5(NsURL, "TEST")
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/version.go:
--------------------------------------------------------------------------------
1 | package ek
2 |
3 | // ////////////////////////////////////////////////////////////////////////////////// //
4 | // //
5 | // Copyright (c) 2025 ESSENTIAL KAOS //
6 | // Apache License, Version 2.0 //
7 | // //
8 | // ////////////////////////////////////////////////////////////////////////////////// //
9 |
10 | // VERSION is current ek package version
11 | const VERSION = "13.28.0"
12 |
--------------------------------------------------------------------------------
/version/fuzz.go:
--------------------------------------------------------------------------------
1 | //go:build gofuzz
2 | // +build gofuzz
3 |
4 | package version
5 |
6 | // ////////////////////////////////////////////////////////////////////////////////// //
7 | // //
8 | // Copyright (c) 2025 ESSENTIAL KAOS //
9 | // Apache License, Version 2.0 //
10 | // //
11 | // ////////////////////////////////////////////////////////////////////////////////// //
12 |
13 | func Fuzz(data []byte) int {
14 | _, err := Parse(string(data))
15 |
16 | if err != nil {
17 | return 0
18 | }
19 |
20 | return 1
21 | }
22 |
--------------------------------------------------------------------------------