1
Fork 0
mirror of https://github.com/RGBCube/nu_scripts synced 2025-08-02 15:17:47 +00:00

improve kconf import (#481)

* improve kconf import

The order of fields loaded via `from yaml` is unstable, so use yq to
read it as json, and then load it by `from json`.

Aims to be `diff` friendly.

Remove the square brackets from the week field and use color to
distinguish it, taking up less space.

* kube_stat shows $ctx.NAME instead of complex combination of $ctx.AUTHINFO and $ctx.CLUSTER

- Improve the default theme of kube_stat.
- Clean up duplicate comments in `kubernetes.nu`.

* when power's DECORATOR mode is `power`, allows to dynamically change the background color

- components now needs to return two values in an array, the first value is the background color, and the second value is the original value.
- as an example, `atuin_stat` reveal its status with two different colors instead of showing or hiding

* allowing pass `config` when register or inject a component

The main difference between `config` and `theme` is: theme assumes you pass a color and will apply with `ansi -e {fg : $arg}`

And in most cases, you don't need to pass `config`

* added new function `power set`

time_segment allows format control via option `short`

* rename `nu-complete kube def` to `nu-complete kube kind`

- get all resources via `kubectl api-resources`
- enable cache

* use `from yaml` instead of `yq -o=json | from json` (for next version)

* nu-complete kube kind: add SHORTNAMES as description

* Fix the caching mechanism of `kube ctx` and `kube kind`

based on the number of file lines instead of modification time.

Because switching the context will change the content of the file, the time will be updated every time

* Added new command `kcache flush` to rebuild the cache.

Sometimes, such as manually editing the cluster address in the
configuration file, the number of lines has not changed, and the cache
does need to be refreshed

* use `path dirname` instead of `dirname`

* applying `ensure-cache-by-lines` in `kube_stat`

---------

Co-authored-by: agent <agent@nuc>
This commit is contained in:
fj0r 2023-05-11 19:37:39 +08:00 committed by GitHub
parent ee996ec169
commit 2d6f32657a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 164 additions and 93 deletions

View file

@ -22,15 +22,24 @@ export def "parse cmd" [] {
| reject sw | reject sw
} }
export def ensure-cache [cache path action] { export def ensure-cache-by-lines [cache path action] {
let ts = (do -i { ls $path | sort-by modified | reverse | get 0.modified }) let ls = (do -i { open $path | lines | length })
if ($ts | is-empty) { return false } if ($ls | is-empty) { return false }
let tc = (do -i { ls $cache | get 0.modified }) let lc = (do -i { open $cache | get lines})
if not (($cache | path exists) and ($ts < $tc)) { if not (($cache | path exists) and (not ($lc | is-empty)) and ($ls == $lc)) {
mkdir (dirname $cache) mkdir ($cache | path dirname)
do $action | save -f $cache {
lines: $ls
payload: (do $action)
} | save -f $cache
} }
open $cache (open $cache).payload
}
export def `kcache flush` [] {
rm -rf ~/.cache/nu-complete/k8s/
nu-complete kube ctx
rm -rf ~/.cache/nu-complete/k8s-api-resources/
} }
export-env { export-env {
@ -70,13 +79,13 @@ export def kk [p: path] {
### ctx ### ctx
export def "kube-config" [] { export def "kube-config" [] {
let file = if ($env.KUBECONFIG? | is-empty) { $"($env.HOME)/.kube/config" } else { $env.KUBECONFIG } let file = if ($env.KUBECONFIG? | is-empty) { $"($env.HOME)/.kube/config" } else { $env.KUBECONFIG }
{ path: $file, data: (cat $file | from yaml)} { path: $file, data: (cat $file | from yaml) }
} }
def "nu-complete kube ctx" [] { def "nu-complete kube ctx" [] {
let k = (kube-config) let k = (kube-config)
let cache = $'($env.HOME)/.cache/nu-complete/k8s/(basename $k.path).json' let cache = $'($env.HOME)/.cache/nu-complete/k8s/($k.path | path basename).json'
let data = (ensure-cache $cache $k.path { || let data = (ensure-cache-by-lines $cache $k.path { ||
let clusters = ($k.data | get clusters | select name cluster.server) let clusters = ($k.data | get clusters | select name cluster.server)
let data = ($k.data let data = ($k.data
| get contexts | get contexts
@ -120,18 +129,18 @@ export def 'kconf import' [name: string, path: string] {
let k = (kube-config) let k = (kube-config)
let d = $k.data let d = $k.data
let i = (cat $path | from yaml) let i = (cat $path | from yaml)
let c = [{ let c = {
name: $name, name: $name,
context: { context: {
cluster: $name, cluster: $name,
namespace: default, namespace: default,
user: $name user: $name
} }
}] }
$d $d
| upsert contexts ($d.contexts | append $c)
| upsert clusters ($d.clusters | append ($i.clusters.0 | upsert name $name)) | upsert clusters ($d.clusters | append ($i.clusters.0 | upsert name $name))
| upsert users ($d.users | append ($i.users.0 | upsert name $name)) | upsert users ($d.users | append ($i.users.0 | upsert name $name))
| upsert contexts ($d.contexts | append $c)
| to yaml | to yaml
} }
@ -159,14 +168,19 @@ export def-env kcconf [name: string@"nu-complete kube ctx"] {
} }
### common ### common
def "nu-complete kube def" [] { export def "nu-complete kube kind without cache" [] {
[ kubectl api-resources | from ssv -a | get NAME
pod deployment svc endpoints | append (kubectl get crd | from ssv -a | get NAME)
configmap secret event }
namespace node pv pvc ingress
job cronjob daemonset statefulset export def "nu-complete kube kind" [] {
clusterrole clusterrolebinding role serviceaccount rolebinding let ctx = (kube-config)
] | append (kubectl get crd | from ssv -a | get NAME) let cache = $'($env.HOME)/.cache/nu-complete/k8s-api-resources/($ctx.data.current-context).json'
ensure-cache-by-lines $cache $ctx.path {||
kubectl api-resources | from ssv -a
| each {|x| {value: $x.NAME description: $x.SHORTNAMES} }
| append (kubectl get crd | from ssv -a | each {|x| {$x.NAME} })
}
} }
def "nu-complete kube res" [context: string, offset: int] { def "nu-complete kube res" [context: string, offset: int] {
@ -178,7 +192,7 @@ def "nu-complete kube res" [context: string, offset: int] {
} }
export def kg [ export def kg [
r: string@"nu-complete kube def" r: string@"nu-complete kube kind"
-n: string@"nu-complete kube ns" -n: string@"nu-complete kube ns"
--all (-A):bool --all (-A):bool
] { ] {
@ -195,7 +209,7 @@ export def kg [
} }
export def kc [ export def kc [
r: string@"nu-complete kube def" r: string@"nu-complete kube kind"
-n: string@"nu-complete kube ns" -n: string@"nu-complete kube ns"
name:string name:string
] { ] {
@ -204,7 +218,7 @@ export def kc [
} }
export def ky [ export def ky [
r: string@"nu-complete kube def" r: string@"nu-complete kube kind"
i: string@"nu-complete kube res" i: string@"nu-complete kube res"
-n: string@"nu-complete kube ns" -n: string@"nu-complete kube ns"
] { ] {
@ -213,7 +227,7 @@ export def ky [
} }
export def kd [ export def kd [
r: string@"nu-complete kube def" r: string@"nu-complete kube kind"
i: string@"nu-complete kube res" i: string@"nu-complete kube res"
-n: string@"nu-complete kube ns" -n: string@"nu-complete kube ns"
] { ] {
@ -222,7 +236,7 @@ export def kd [
} }
export def ke [ export def ke [
r: string@"nu-complete kube def" r: string@"nu-complete kube kind"
i: string@"nu-complete kube res" i: string@"nu-complete kube res"
-n: string@"nu-complete kube ns" -n: string@"nu-complete kube ns"
] { ] {
@ -231,7 +245,7 @@ export def ke [
} }
export def kdel [ export def kdel [
r: string@"nu-complete kube def" r: string@"nu-complete kube kind"
i: string@"nu-complete kube res" i: string@"nu-complete kube res"
-n: string@"nu-complete kube ns" -n: string@"nu-complete kube ns"
--force(-f): bool --force(-f): bool

View file

@ -3,7 +3,7 @@ export def ensure-cache [cache path action] {
if ($ts | is-empty) { return false } if ($ts | is-empty) { return false }
let tc = (do -i { ls $cache | get 0.modified }) let tc = (do -i { ls $cache | get 0.modified })
if not (($cache | path exists) and ($ts < $tc)) { if not (($cache | path exists) and ($ts < $tc)) {
mkdir (dirname $cache) mkdir ($cache | path dirname)
do $action | save -f $cache do $action | save -f $cache
} }
open $cache open $cache

View file

@ -5,10 +5,14 @@ use power.nu
power inject 0 1 {source: git, color: '#504945'} power inject 0 1 {source: git, color: '#504945'}
use power_kube.nu use power_kube.nu
power inject 1 2 {source: kube, color: '#504945'} { power inject 1 2 {source: kube, color: '#504945'} {
context: purple context: cyan
} {
reverse: true
separator: '@'
} }
use power_utils.nu use power_utils.nu
power inject 0 1 {source: atuin, color: '#3B4E32'} power inject 0 1 {source: atuin, color: '#4C4B4A'}
power set time $nothing { short: false }
power init power init
``` ```
or or

View file

@ -12,7 +12,7 @@ def related [sub dir] {
} }
export def "pwd_abbr" [] { export def "pwd_abbr" [] {
{|| {|bg|
let pwd = ($env.PWD) let pwd = ($env.PWD)
let to_home = (related $pwd $nu.home-path) let to_home = (related $pwd $nu.home-path)
@ -44,25 +44,25 @@ export def "pwd_abbr" [] {
} else { } else {
$theme.default $theme.default
} }
$"($style)($dir_comp | str join (char separator))" [$bg $"($style)($dir_comp | str join (char separator))"]
} }
} }
### proxy ### proxy
export def proxy_stat [] { export def proxy_stat [] {
{|| {|bg|
let theme = $env.NU_POWER_THEME.proxy let theme = $env.NU_POWER_THEME.proxy
if not (($env.https_proxy? | is-empty) and ($env.http_proxy? | is-empty)) { if not (($env.https_proxy? | is-empty) and ($env.http_proxy? | is-empty)) {
$theme.on [$bg '']
} else { } else {
$nothing [$bg $nothing]
} }
} }
} }
### host ### host
def host_abbr [] { def host_abbr [] {
{|| {|bg|
let theme = $env.NU_POWER_THEME.host let theme = $env.NU_POWER_THEME.host
let n = (hostname | str trim) let n = (hostname | str trim)
let ucl = if (is-admin) { let ucl = if (is-admin) {
@ -70,15 +70,21 @@ def host_abbr [] {
} else { } else {
$theme.default $theme.default
} }
$"($ucl)($n)" [$bg $"($ucl)($n)"]
} }
} }
### time ### time
def time_segment [] { def time_segment [] {
{|| {|bg|
let config = $env.NU_POWER_CONFIG.time
let theme = $env.NU_POWER_THEME.time let theme = $env.NU_POWER_THEME.time
$"($theme.now)(date now | date format $theme.format)" let format = if $config.short {
$'($theme.fst)%y%m%d($theme.snd)%w($theme.fst)%H%M%S'
} else {
$'($theme.fst)%y-%m-%d[%w]%H:%M:%S'
}
[$bg $"(date now | date format $format)"]
} }
} }
@ -108,7 +114,7 @@ export def wraptime [message action] {
def get_component [schema] { def get_component [schema] {
let component = ($env.NU_PROMPT_COMPONENTS | get $schema.source) let component = ($env.NU_PROMPT_COMPONENTS | get $schema.source)
if $env.NU_POWER_BENCHMARK? == true { if $env.NU_POWER_BENCHMARK? == true {
{|| logtime $'component ($schema.source)' $component } {|bg| logtime $'component ($schema.source)' {|| do $component $bg } }
} else { } else {
$component $component
} }
@ -187,11 +193,11 @@ def left_prompt [segment] {
{|| {||
let segment = ($segment let segment = ($segment
| reduce -f [] {|x, acc| | reduce -f [] {|x, acc|
let y = (do $x.1) let y = (do $x.1 $x.0)
if $y == $nothing { if $y.1 == $nothing {
$acc $acc
} else { } else {
$acc | append [[$x.0 $y]] $acc | append [$y]
} }
}) })
let stop = ($segment | length) - 1 let stop = ($segment | length) - 1
@ -221,11 +227,11 @@ def right_prompt [segment] {
{|| {||
$segment $segment
| reduce -f [] {|x,acc| | reduce -f [] {|x,acc|
let y = (do $x.1) let y = (do $x.1 $x.0)
if $y == $nothing { if $y.1 == $nothing {
$acc $acc
} else { } else {
$acc | append [[$x.0 $y]] $acc | append [$y]
} }
} }
| enumerate | enumerate
@ -288,9 +294,9 @@ def decorator_gen [
def squash [thunk] { def squash [thunk] {
mut r = "" mut r = ""
for t in $thunk { for t in $thunk {
let v = (do $t.0) let v = (do $t.0 $nothing)
if ($v != $nothing) { if ($v.1 != $nothing) {
$r += (do $t.1 $v) $r += (do $t.1 $v.1)
} }
} }
$r $r
@ -338,11 +344,11 @@ def up_prompt [segment] {
| each {|y| | each {|y|
$y $y
| reduce -f [] {|x, acc| | reduce -f [] {|x, acc|
let y = (do $x) let y = (do $x $nothing)
if $y == $nothing { if $y.1 == $nothing {
$acc $acc
} else { } else {
$acc | append $y $acc | append $y.1
} }
} }
| str join $'(ansi light_yellow)|' | str join $'(ansi light_yellow)|'
@ -421,21 +427,39 @@ export def-env init [] {
hook hook
} }
export def-env register [name source theme] { export def-env set [name theme config?] {
let-env NU_PROMPT_COMPONENTS = ( let-env NU_POWER_THEME = (if ($theme | is-empty) {
$env.NU_PROMPT_COMPONENTS | upsert $name {|| $source } $env.NU_POWER_THEME
) } else {
let-env NU_POWER_THEME = (
$env.NU_POWER_THEME $env.NU_POWER_THEME
| upsert $name ($theme | upsert $name ($theme
| transpose k v | transpose k v
| reduce -f {} {|it, acc| | reduce -f {} {|it, acc|
$acc | insert $it.k (ansi -e {fg: $it.v}) $acc | insert $it.k (ansi -e {fg: $it.v})
}) })
})
let-env NU_POWER_CONFIG = (if ($config | is-empty) {
$env.NU_POWER_CONFIG
} else {
$env.NU_POWER_CONFIG
| upsert $name ($config
| transpose k v
| reduce -f {} {|it, acc|
$acc | insert $it.k $it.v
})
})
}
export def-env register [name source theme config?] {
set $name $theme $config
let-env NU_PROMPT_COMPONENTS = (
$env.NU_PROMPT_COMPONENTS | upsert $name {|| $source }
) )
} }
export def-env inject [pos idx define theme?] { export def-env inject [pos idx define theme? config?] {
let prev = ($env.NU_POWER_SCHEMA | get $pos) let prev = ($env.NU_POWER_SCHEMA | get $pos)
let next = if $idx == 0 { let next = if $idx == 0 {
$prev | prepend $define $prev | prepend $define
@ -452,8 +476,9 @@ export def-env inject [pos idx define theme?] {
| update $pos $next | update $pos $next
) )
if not ($theme | is-empty) {
let kind = $define.source let kind = $define.source
if not ($theme | is-empty) {
let prev_theme = ($env.NU_POWER_THEME | get $kind) let prev_theme = ($env.NU_POWER_THEME | get $kind)
let prev_cols = ($prev_theme | columns) let prev_cols = ($prev_theme | columns)
let next_theme = ($theme | transpose k v) let next_theme = ($theme | transpose k v)
@ -467,6 +492,19 @@ export def-env inject [pos idx define theme?] {
} }
} }
} }
if not ($config | is-empty) {
let prev_cols = ($env.NU_POWER_CONFIG | get $kind | columns)
for n in ($config | transpose k v) {
if $n.k in $prev_cols {
let-env NU_POWER_CONFIG = (
$env.NU_POWER_CONFIG | update $kind {|conf|
$conf | get $kind | update $n.k $n.v
}
)
}
}
}
} }
export def-env eject [] { export def-env eject [] {
@ -550,8 +588,17 @@ export-env {
default: (ansi blue) default: (ansi blue)
} }
time: { time: {
now: (ansi xterm_tan) fst: (ansi xterm_tan)
format: '%y%m%d[%w]%H%M%S' snd: (ansi xterm_aqua)
}
}
)
let-env NU_POWER_CONFIG = (default_env
NU_POWER_CONFIG
{
time: {
short: true
} }
} }
) )

View file

@ -101,10 +101,10 @@ export def git_status [] {
} }
export def git_stat [] { export def git_stat [] {
{|| {|bg|
let status = (git_status) let status = (git_status)
if $status.branch == 'no_branch' { return '' } if $status.branch == 'no_branch' { return [$bg ''] }
let theme = $env.NU_POWER_THEME.git let theme = $env.NU_POWER_THEME.git
let branch = if ($status.remote | is-empty) { let branch = if ($status.remote | is-empty) {
@ -124,7 +124,7 @@ export def git_stat [] {
} }
}) })
$'($branch)($summary)' [$bg $'($branch)($summary)']
} }
} }

View file

@ -1,20 +1,23 @@
### kubernetes ### kubernetes
def ensure-cache [cache path action] { def ensure-cache-by-lines [cache path action] {
let ts = (do -i { ls $path | sort-by modified | reverse | get 0.modified }) let ls = (do -i { open $path | lines | length })
if ($ts | is-empty) { return false } if ($ls | is-empty) { return false }
let tc = (do -i { ls $cache | get 0.modified }) let lc = (do -i { open $cache | get lines})
if not (($cache | path exists) and ($ts < $tc)) { if not (($cache | path exists) and (not ($lc | is-empty)) and ($ls == $lc)) {
mkdir (dirname $cache) mkdir ($cache | path dirname)
do $action | save -f $cache {
lines: $ls
payload: (do $action)
} | save -f $cache
} }
open $cache (open $cache).payload
} }
def "kube ctx" [] { def "kube ctx" [] {
let cache = $'($env.HOME)/.cache/nu-power/kube.json' let cache = $'($env.HOME)/.cache/nu-power/kube.json'
let file = if ($env.KUBECONFIG? | is-empty) { $"($env.HOME)/.kube/config" } else { $env.KUBECONFIG } let file = if ($env.KUBECONFIG? | is-empty) { $"($env.HOME)/.kube/config" } else { $env.KUBECONFIG }
if not ($file | path exists) { return $nothing } if not ($file | path exists) { return $nothing }
ensure-cache $cache $file { ensure-cache-by-lines $cache $file {
do -i { do -i {
kubectl config get-contexts kubectl config get-contexts
| from ssv -a | from ssv -a
@ -25,27 +28,30 @@ def "kube ctx" [] {
} }
def kube_stat [] { def kube_stat [] {
{|| {|bg|
let ctx = (kube ctx) let ctx = (kube ctx)
if ($ctx | is-empty) { if ($ctx | is-empty) {
"" [$bg ""]
} else { } else {
let theme = $env.NU_POWER_THEME.kube let theme = $env.NU_POWER_THEME.kube
let c = if $ctx.AUTHINFO == $ctx.CLUSTER { let config = $env.NU_POWER_CONFIG.kube
$ctx.CLUSTER let p = if $config.reverse {
$"($theme.namespace)($ctx.NAMESPACE)($theme.separator)($config.separator)($theme.context)($ctx.NAME)"
} else { } else {
$"($ctx.AUTHINFO)@($ctx.CLUSTER)" $"($theme.context)($ctx.NAME)($theme.separator)($config.separator)($theme.namespace)($ctx.NAMESPACE)"
} }
let p = $"($theme.context)($c)($theme.separator)/($theme.namespace)($ctx.NAMESPACE)" [$bg $"($p)"]
$"($p)" | str trim
} }
} }
} }
export-env { export-env {
power register kube (kube_stat) { power register kube (kube_stat) {
context: red context: cyan
separator: yellow separator: purple
namespace: cyan_bold namespace: yellow
} {
reverse: false
separator: ':'
} }
} }

View file

@ -1,10 +1,10 @@
export def atuin_stat [] { export def atuin_stat [] {
{|| {|bg|
let theme = $env.NU_POWER_THEME.atuin let theme = $env.NU_POWER_THEME.atuin
if not ($env.ATUIN_SESSION? | is-empty) { if not ($env.ATUIN_SESSION? | is-empty) {
$theme.on [$bg '']
} else { } else {
$nothing ['#504945' '']
} }
} }
} }