From 7fe503a9bd297cbfebdcbe05941729c2c98d8186 Mon Sep 17 00:00:00 2001 From: Brian Ketelsen Date: Sat, 30 Sep 2023 12:24:18 -0400 Subject: [PATCH] fix: change yq package (#304) * fix: update nixpkgs * fix: update nixpkgs * fix: update nixpkgs * fix: update nixpkgs * fix: update nixpkgs * fix: update nixpkgs * fix: update nixpkgs * chore: messing with versions and installing * fix: change yq package to yq-go * fix: response.body.close --- fin/theme.go | 19 ++ flake.lock | 8 +- flake.nix | 11 +- go.mod | 20 +- go.sum | 21 ++ internal/cache/cache.go | 14 +- internal/cmdutil/exec.go | 17 + internal/debug/debug.go | 2 + internal/flake/flake.go | 41 ++- internal/flake/git.go | 58 ++-- internal/fleek/config.go | 42 ++- internal/fleek/high.yml | 2 +- internal/fleek/packages.yml | 2 +- internal/fleek/system.go | 2 +- internal/fleekcli/add.go | 19 +- internal/fleekcli/apply.go | 2 +- internal/fleekcli/eject.go | 2 +- internal/fleekcli/generate.go | 8 +- internal/fleekcli/info.go | 3 +- internal/fleekcli/init.go | 4 +- internal/fleekcli/join.go | 20 +- internal/fleekcli/main.go | 11 +- internal/fleekcli/remove.go | 7 +- internal/fleekcli/root.go | 43 +-- internal/fleekcli/search.go | 10 +- internal/fleekcli/show.go | 5 +- internal/fleekcli/version.go | 77 ++++- internal/fleekcli/write.go | 3 +- internal/midcobra/verbose.go | 80 +++++ internal/verbose/verbose.go | 78 +++++ internal/vercheck/vercheck.go | 299 ++++++++++++++++++ internal/vercheck/vercheck_test.go | 114 +++++++ .../go-crypto/openpgp/internal/ecc/x448.go | 4 +- vendor/github.com/muesli/mango/README.md | 19 +- vendor/github.com/muesli/mango/mango.go | 21 +- vendor/github.com/pterm/pterm/README.md | 51 ++- .../pterm/interactive_multiselect_printer.go | 4 +- .../pterm/pterm/interactive_select_printer.go | 4 +- vendor/github.com/pterm/pterm/pterm.go | 14 - vendor/github.com/pterm/pterm/slog_handler.go | 82 +++++ .../sergi/go-diff/diffmatchpatch/diff.go | 8 +- .../skeema/knownhosts/knownhosts.go | 30 +- vendor/modules.txt | 20 +- 43 files changed, 1070 insertions(+), 231 deletions(-) create mode 100644 internal/midcobra/verbose.go create mode 100644 internal/verbose/verbose.go create mode 100644 internal/vercheck/vercheck.go create mode 100644 internal/vercheck/vercheck_test.go create mode 100644 vendor/github.com/pterm/pterm/slog_handler.go diff --git a/fin/theme.go b/fin/theme.go index 289e520c..9247d5a6 100644 --- a/fin/theme.go +++ b/fin/theme.go @@ -8,9 +8,28 @@ var HelpSectionPrinter = pterm.DefaultSection.WithLevel(2).Sprint var TitleSectionPrinter = pterm.DefaultSection.WithLevel(1).Sprint var DescriptionSectionPrinter = pterm.DefaultSection.WithLevel(2).Sprint var DetailSectionPrinter = pterm.DefaultSection.WithLevel(3).Sprint +var Logger = pterm.DefaultLogger.WithTime(false).WithLevel(pterm.LogLevelWarn) var ParagraphPrinter = pterm.DefaultParagraph.Sprint +// SetTrace sets the log level to Trace +// for trace/debugging level output +func SetTrace() { + Logger = pterm.DefaultLogger.WithTime(false).WithLevel(pterm.LogLevelTrace) +} + +// SetDebug sets the log level to Debug +// for trace/debugging level output +func SetDebug() { + Logger = pterm.DefaultLogger.WithTime(false).WithLevel(pterm.LogLevelDebug) +} + +// SetDebug sets the log level to Debug (unfortunately) +// for verbose level output +func SetVerbose() { + Logger = pterm.DefaultLogger.WithTime(false).WithLevel(pterm.LogLevelInfo) +} + var ( // info infoMessageStyle = &pterm.Style{pterm.FgLightBlue} diff --git a/flake.lock b/flake.lock index 1cbb9b28..e7440081 100644 --- a/flake.lock +++ b/flake.lock @@ -2,16 +2,16 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1681154110, - "narHash": "sha256-OQwWzlzAY1dCqgSsgZzsPIOGmX4pBGaoXOy0rSl4b5Y=", + "lastModified": 1695644571, + "narHash": "sha256-asS9dCCdlt1lPq0DLwkVBbVoEKuEuz+Zi3DG7pR/RxA=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "115a96e2ac1e92937cd47c30e073e16dcaaf6247", + "rev": "6500b4580c2a1f3d0f980d32d285739d8e156d92", "type": "github" }, "original": { "owner": "NixOS", - "ref": "release-22.11", + "ref": "master", "repo": "nixpkgs", "type": "github" } diff --git a/flake.nix b/flake.nix index 0f70f6f3..5f14524d 100644 --- a/flake.nix +++ b/flake.nix @@ -2,7 +2,7 @@ description = "Fleek - 'Home as Code' for Humans"; inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/release-22.11"; + nixpkgs.url = "github:NixOS/nixpkgs/master"; }; outputs = { self, nixpkgs }: let @@ -15,9 +15,16 @@ "aarch64-darwin" # 64-bit ARM macOS "x86_64-darwin" # 64-bit Intel macOS ]; + overlays = [ + (self: super: rec { + go = super.go_1_21; + buildGoModule = super.buildGo121Module; + + }) + ]; # Helper for providing per-supported-system outputs forEachSystem = f: nixpkgs.lib.genAttrs systems (system: f { - pkgs = import nixpkgs { inherit system; }; + pkgs = import nixpkgs { inherit overlays system; }; }); in { diff --git a/go.mod b/go.mod index a8b21264..2551fd36 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/ublue-os/fleek -go 1.20 +go 1.21 + +toolchain go1.21.1 require ( github.com/charmbracelet/lipgloss v0.8.0 @@ -21,7 +23,7 @@ require ( atomicgo.dev/schedule v0.1.0 // indirect dario.cat/mergo v1.0.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c // indirect github.com/acomagu/bufpipe v1.0.4 // indirect github.com/atotto/clipboard v0.1.4 // indirect github.com/charmbracelet/bubbles v0.16.1 // indirect @@ -32,23 +34,25 @@ require ( github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect - github.com/muesli/mango v0.1.0 // indirect + github.com/muesli/mango v0.2.0 // indirect github.com/muesli/mango-pflag v0.1.0 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect - github.com/sergi/go-diff v1.2.0 // indirect - github.com/skeema/knownhosts v1.2.0 // indirect + github.com/sergi/go-diff v1.3.1 // indirect + github.com/skeema/knownhosts v1.2.1 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect golang.org/x/crypto v0.13.0 // indirect - golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/net v0.15.0 // indirect golang.org/x/sync v0.3.0 // indirect golang.org/x/tools v0.13.0 // indirect + google.golang.org/protobuf v1.26.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect ) @@ -68,11 +72,11 @@ require ( github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.2 // indirect github.com/pkg/errors v0.9.1 - github.com/pterm/pterm v0.12.66 + github.com/pterm/pterm v0.12.69 github.com/rivo/uniseg v0.4.4 // indirect github.com/spf13/pflag v1.0.5 github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - golang.org/x/mod v0.12.0 // indirect + golang.org/x/mod v0.12.0 golang.org/x/sys v0.12.0 // indirect golang.org/x/term v0.12.0 golang.org/x/text v0.13.0 // indirect diff --git a/go.sum b/go.sum index fa6c8121..14092576 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,8 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c h1:kMFnB0vCcX7IL/m9Y5LO+KQYv+t1CQOiFe6+SV2J7bE= +github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= @@ -66,6 +68,10 @@ github.com/go-git/go-git/v5 v5.9.0 h1:cD9SFA7sHVRdJ7AYck1ZaAa/yeuBvGPxwXDL8cxrOb github.com/go-git/go-git/v5 v5.9.0/go.mod h1:RKIqga24sWdMGZF+1Ekv9kylsDz6LzdTSI2s/OsZWE0= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -113,6 +119,8 @@ github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELU github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/mango v0.1.0 h1:DZQK45d2gGbql1arsYA4vfg4d7I9Hfx5rX/GCmzsAvI= github.com/muesli/mango v0.1.0/go.mod h1:5XFpbC8jY5UUv89YQciiXNlbi+iJgt29VDC5xbzrLL4= +github.com/muesli/mango v0.2.0 h1:iNNc0c5VLQ6fsMgAqGQofByNUBH2Q2nEbD6TaI+5yyQ= +github.com/muesli/mango v0.2.0/go.mod h1:5XFpbC8jY5UUv89YQciiXNlbi+iJgt29VDC5xbzrLL4= github.com/muesli/mango-cobra v1.2.0 h1:DQvjzAM0PMZr85Iv9LIMaYISpTOliMEg+uMFtNbYvWg= github.com/muesli/mango-cobra v1.2.0/go.mod h1:vMJL54QytZAJhCT13LPVDfkvCUJ5/4jNUKF/8NC2UjA= github.com/muesli/mango-pflag v0.1.0 h1:UADqbYgpUyRoBja3g6LUL+3LErjpsOwaC9ywvBWe7Sg= @@ -142,6 +150,8 @@ github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5b github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= github.com/pterm/pterm v0.12.66 h1:bjsoMyUstaarzJ1NG7+1HGT7afR0JVMYsR3ooPeh4bo= github.com/pterm/pterm v0.12.66/go.mod h1:nFuT9ZVkkCi8o4L1dtWuYPwDQxggLh4C263qG5nTLpQ= +github.com/pterm/pterm v0.12.69 h1:fBCKnB8dSLAl8FlYRQAWYGp2WTI/Xm/tKJ21Hyo9USw= +github.com/pterm/pterm v0.12.69/go.mod h1:wl06ko9MHnqxz4oDV++IORDpjCzw6+mfrvf0MPj6fdk= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= @@ -154,9 +164,13 @@ github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM= github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo= +github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= +github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -182,6 +196,8 @@ golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= @@ -246,6 +262,10 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= @@ -253,6 +273,7 @@ gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/internal/cache/cache.go b/internal/cache/cache.go index 7271c689..597346c7 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -35,7 +35,7 @@ var cacheName = "packages.json" func New() (*PackageCache, error) { cacheDir := xdg.CacheSubpath("fleek") - fin.Debug.Printfln("package cache: %s", cacheDir) + fin.Logger.Debug("package cache", fin.Logger.Args("dir", cacheDir)) pc := &PackageCache{ location: cacheDir, @@ -47,14 +47,14 @@ func New() (*PackageCache, error) { } } if pc.valid() { - fin.Debug.Println("package list exists") + fin.Logger.Debug("package list exists") // read it bb, err := os.ReadFile(pc.cacheFile()) if err != nil { return pc, err } var plist PackageList - fin.Debug.Println("unmarshal package list") + fin.Logger.Debug("unmarshal package list") err = json.Unmarshal(bb, &plist) if err != nil { return pc, err @@ -79,20 +79,20 @@ func (pc *PackageCache) cacheFile() string { return filepath.Join(pc.location, cacheName) } func (pc *PackageCache) Update() error { - fin.Debug.Println("updating package list") + fin.Logger.Debug("updating package list") // get it bb, err := pc.packageIndex() if err != nil { return err } - fin.Debug.Printfln("writing cache file: %s", pc.cacheFile()) + fin.Logger.Debug("writing cache file", fin.Logger.Args("file", pc.cacheFile())) err = os.WriteFile(pc.cacheFile(), bb, 0755) if err != nil { return err } var plist PackageList - fin.Debug.Println("unmarshal package list") + fin.Logger.Debug("unmarshal package list") err = json.Unmarshal(bb, &plist) if err != nil { return err @@ -103,7 +103,7 @@ func (pc *PackageCache) Update() error { func (pc *PackageCache) packageIndex() ([]byte, error) { args := []string{"search", "nixpkgs", "--json"} - cmd, buf := cmdutil.CommandTTYWithBuffer("nix", args...) + cmd, buf := cmdutil.CommandTTYWithBufferNoOut("nix", args...) cmd.Env = os.Environ() // nix search nixpkgs --json err := cmd.Run() diff --git a/internal/cmdutil/exec.go b/internal/cmdutil/exec.go index 8f38997a..b629e482 100644 --- a/internal/cmdutil/exec.go +++ b/internal/cmdutil/exec.go @@ -34,3 +34,20 @@ func CommandTTYWithBuffer( outBuf.Write(errBuf.Bytes()) return cmd, outBuf } + +// CommandTTYWithBufferNoOut returns a command +// and a buffer that contains stdout and stderr combined. +func CommandTTYWithBufferNoOut( + name string, + arg ...string, +) (*exec.Cmd, *bytes.Buffer) { + cmd := exec.Command(name, arg...) + //cmd.Stdin = os.Stdin + + errBuf := bytes.NewBuffer(nil) + outBuf := bytes.NewBuffer(nil) + cmd.Stderr = errBuf + cmd.Stdout = outBuf + outBuf.Write(errBuf.Bytes()) + return cmd, outBuf +} diff --git a/internal/debug/debug.go b/internal/debug/debug.go index a4ccc732..97f43eac 100644 --- a/internal/debug/debug.go +++ b/internal/debug/debug.go @@ -9,6 +9,7 @@ import ( "github.com/pkg/errors" "github.com/pterm/pterm" + "github.com/ublue-os/fleek/fin" ) var enabled bool @@ -24,6 +25,7 @@ func Enable() { pterm.EnableDebugMessages() log.SetPrefix("[DEBUG] ") log.SetFlags(log.Lshortfile | log.Ltime) + fin.SetDebug() //_ = log.Output(2, "Debug mode enabled.") } diff --git a/internal/flake/flake.go b/internal/flake/flake.go index 08b687ed..300e1c6d 100644 --- a/internal/flake/flake.go +++ b/internal/flake/flake.go @@ -38,9 +38,8 @@ type SystemData struct { } func Load(cfg *fleek.Config, app *app.App) (*Flake, error) { - if cfg.Verbose { - fin.Verbose.Println(app.Trans("flake.initializingTemplates")) - } + fin.Logger.Info(app.Trans("flake.initializingTemplates")) + tt := make(map[string]*template.Template) err := fs.WalkDir(templates, ".", func(path string, d fs.DirEntry, err error) error { if err != nil { @@ -66,7 +65,7 @@ func Load(cfg *fleek.Config, app *app.App) (*Flake, error) { } func (f *Flake) Update() error { - fin.Info.Println(f.app.Trans("flake.update")) + fin.Logger.Info(f.app.Trans("flake.update")) updateCmdLine := []string{"flake", "update"} err := f.runNix(nixbin, updateCmdLine) @@ -82,7 +81,7 @@ func (f *Flake) Update() error { return nil } func (f *Flake) Create(force bool, symlink bool) error { - fin.Info.Println(f.app.Trans("init.writingConfigs")) + fin.Logger.Info(f.app.Trans("init.writingConfigs")) err := f.ensureFlakeDir() if err != nil { return err @@ -115,7 +114,7 @@ func (f *Flake) Create(force bool, symlink bool) error { return err } - fin.Info.Println(f.app.Trans("init.blingLevel", f.Config.Bling)) + fin.Logger.Info("", fin.Logger.Args(f.app.Trans("init.blingLevel", f.Config.Bling))) err = f.Config.WriteInitialConfig(force, symlink) if err != nil { return err @@ -204,15 +203,15 @@ func (f *Flake) IsJoin() (bool, error) { return false, nil } func (f *Flake) Join() error { - fin.Info.Println(f.app.Trans("init.writingConfigs")) + fin.Logger.Info(f.app.Trans("init.writingConfigs")) // Symlink the yaml file to home cfile, err := f.Config.Location() if err != nil { - fin.Debug.Printfln("location err: %s ", err) + fin.Logger.Debug("config location location", fin.Logger.Args("error", err)) return err } - fin.Debug.Printfln("init cfile: %s ", cfile) + fin.Logger.Debug("init config", fin.Logger.Args("file", cfile)) home, err := os.UserHomeDir() if err != nil { @@ -226,19 +225,19 @@ func (f *Flake) Join() error { if err != nil { return err } - fin.Debug.Println("new system") + fin.Logger.Debug("new system") sys, err := fleek.NewSystem() if err != nil { return err } - fin.Debug.Println("write system") + fin.Logger.Debug("write system") // var found bool for _, s := range f.Config.Systems { if s.Hostname == sys.Hostname && s.Username == sys.Username && s.Arch == sys.Arch { - fin.Debug.Println("system already exists") + fin.Logger.Debug("system already exists") found = true } } @@ -273,11 +272,11 @@ func (f *Flake) Join() error { } } - fin.Debug.Println("write config") + fin.Logger.Debug("write config") err = f.Config.Save() if err != nil { - fin.Debug.Println("config save failed") + fin.Logger.Debug("config save failed", fin.Logger.Args("error", err)) return err } git, err := f.IsGitRepo() @@ -409,7 +408,7 @@ func (f *Flake) Write(message string, writeHost, writeUser bool) error { func (f *Flake) ensureFlakeDir() error { if f.Config.Verbose { - fin.Verbose.Println(f.app.Trans("flake.ensureDir")) + fin.Logger.Info(f.app.Trans("flake.ensureDir")) } err := f.Config.MakeFlakeDir() if err != nil { @@ -433,7 +432,7 @@ func (f *Flake) writeFile(template string, path string, d Data, force bool) erro fpath := filepath.Join(f.Config.UserFlakeDir(), path) err := os.MkdirAll(filepath.Dir(fpath), 0755) if err != nil { - fin.Debug.Println("mkdir error", err) + fin.Logger.Debug("mkdir", fin.Logger.Args("error", err)) } _, err = os.Stat(fpath) @@ -443,17 +442,17 @@ func (f *Flake) writeFile(template string, path string, d Data, force bool) erro if ok { file, err := os.Create(fpath) if err != nil { - fin.Debug.Println("create error", err) + fin.Logger.Debug("create file", fin.Logger.Args("error", err)) return err } defer file.Close() if err = f.Templates[template].Execute(file, d); err != nil { - fin.Debug.Println("template error", err) + fin.Logger.Debug("template", fin.Logger.Args("error", err)) return err } } else { - fin.Debug.Println("template not found", template) + fin.Logger.Info("template not found", fin.Logger.Args("name", template)) return errors.New("template not found") } } else { @@ -554,7 +553,7 @@ func (f *Flake) WriteTemplates() error { return nil } func (f *Flake) Apply() error { - fin.Info.Println(f.app.Trans("flake.apply")) + fin.Logger.Info(f.app.Trans("flake.apply")) user, err := fleek.Username() @@ -577,7 +576,7 @@ func (f *Flake) runNix(cmd string, cmdLine []string) error { command := cmdutil.CommandTTY(cmd, cmdLine...) command.Dir = f.Config.UserFlakeDir() - fin.Debug.Println("running nix command in ", command.Dir) + fin.Logger.Debug("running nix command", fin.Logger.Args("directory", command.Dir)) command.Env = os.Environ() if f.Config.Unfree { command.Env = append(command.Env, "NIXPKGS_ALLOW_UNFREE=1") diff --git a/internal/flake/git.go b/internal/flake/git.go index c146e98d..445aedab 100644 --- a/internal/flake/git.go +++ b/internal/flake/git.go @@ -9,7 +9,6 @@ import ( "github.com/go-git/go-git/v5" "github.com/ublue-os/fleek/fin" "github.com/ublue-os/fleek/internal/cmdutil" - "github.com/ublue-os/fleek/internal/debug" fgit "github.com/ublue-os/fleek/internal/git" ) @@ -66,47 +65,43 @@ func (f *Flake) IsGitRepo() (bool, error) { func (f *Flake) mayCommit(message string) error { git, err := f.IsGitRepo() if err != nil { - fin.Debug.Printfln("git repo error: %s", err) + fin.Logger.Error("git repo", fin.Logger.Args("error", err)) return err } if git { - fin.Debug.Println("is git repo") + fin.Logger.Debug("is git repo") // add - fin.Debug.Println("git will add") - if f.Config.Verbose { - fin.Verbose.Println(f.app.Trans("git.add")) - } + fin.Logger.Debug("git will add") + fin.Logger.Info(f.app.Trans("git.add")) + err = f.add() if err != nil { - fin.Debug.Printfln("git add error: %s", err) + fin.Logger.Error("git add", fin.Logger.Args("error", err)) return err } if f.Config.Git.AutoCommit { - fin.Debug.Println("git will commit") - if f.Config.Verbose { - fin.Verbose.Println(f.app.Trans("git.commit")) - } + fin.Logger.Debug("git will commit") + fin.Logger.Info(f.app.Trans("git.commit")) + err = f.commit(message) if err != nil { - fin.Debug.Printfln("git commit error: %s", err) + fin.Logger.Error("git commit", fin.Logger.Args("error", err)) return err } } if f.Config.Git.AutoPush { - fin.Debug.Println("git will push") - if f.Config.Verbose { - fin.Verbose.Println(f.app.Trans("git.push")) - } + fin.Logger.Debug("git will push") + fin.Logger.Info(f.app.Trans("git.push")) err = f.push() if err != nil { - fin.Debug.Printfln("git push error: %s", err) + fin.Logger.Error("git push", fin.Logger.Args("error", err)) return err } } } else { - fin.Debug.Println("skipping git") + fin.Logger.Info("skipping git") return nil } @@ -115,29 +110,26 @@ func (f *Flake) mayCommit(message string) error { func (f *Flake) MayPull() error { git, err := f.IsGitRepo() if err != nil { - fin.Debug.Printfln("git repo error: %s", err) + fin.Logger.Error("check repo", fin.Logger.Args("error", err)) return err } if git { - if f.Config.Verbose { - fin.Verbose.Println(f.app.Trans("git.commit")) - } - fin.Debug.Println("is git repo") + fin.Logger.Info(f.app.Trans("git.commit")) + fin.Logger.Debug("is git repo") if f.Config.Git.AutoPull { - fin.Debug.Println("git will pull") - if f.Config.Verbose { - fin.Verbose.Println(f.app.Trans("git.pull")) - } + fin.Logger.Debug("git will pull") + fin.Logger.Info(f.app.Trans("git.pull")) + err = f.pull() if err != nil { - fin.Debug.Printfln("git pull error: %s", err) + fin.Logger.Error("git pull", fin.Logger.Args("error", err)) return err } } } else { - fin.Debug.Println("skipping git") + fin.Logger.Info("skipping git") return nil } @@ -159,7 +151,7 @@ func (f *Flake) commit(message string) error { return errors.New("error parsing git status") } if status.Empty() { - fin.Debug.Println("git status is empty, skipping commit") + fin.Logger.Debug("git status is empty, skipping commit") return nil } if message == "" { @@ -236,13 +228,13 @@ func (f *Flake) remote() (string, error) { var err error repo, err := f.gitOpen() if err != nil { - debug.Log("fr open: %s", err) - + fin.Logger.Error("flake git repo open", fin.Logger.Args("error", err)) return "", fmt.Errorf("opening repository: %w", err) } list, err := repo.Remotes() if err != nil { + fin.Logger.Error("flake git repo remotes", fin.Logger.Args("error", err)) return "", fmt.Errorf("getting remotes : %w", err) } var urls string diff --git a/internal/fleek/config.go b/internal/fleek/config.go index 6a24b93b..41329782 100644 --- a/internal/fleek/config.go +++ b/internal/fleek/config.go @@ -26,7 +26,7 @@ var ( blingLevels = []string{"none", "low", "default", "high"} LowPackages = []string{"htop", "git", "github-cli", "glab"} DefaultPackages = []string{"fzf", "ripgrep", "vscode", "just"} - HighPackages = []string{"lazygit", "jq", "yq", "neovim", "neofetch", "btop", "cheat"} + HighPackages = []string{"lazygit", "jq", "yq-go", "neovim", "neofetch", "btop", "cheat"} LowPrograms = []string{"starship"} DefaultPrograms = []string{"direnv"} HighPrograms = []string{"eza", "bat", "atuin", "zoxide"} @@ -142,7 +142,7 @@ func CollectGarbage() error { } func NewUser() (*User, error) { - fin.Info.Println("Enter User Details for Git Configuration:") + fin.Logger.Info("Enter User Details for Git Configuration:") user := &User{} var use bool @@ -156,7 +156,7 @@ func NewUser() (*User, error) { name = strings.TrimSpace(name) if name != "" { - fin.Info.Println("Detected your name: " + name) + fin.Logger.Info("Detected your name: " + name) use, err = ux.Confirm("Use detected name: " + name) if err != nil { return user, err @@ -504,12 +504,13 @@ func (c *Config) WriteInitialConfig(force bool, symlink bool) error { systemAliases["fleeks"] = "cd ~/" + c.FlakeDir sys, err := NewSystem() if err != nil { - fin.Debug.Printfln("new system err: %s ", err) + fin.Logger.Debug("new system", fin.Logger.Args("error", err)) return err } user, err := NewUser() if err != nil { - fin.Debug.Printfln("new user err: %s ", err) + fin.Logger.Debug("new user", fin.Logger.Args("error", err)) + return err } sys.User = user @@ -538,15 +539,15 @@ func (c *Config) WriteInitialConfig(force bool, symlink bool) error { cfile, err := c.Location() if err != nil { - fin.Debug.Printfln("location err: %s ", err) + fin.Logger.Debug("location err", fin.Logger.Args("error", err)) + return err } - fin.Debug.Printfln("cfile: %s", cfile) + fin.Logger.Debug("config", fin.Logger.Args("file", cfile)) _, err = os.Stat(cfile) - - fin.Debug.Printfln("stat err: %v ", err) - fin.Debug.Printfln("force: %v ", force) + fin.Logger.Debug("stat", fin.Logger.Args("error", err)) + fin.Logger.Debug("force", fin.Logger.Args("value", force)) if force || errors.Is(err, fs.ErrNotExist) { @@ -639,7 +640,7 @@ func (c *Config) NeedsMigration() bool { systemFile := filepath.Join(systemDir, s.Hostname+".nix") // beast/beast.nix if Exists(systemFile) { - fin.Info.Println("Found unmigrated system file:", systemFile) + fin.Logger.Warn("Found unmigrated system file:", fin.Logger.Args("file", systemFile)) return true } @@ -647,21 +648,17 @@ func (c *Config) NeedsMigration() bool { hostFile := filepath.Join(systemDir, "host.nix") // beast/host.nix if Exists(hostFile) { - - fin.Info.Println("Found unmigrated system file:", hostFile) - + fin.Logger.Warn("Found unmigrated system file:", fin.Logger.Args("file", hostFile)) return true } hostFile = filepath.Join(systemDir, "user.nix") // beast/user.nix if Exists(hostFile) { - - fin.Info.Println("Found unmigrated system file:", hostFile) - + fin.Logger.Warn("Found unmigrated system file:", fin.Logger.Args("file", hostFile)) return true } if s.User == nil { - fin.Info.Println("Found unmigrated system users") + fin.Logger.Warn("Found unmigrated system users") return true } @@ -675,9 +672,8 @@ func (c *Config) Migrate() error { systemFile := filepath.Join(systemDir, s.Hostname+".nix") // beast/beast.nix if Exists(systemFile) { - fin.Info.Println("Found unmigrated system file:", systemFile) + fin.Logger.Warn("Migrating system file", fin.Logger.Args("file", systemFile)) userFile := filepath.Join(systemDir, s.Username+".nix") - err := Move(systemFile, userFile) if err != nil { return err @@ -686,7 +682,7 @@ func (c *Config) Migrate() error { hostFile := filepath.Join(systemDir, "user.nix") // beast/user.nix -> beast/custom.nix if Exists(hostFile) { - fin.Info.Println("Found unmigrated system file:", hostFile) + fin.Logger.Warn("Migrating system file", fin.Logger.Args("file", hostFile)) newHostFile := filepath.Join(systemDir, "custom.nix") err := Move(hostFile, newHostFile) @@ -698,7 +694,7 @@ func (c *Config) Migrate() error { hostFile = filepath.Join(systemDir, "host.nix") // beast/host.nix -> beast/custom.nix if Exists(hostFile) { - fin.Info.Println("Found unmigrated system file:", hostFile) + fin.Logger.Warn("Migrating system file", fin.Logger.Args("file", hostFile)) newHostFile := filepath.Join(systemDir, "custom.nix") err := Move(hostFile, newHostFile) @@ -707,7 +703,7 @@ func (c *Config) Migrate() error { } } if s.User == nil { - fin.Info.Println("Migrating Users to System:", s.Hostname) + fin.Logger.Warn("Migrating users", fin.Logger.Args("hostname", s.Hostname)) sysuser := c.UserForSystem(s.Hostname) s.User = sysuser diff --git a/internal/fleek/high.yml b/internal/fleek/high.yml index 206cb545..a4726e51 100644 --- a/internal/fleek/high.yml +++ b/internal/fleek/high.yml @@ -10,7 +10,7 @@ packages: - vscode - lazygit - jq - - yq + - yq-go - neovim - neofetch - btop diff --git a/internal/fleek/packages.yml b/internal/fleek/packages.yml index 814f2c4b..1771ccfa 100644 --- a/internal/fleek/packages.yml +++ b/internal/fleek/packages.yml @@ -30,7 +30,7 @@ description: | simple terminal UI for git commands https://github.com/jesseduffield/lazygit - - name: yq + - name: yq-go description: | a lightweight and portable command-line YAML processor. https://mikefarah.gitbook.io/yq/ diff --git a/internal/fleek/system.go b/internal/fleek/system.go index 11465f68..39dab133 100644 --- a/internal/fleek/system.go +++ b/internal/fleek/system.go @@ -119,7 +119,7 @@ func UserShell() (string, error) { if strings.Contains(shell, "bash") { shell = "bash" } - fin.Debug.Printfln("detected shell: %s", shell) + fin.Logger.Debug("shell", fin.Logger.Args("detected", shell)) return shell, nil } diff --git a/internal/fleekcli/add.go b/internal/fleekcli/add.go index 16ccff7a..dbc4aeb8 100644 --- a/internal/fleekcli/add.go +++ b/internal/fleekcli/add.go @@ -44,7 +44,7 @@ func add(cmd *cobra.Command, args []string) error { } pc, err := cache.New() if err != nil { - fin.Error.Println(app.Trans("search.cacheError")) + fin.Logger.Error(app.Trans("search.cacheError")) return err } var hits []cache.SearchResult @@ -76,11 +76,11 @@ func add(cmd *cobra.Command, args []string) error { } } if len(exactHits) == 1 { - fin.Info.Println("Found exact match for " + p) + fin.Logger.Info("Found exact match for " + p) } if len(exactHits) < 1 { if len(hits) > 0 { - fin.Info.Println("Found " + fmt.Sprint(len(hits)) + " matche(s) for " + p) + fin.Logger.Info("Found " + fmt.Sprint(len(hits)) + " matche(s) for " + p) for _, hit := range hits { fin.Info.Println("\tName: ", hit.Name) fin.Info.Println("\tDescription: ", hit.Package.Description) @@ -90,17 +90,16 @@ func add(cmd *cobra.Command, args []string) error { return nil } - fin.Info.Println("Found no matches for " + p + "!") + fin.Logger.Info("Found no matches for " + p + "!") return nil } - fin.Info.Println("exact hits", len(exactHits)) - fin.Info.Println("possible matches", len(hits)) + fin.Logger.Info("results", fin.Logger.Args("exact hits", len(exactHits), "possible matches", len(hits))) - fin.Info.Println(app.Trans("add.adding") + p) + fin.Logger.Info(app.Trans("add.adding") + p) err = fl.Config.AddPackage(p) if err != nil { - fin.Debug.Printfln("add package error: %s", err) + fin.Logger.Debug("add package", fin.Logger.Args("error", err)) return err } sb.WriteString(p + " ") @@ -108,11 +107,11 @@ func add(cmd *cobra.Command, args []string) error { } err = fl.Write(sb.String(), false, false) if err != nil { - fin.Debug.Printfln("flake write error: %s", err) + fin.Logger.Debug("write flake", fin.Logger.Args("error", err)) return err } - fin.Info.Println(app.Trans("add.applying")) + fin.Logger.Info(app.Trans("add.applying")) err = fl.Apply() if err != nil { diff --git a/internal/fleekcli/apply.go b/internal/fleekcli/apply.go index 9a7918e8..1d477241 100644 --- a/internal/fleekcli/apply.go +++ b/internal/fleekcli/apply.go @@ -64,7 +64,7 @@ func apply(cmd *cobra.Command) error { return err } } else { - fin.Info.Println(app.Trans("apply.dryApplyingConfig")) + fin.Logger.Info(app.Trans("apply.dryApplyingConfig")) if err := fl.Check(); err != nil { if err != nil { return err diff --git a/internal/fleekcli/eject.go b/internal/fleekcli/eject.go index 0d2f84a9..cac365da 100644 --- a/internal/fleekcli/eject.go +++ b/internal/fleekcli/eject.go @@ -60,7 +60,7 @@ func eject(cmd *cobra.Command) error { return err } // TODO app trans - fin.Info.Println(app.Trans("generate.runFlake")) + fin.Logger.Info(app.Trans("generate.runFlake")) for _, system := range fl.Config.Systems { // nix run --impure home-manager/master -- -b bak switch --flake .#bjk@ghanima diff --git a/internal/fleekcli/generate.go b/internal/fleekcli/generate.go index 1e100733..0f62465b 100644 --- a/internal/fleekcli/generate.go +++ b/internal/fleekcli/generate.go @@ -64,7 +64,7 @@ func generate(cmd *cobra.Command) error { } fl.Config.Bling = cmd.Flag(app.Trans("generate.levelFlag")).Value.String() - fin.Info.Println("Bling level:", fl.Config.Bling) + fin.Logger.Info("Bling", fin.Logger.Args("level", fl.Config.Bling)) err = fl.Create(force, false) if err != nil { return usererr.WithUserMessage(err, app.Trans("flake.creating")) @@ -85,7 +85,7 @@ func generate(cmd *cobra.Command) error { if err != nil { return err } - fin.Info.Println("writing,", fl.Config.Bling) + fin.Logger.Info("writing config") err = fl.Write("fleek: generate", true, true) if err != nil { return err @@ -96,12 +96,12 @@ func generate(cmd *cobra.Command) error { if err != nil { return usererr.WithUserMessage(err, app.Trans("generate.applyFlag")) } - fin.Info.Println(app.Trans("global.completed")) + fin.Logger.Info(app.Trans("global.completed")) return nil } // TODO app trans - fin.Info.Println(app.Trans("generate.runFlake")) + fin.Logger.Info(app.Trans("generate.runFlake")) for _, system := range fl.Config.Systems { // nix run --impure home-manager/master -- -b bak switch --flake .#bjk@ghanima diff --git a/internal/fleekcli/info.go b/internal/fleekcli/info.go index a6bef0c7..50982e61 100644 --- a/internal/fleekcli/info.go +++ b/internal/fleekcli/info.go @@ -30,6 +30,7 @@ func InfoCommand() *cobra.Command { func infoFleek(cmd *cobra.Command, args []string) error { fin.Description.Println(cmd.Short) + fin.Logger.Debug("args", fin.Logger.Args("args", args)) err := mustConfig() if err != nil { return err @@ -54,7 +55,7 @@ func infoFleek(cmd *cobra.Command, args []string) error { b, err = fleek.NoBling() cobra.CheckErr(err) } - fin.Info.Println("["+b.Name+" Bling]", b.Description) + fin.Logger.Info("Bling", fin.Logger.Args("Level", b.Name, "Description", b.Description)) needle := args[0] var found bool diff --git a/internal/fleekcli/init.go b/internal/fleekcli/init.go index 72013331..1a119eef 100644 --- a/internal/fleekcli/init.go +++ b/internal/fleekcli/init.go @@ -70,11 +70,11 @@ func initialize(cmd *cobra.Command, _ []string) error { if err != nil { return usererr.WithUserMessage(err, app.Trans("init.applyFlag")) } - fin.Info.Println(app.Trans("global.completed")) + fin.Logger.Info(app.Trans("global.completed")) return nil } - fin.Info.Println(app.Trans("init.complete")) + fin.Logger.Info(app.Trans("init.complete")) return nil } diff --git a/internal/fleekcli/join.go b/internal/fleekcli/join.go index 36a47250..430a4682 100644 --- a/internal/fleekcli/join.go +++ b/internal/fleekcli/join.go @@ -70,25 +70,25 @@ func join(cmd *cobra.Command, args []string) error { } migrate := config.NeedsMigration() if migrate { - fin.Info.Println("Migration required") + fin.Logger.Info("Migration required") err := config.Migrate() if err != nil { - fin.Error.Println("error migrating host files:", err) + fin.Logger.Error("migrating host files", fin.Logger.Args("error", err)) os.Exit(1) } fl, err := flake.Load(config, app) if err != nil { - fin.Error.Println("error loading flake:", err) + fin.Logger.Error("loading flake", fin.Logger.Args("error", err)) os.Exit(1) } // Symlink the yaml file to home cfile, err := fl.Config.Location() if err != nil { - fin.Debug.Printfln("location err: %s ", err) + fin.Logger.Error("config location", fin.Logger.Args("error", err)) return err } - fin.Debug.Printfln("init cfile: %s ", cfile) + fin.Logger.Debug("config", fin.Logger.Args("file", cfile)) home, err := os.UserHomeDir() if err != nil { @@ -97,17 +97,17 @@ func join(cmd *cobra.Command, args []string) error { csym := filepath.Join(home, ".fleek.yml") err = os.Symlink(cfile, csym) if err != nil { - fin.Debug.Println("symlink failed") + fin.Logger.Debug("symlink failed") return err } err = fl.Write("update host and user files", true, false) if err != nil { - fin.Error.Println("error writing flake:", err) + fin.Logger.Error("writing flake", fin.Logger.Args("error", err)) os.Exit(1) } } - fin.Info.Println(app.Trans("init.joining")) + fin.Logger.Info(app.Trans("init.joining")) fl, err := flake.Load(config, app) if err != nil { return err @@ -127,7 +127,7 @@ func join(cmd *cobra.Command, args []string) error { } err = fl.Write("join new system", true, true) if err != nil { - fin.Debug.Printfln("flake write error: %s", err) + fin.Logger.Error("flake write", fin.Logger.Args("error", err)) return err } @@ -135,7 +135,7 @@ func join(cmd *cobra.Command, args []string) error { if err != nil { return err } - fin.Info.Println(app.Trans("join.complete")) + fin.Logger.Info(app.Trans("join.complete")) return nil } diff --git a/internal/fleekcli/main.go b/internal/fleekcli/main.go index 7cfa99b7..4d2c680d 100644 --- a/internal/fleekcli/main.go +++ b/internal/fleekcli/main.go @@ -13,10 +13,11 @@ import ( ) var ( - debugMiddleware *midcobra.DebugMiddleware = &midcobra.DebugMiddleware{} - traceMiddleware *midcobra.TraceMiddleware = &midcobra.TraceMiddleware{} - app *fleek.App - root *cobra.Command + debugMiddleware *midcobra.DebugMiddleware = &midcobra.DebugMiddleware{} + traceMiddleware *midcobra.TraceMiddleware = &midcobra.TraceMiddleware{} + verboseMiddleware *midcobra.VerboseMiddleware = &midcobra.VerboseMiddleware{} + app *fleek.App + root *cobra.Command ) func Main() { @@ -30,6 +31,8 @@ func Execute(ctx context.Context, args []string) int { exe := midcobra.New(root) exe.AddMiddleware(traceMiddleware) exe.AddMiddleware(debugMiddleware) + exe.AddMiddleware(verboseMiddleware) + return exe.Execute(ctx, args) } func init() { diff --git a/internal/fleekcli/remove.go b/internal/fleekcli/remove.go index 3e15b23c..becdd0c2 100644 --- a/internal/fleekcli/remove.go +++ b/internal/fleekcli/remove.go @@ -57,7 +57,7 @@ func remove(cmd *cobra.Command, args []string) error { } err = fl.Config.RemovePackage(p) if err != nil { - fin.Debug.Printfln("remove package error: %s", err) + fin.Logger.Error("new package", fin.Logger.Args("error", err)) return err } sb.WriteString(p + " ") @@ -65,12 +65,13 @@ func remove(cmd *cobra.Command, args []string) error { } err = fl.Write(sb.String(), false, false) if err != nil { - fin.Debug.Printfln("flake write error: %s", err) + fin.Logger.Error("flake write", fin.Logger.Args("error", err)) + return err } if verbose { - fin.Info.Println(app.Trans("remove.applying")) + fin.Logger.Info(app.Trans("remove.applying")) } err = fl.Apply() if err != nil { diff --git a/internal/fleekcli/root.go b/internal/fleekcli/root.go index 6063a6ac..70af013d 100644 --- a/internal/fleekcli/root.go +++ b/internal/fleekcli/root.go @@ -10,6 +10,7 @@ import ( "github.com/ublue-os/fleek/internal/flake" "github.com/ublue-os/fleek/internal/fleek" "github.com/ublue-os/fleek/internal/fleekcli/usererr" + "github.com/ublue-os/fleek/internal/vercheck" "github.com/ublue-os/fleek/internal/xdg" ) @@ -33,25 +34,26 @@ func RootCmd() *cobra.Command { if flags.quiet { cmd.SetErr(io.Discard) } - fin.Debug.Println("debug enabled") + vercheck.CheckVersion(cmd.ErrOrStderr(), cmd.CommandPath()) + fin.Logger.Debug("debug enabled") info, ok := debug.ReadBuildInfo() if ok { - fin.Debug.Println(info.String()) + fin.Logger.Trace(info.String()) } err := flake.ForceProfile() if err != nil { - fin.Error.Println("Nix can't list profiles.") + fin.Logger.Error("Nix can't list profiles.") os.Exit(1) } // try to get the config, which may not exist yet c, err := fleek.ReadConfig(flags.location) if err == nil { - if flags.verbose { - fin.Info.Println(app.Trans("fleek.configLoaded")) - } + + fin.Logger.Debug(app.Trans("fleek.configLoaded"), fin.Logger.Args("location", flags.location)) + cfg = c cfgFound = true } else { @@ -61,32 +63,35 @@ func RootCmd() *cobra.Command { if cfg != nil { cfg.Quiet = flags.quiet cfg.Verbose = flags.verbose - fin.Debug.Printfln("git autopush: %v", cfg.Git.AutoPush) - fin.Debug.Printfln("git autocommit: %v", cfg.Git.AutoCommit) - fin.Debug.Printfln("git autopull: %v", cfg.Git.AutoPull) + fin.Logger.Debug("git", + fin.Logger.Args( + "autopush", cfg.Git.AutoPush, + "autocommit", cfg.Git.AutoCommit, + "autopull", cfg.Git.AutoPull, + )) if cfg.Ejected { if cmd.Name() != app.Trans("apply.use") { - fin.Error.Println(app.Trans("eject.ejected")) + fin.Logger.Error(app.Trans("eject.ejected")) os.Exit(1) } } migrate := cfg.NeedsMigration() if migrate { - fin.Info.Println("Migration required") + fin.Logger.Warn("Migration required") err := cfg.Migrate() if err != nil { - fin.Error.Println("error migrating host files:", err) + fin.Logger.Error("migrating host files", fin.Logger.Args("error", err)) os.Exit(1) } fl, err := flake.Load(cfg, app) if err != nil { - fin.Error.Println("error loading flake:", err) + fin.Logger.Error("loading flake", fin.Logger.Args("error", err)) os.Exit(1) } err = fl.Write("update host and user files", true, false) if err != nil { - fin.Error.Println("error writing flake:", err) + fin.Logger.Error(" writing flake:", fin.Logger.Args("error", err)) os.Exit(1) } } @@ -98,13 +103,9 @@ func RootCmd() *cobra.Command { if flags.quiet { cmd.SetErr(io.Discard) } - fin.Debug.Printfln("git autopush: %v", cfg.Git.AutoPush) - fin.Debug.Printfln("git autocommit: %v", cfg.Git.AutoCommit) - fin.Debug.Printfln("git autopull: %v", cfg.Git.AutoPull) - fin.Debug.Printfln("auto gc: %v", cfg.AutoGC) if cfg.AutoGC { - fin.Info.Println("Running nix-collect-garbage") + fin.Logger.Info("Running nix-collect-garbage") // we don't care too much if there's an error here _ = fleek.CollectGarbage() } @@ -185,11 +186,11 @@ func RootCmd() *cobra.Command { command.PersistentFlags().BoolVarP( &flags.quiet, app.Trans("fleek.quietFlag"), "q", false, app.Trans("fleek.quietFlagDescription")) - command.PersistentFlags().BoolVarP( - &flags.verbose, app.Trans("fleek.verboseFlag"), "v", false, app.Trans("fleek.verboseFlagDescription")) command.PersistentFlags().StringVarP( &flags.location, app.Trans("init.locationFlag"), "l", xdg.DataSubpathRel("fleek"), app.Trans("init.locationFlagDescription")) + verboseMiddleware.AttachToFlag(command.PersistentFlags(), app.Trans("fleek.verboseFlag")) + debugMiddleware.AttachToFlag(command.PersistentFlags(), app.Trans("fleek.debugFlag")) traceMiddleware.AttachToFlag(command.PersistentFlags(), app.Trans("fleek.traceFlag")) diff --git a/internal/fleekcli/search.go b/internal/fleekcli/search.go index dd7c0b77..1bf58a2f 100644 --- a/internal/fleekcli/search.go +++ b/internal/fleekcli/search.go @@ -50,7 +50,7 @@ func search(cmd *cobra.Command, args []string) error { fuzzy = true } if fuzzy { - fin.Info.Println(app.Trans("search.fuzzyEnabled")) + fin.Logger.Info(app.Trans("search.fuzzyEnabled")) } needle := args[0] @@ -61,7 +61,7 @@ func search(cmd *cobra.Command, args []string) error { pc, err := cache.New() if err != nil { _ = spinner.Stop() - fin.Error.Println(app.Trans("search.cacheError")) + fin.Logger.Error(app.Trans("search.cacheError")) return err } spinner.Success() @@ -73,7 +73,7 @@ func search(cmd *cobra.Command, args []string) error { err = pc.Update() if err != nil { _ = spinner.Stop() - fin.Error.Println(app.Trans("search.cacheError")) + fin.Logger.Error(app.Trans("search.cacheError")) return err } spinner.Success() @@ -111,7 +111,7 @@ func search(cmd *cobra.Command, args []string) error { if len(hits) == 0 { fin.Warning.Println(app.Trans("search.noResults")) } else { - fin.Info.Println(app.Trans("search.fuzzyMatches")) + fin.Logger.Info(app.Trans("search.fuzzyMatches")) _ = fin.Table().WithHasHeader(true).WithData(toTableDataWithHeader(hits)).Render() } } @@ -121,7 +121,7 @@ func search(cmd *cobra.Command, args []string) error { fin.Warning.Println(app.Trans("search.noResultsExact")) } } else { - fin.Info.Println(app.Trans("search.exactMatches")) + fin.Logger.Info(app.Trans("search.exactMatches")) _ = fin.Table().WithHasHeader(true).WithData(toTableDataWithHeader(exactHits)).Render() } diff --git a/internal/fleekcli/show.go b/internal/fleekcli/show.go index 01b00998..86f0afdf 100644 --- a/internal/fleekcli/show.go +++ b/internal/fleekcli/show.go @@ -77,12 +77,13 @@ func showFleek(cmd *cobra.Command) error { b, err = fleek.NoBling() cobra.CheckErr(err) default: - fin.Error.Println(app.Trans("show.invalidLevel", level)) + fin.Logger.Error(app.Trans("show.invalidLevel", fin.Logger.Args("given", level))) return nil } if !showJSON { - fin.Info.Println("["+b.Name+" Bling]", b.Description) + fin.Description.Println("["+b.Name+" Bling]", b.Description) + } if showJSON { diff --git a/internal/fleekcli/version.go b/internal/fleekcli/version.go index e8eb0927..341734c7 100644 --- a/internal/fleekcli/version.go +++ b/internal/fleekcli/version.go @@ -2,10 +2,17 @@ package fleekcli import ( "fmt" + "io" + "net/http" + "os" "runtime" + "strings" "github.com/spf13/cobra" + "github.com/ublue-os/fleek/fin" "github.com/ublue-os/fleek/internal/build" + "github.com/ublue-os/fleek/internal/envir" + "github.com/ublue-os/fleek/internal/vercheck" ) type versionFlags struct { @@ -27,12 +34,29 @@ func VersionCmd() *cobra.Command { app.Trans("version.flagVerboseDescription"), ) + command.AddCommand(selfUpdateCmd()) return command } +func selfUpdateCmd() *cobra.Command { + command := &cobra.Command{ + Use: "update", + Short: "Update fleek launcher and binary", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + return vercheck.SelfUpdate(cmd.OutOrStdout(), cmd.ErrOrStderr()) + }, + } + + return command +} func versionCmdFunc(cmd *cobra.Command, _ []string, flags versionFlags) error { w := cmd.OutOrStdout() v := getVersionInfo() + lv, err := latestVersion() + if err != nil { + fin.Logger.Warn("Unable to check latest version", fin.Logger.Args("error", err)) + } if flags.verbose { fmt.Fprintf(w, app.Trans("version.version"), v.Version) @@ -40,6 +64,10 @@ func versionCmdFunc(cmd *cobra.Command, _ []string, flags versionFlags) error { fmt.Fprintf(w, app.Trans("version.commit"), v.Commit) fmt.Fprintf(w, app.Trans("version.time"), v.CommitDate) fmt.Fprintf(w, app.Trans("version.go"), v.GoVersion) + fmt.Fprintf(w, "Launcher: %v\n", v.LauncherVersion) + fmt.Fprintf(w, "Latest Version: %v\n", lv) + fmt.Fprintf(w, "Upgrade available: %v\n", isNewFleekAvailable(v.Version, lv)) + } else { fmt.Fprintf(w, "%v\n", v.Version) } @@ -47,22 +75,49 @@ func versionCmdFunc(cmd *cobra.Command, _ []string, flags versionFlags) error { } type versionInfo struct { - Version string - IsPrerelease bool - Platform string - Commit string - CommitDate string - GoVersion string + Version string + IsPrerelease bool + Platform string + Commit string + CommitDate string + GoVersion string + LauncherVersion string } func getVersionInfo() *versionInfo { v := &versionInfo{ - Version: build.Version, - Platform: fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH), - Commit: build.Commit, - CommitDate: build.CommitDate, - GoVersion: runtime.Version(), + Version: build.Version, + Platform: fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH), + Commit: build.Commit, + CommitDate: build.CommitDate, + GoVersion: runtime.Version(), + LauncherVersion: os.Getenv(envir.LauncherVersion), } return v } + +func latestVersion() (string, error) { + res, err := http.Get("https://releases.getfleek.dev/fleek/stable/version") + if err != nil { + return "unknown", err + } + defer res.Body.Close() + body, err := io.ReadAll(res.Body) + if err != nil { + return "unknown", err + } + sb := string(body) + return strings.TrimSpace(sb), nil +} + +// isNewFleekAvailable returns true if a new fleek CLI binary version is available. +func isNewFleekAvailable(current, latest string) bool { + if latest == "" { + return false + } + if strings.Contains(current, "0.0.0-dev") { + return false + } + return vercheck.SemverCompare(current, latest) < 0 +} diff --git a/internal/fleekcli/write.go b/internal/fleekcli/write.go index d455a0d1..0a5da8f1 100644 --- a/internal/fleekcli/write.go +++ b/internal/fleekcli/write.go @@ -39,7 +39,8 @@ func write(cmd *cobra.Command) error { err = fl.Write("flake update", true, false) if err != nil { - fin.Debug.Printfln("flake write error: %s", err) + fin.Logger.Error("flake write", fin.Logger.Args("error", err)) + return err } diff --git a/internal/midcobra/verbose.go b/internal/midcobra/verbose.go new file mode 100644 index 00000000..714fa208 --- /dev/null +++ b/internal/midcobra/verbose.go @@ -0,0 +1,80 @@ +// Copyright 2022 Jetpack Technologies Inc and contributors. All rights reserved. +// Use of this source code is governed by the license in the LICENSE file. + +package midcobra + +import ( + "errors" + "os" + "os/exec" + "strconv" + + "github.com/fatih/color" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + "github.com/ublue-os/fleek/fin" + "github.com/ublue-os/fleek/internal/debug" + "github.com/ublue-os/fleek/internal/fleekcli/usererr" + "github.com/ublue-os/fleek/internal/ux" + "github.com/ublue-os/fleek/internal/verbose" +) + +type VerboseMiddleware struct { + executionID string // uuid + flag *pflag.Flag +} + +var _ Middleware = (*VerboseMiddleware)(nil) + +func (d *VerboseMiddleware) AttachToFlag(flags *pflag.FlagSet, flagName string) { + flags.Bool( + flagName, + false, + "Show full stack traces on errors", + ) + d.flag = flags.Lookup(flagName) + d.flag.Hidden = true +} + +func (d *VerboseMiddleware) preRun(_ *cobra.Command, _ []string) { + if d == nil { + return + } + + strVal := "" + if d.flag.Changed { + strVal = d.flag.Value.String() + } else { + strVal = os.Getenv("FLEEK_VERBOSE") + } + if enabled, _ := strconv.ParseBool(strVal); enabled { + verbose.Enable() + } +} + +func (d *VerboseMiddleware) postRun(cmd *cobra.Command, _ []string, runErr error) { + if runErr == nil { + return + } + if usererr.HasUserMessage(runErr) { + if usererr.IsWarning(runErr) { + ux.Fwarning(cmd.ErrOrStderr(), runErr.Error()) + return + } + color.New(color.FgRed).Fprintf(cmd.ErrOrStderr(), "\nError: %s\n\n", runErr.Error()) + } else { + color.New(color.FgRed).Fprintf(cmd.ErrOrStderr(), "Error: %v\n\n", runErr) + } + + st := debug.EarliestStackTrace(runErr) + var exitErr *exec.ExitError + if errors.As(runErr, &exitErr) { + fin.Debug.Printfln("Command stderr: %s\n", exitErr.Stderr) + } + fin.Debug.Printfln("\nExecutionID:%s\n%+v\n", d.executionID, st) +} + +func (d *VerboseMiddleware) withExecutionID(execID string) Middleware { + d.executionID = execID + return d +} diff --git a/internal/verbose/verbose.go b/internal/verbose/verbose.go new file mode 100644 index 00000000..6804b6d1 --- /dev/null +++ b/internal/verbose/verbose.go @@ -0,0 +1,78 @@ +package verbose + +import ( + "fmt" + "io" + "log" + "os" + "strconv" + + "github.com/pkg/errors" + "github.com/ublue-os/fleek/fin" +) + +var enabled bool + +func init() { + enabled, _ = strconv.ParseBool(os.Getenv("FLEEK_VERBOSE")) +} + +func IsEnabled() bool { return enabled } + +func Enable() { + enabled = true + //pterm.EnableDebugMessages() + + fin.SetVerbose() + //_ = log.Output(2, "Debug mode enabled.") +} + +func SetOutput(w io.Writer) { + log.SetOutput(w) +} + +func Log(format string, v ...any) { + if !enabled { + return + } + _ = log.Output(2, fmt.Sprintf(format, v...)) +} + +func Recover() { + r := recover() + if r == nil { + return + } + if enabled { + log.Println("Allowing panic because debug mode is enabled.") + panic(r) + } + fmt.Println("Error:", r) +} + +func EarliestStackTrace(err error) errors.StackTrace { + type stackTracer interface { + StackTrace() errors.StackTrace + } + + type causer interface { + Cause() error + } + + var st stackTracer + var earliestStackTrace errors.StackTrace + + for err != nil { + if errors.As(err, &st) { + earliestStackTrace = st.StackTrace() + } + + var c causer + if !errors.As(err, &c) { + break + } + err = c.Cause() + } + + return earliestStackTrace +} diff --git a/internal/vercheck/vercheck.go b/internal/vercheck/vercheck.go new file mode 100644 index 00000000..58f02e0e --- /dev/null +++ b/internal/vercheck/vercheck.go @@ -0,0 +1,299 @@ +// Copyright 2023 Jetpack Technologies Inc and contributors. All rights reserved. +// Use of this source code is governed by the license in the LICENSE file. + +package vercheck + +import ( + "bytes" + "fmt" + "io" + "io/fs" + "os" + "os/exec" + "path/filepath" + "strings" + + "github.com/fatih/color" + "github.com/pkg/errors" + "github.com/samber/lo" + "golang.org/x/mod/semver" + + "github.com/ublue-os/fleek/internal/build" + "github.com/ublue-os/fleek/internal/cmdutil" + "github.com/ublue-os/fleek/internal/envir" + "github.com/ublue-os/fleek/internal/fleekcli/usererr" + "github.com/ublue-os/fleek/internal/ux" + "github.com/ublue-os/fleek/internal/xdg" +) + +// Keep this in-sync with latest version in launch.sh. +// If this version is newer than the version in launch.sh, we'll print a notice. +const expectedLauncherVersion = "0.2.1" + +// envName determines whether the version check has already occurred. +// We set this env-var so that this fleek command invoking other fleek commands +// do not re-run the version check and print the notice again. +const envName = "__FLEEK_VERSION_CHECK" + +// currentFleekVersion is the version of the fleek CLI binary that is currently running. +// We use this variable so that we can mock it in tests. +var currentFleekVersion = build.Version + +// isDevBuild determines whether this CLI binary was built during development, or published +// as a release. +// We use this variable so we can mock it in tests. +var isDevBuild = build.IsDev + +var commandSkipList = []string{ + "fleek version update", +} + +// CheckVersion checks the launcher and binary versions and prints a notice if +// they are out of date. +// +// It will set the checkVersionEnvName to indicate that the version check was done. +// Callers should call ClearEnvVar after their work is done. +func CheckVersion(w io.Writer, commandPath string) { + if isDevBuild { + return + } + + if os.Getenv(envName) == "1" { + return + } + + hasSkipPrefix := lo.ContainsBy( + commandSkipList, + func(skipPath string) bool { return strings.HasPrefix(commandPath, skipPath) }, + ) + if hasSkipPrefix { + return + } + + // check launcher version + launcherNotice := launcherVersionNotice() + if launcherNotice != "" { + ux.Finfo(w, launcherNotice) + + // fallthrough to alert the user about a new Devbox CLI binary being possibly available + } + + // check fleek CLI version + fleekNotice := fleekVersionNotice() + if fleekNotice != "" { + ux.Finfo(w, fleekNotice) + } + + os.Setenv(envName, "1") +} + +// SelfUpdate updates the fleek launcher and fleek CLI binary. +// It ignores and deletes the version cache. +// +// The launcher is a wrapper bash script introduced to manage the auto-update process +// for fleek. The production fleek application is actually this launcher script +// that acts as "fleek" and delegates commands to the fleek CLI binary. +func SelfUpdate(stdOut, stdErr io.Writer) error { + if isNewLauncherAvailable() { + return selfUpdateLauncher(stdOut, stdErr) + } + + return selfUpdateFleek(stdErr) +} + +func selfUpdateLauncher(stdOut, stdErr io.Writer) error { + installScript := "" + if cmdutil.Exists("curl") { + installScript = "curl -fsSL https://getfleek.dev/fleek | bash" + } else if cmdutil.Exists("wget") { + installScript = "wget -qO- https://getfleek.dev/fleek | bash" + } else { + return usererr.New("curl or wget is required to update fleek. Please install either and try again.") + } + + // Delete current version file. This will trigger an update when invoking any fleek command; + // in this case, inside triggerUpdate function. + if err := removeCurrentVersionFile(); err != nil { + return err + } + + // Fetch the new launcher. And installs the new fleek CLI binary. + cmd := exec.Command("sh", "-c", installScript) + cmd.Stdout = stdOut + cmd.Stderr = stdErr + if err := cmd.Run(); err != nil { + return errors.WithStack(err) + } + + // Previously, we have already updated the binary. So, we call triggerUpdate + // just to get the new version information. + updated, err := triggerUpdate(stdErr) + if err != nil { + return errors.WithStack(err) + } + + printSuccessMessage(stdErr, "Launcher", currentLauncherVersion(), updated.launcherVersion) + printSuccessMessage(stdErr, "Fleek", currentFleekVersion, updated.fleekVersion) + + return nil +} + +// selfUpdateFleek will update the fleek CLI binary to the latest version. +func selfUpdateFleek(stdErr io.Writer) error { + // Delete current version file. This will trigger an update when the next fleek command is run; + // in this case, inside triggerUpdate function. + if err := removeCurrentVersionFile(); err != nil { + return err + } + + updated, err := triggerUpdate(stdErr) + if err != nil { + return errors.WithStack(err) + } + + printSuccessMessage(stdErr, "Fleek", currentFleekVersion, updated.fleekVersion) + + return nil +} + +type updatedVersions struct { + fleekVersion string + launcherVersion string +} + +// triggerUpdate runs `fleek version -v` and triggers an update since a new +// version is available. It parses the output to get the new launcher and +// fleek versions. +func triggerUpdate(stdErr io.Writer) (*updatedVersions, error) { + + exePath := os.Getenv(envir.LauncherPath) + if exePath == "" { + ux.Fwarning(stdErr, "expected LAUNCHER_PATH to be set. Defaulting to \"fleek\".") + exePath = "fleek" + } + + // TODO savil. Add a --json flag to fleek version and parse the output as JSON + cmd := exec.Command(exePath, "version", "-v") + + buf := new(bytes.Buffer) + cmd.Stdout = io.MultiWriter(stdErr, buf) + cmd.Stderr = stdErr + if err := cmd.Run(); err != nil { + return nil, errors.WithStack(err) + } + + // Parse the output to ascertain the new fleek and launcher versions + updated := &updatedVersions{} + for _, line := range strings.Split(buf.String(), "\n") { + if strings.HasPrefix(line, "Version:") { + updated.fleekVersion = strings.TrimSpace(strings.TrimPrefix(line, "Version:")) + } + + if strings.HasPrefix(line, "Launcher:") { + updated.launcherVersion = strings.TrimSpace(strings.TrimPrefix(line, "Launcher:")) + } + } + return updated, nil +} + +func printSuccessMessage(w io.Writer, toolName, oldVersion, newVersion string) { + var msg string + if SemverCompare(oldVersion, newVersion) == 0 { + msg = fmt.Sprintf("already at %s version %s", toolName, newVersion) + } else { + msg = fmt.Sprintf("updated to %s version %s", toolName, newVersion) + } + + // Prints a Success: message to the writer. + // Move to ux.Success. Not doing so to minimize merge-conflicts. + fmt.Fprintf(w, "%s%s\n", color.New(color.FgGreen).Sprint("Success: "), msg) +} + +func launcherVersionNotice() string { + if !isNewLauncherAvailable() { + return "" + } + + return fmt.Sprintf( + "New launcher available: %s -> %s. Please run `fleek version update`.\n", + currentLauncherVersion(), + expectedLauncherVersion, + ) +} + +func fleekVersionNotice() string { + if !isNewFleekAvailable() { + return "" + } + + return fmt.Sprintf( + "New fleek available: %s -> %s. Please run `fleek version update`.\n", + currentFleekVersion, + latestVersion(), + ) +} + +// isNewLauncherAvailable returns true if a new launcher version is available. +func isNewLauncherAvailable() bool { + launcherVersion := currentLauncherVersion() + if launcherVersion == "" { + return false + } + return SemverCompare(launcherVersion, expectedLauncherVersion) < 0 +} + +// isNewFleekAvailable returns true if a new fleek CLI binary version is available. +func isNewFleekAvailable() bool { + latest := latestVersion() + if latest == "" { + return false + } + return SemverCompare(currentFleekVersion, latest) < 0 +} + +// currentLauncherAvailable returns launcher's version if it is +// available, or empty string if it is not. +func currentLauncherVersion() string { + launcherVersion := os.Getenv(envir.LauncherVersion) + if launcherVersion == "" { + return "" + } + return "v" + launcherVersion +} + +func removeCurrentVersionFile() error { + // currentVersionFilePath is the path to the file that contains the cached + // version. The launcher checks this file to see if a new version is available. + // If the version is newer, then the launcher updates. + // + // Note: keep this in sync with launch.sh code + currentVersionFilePath := filepath.Join(xdg.CacheSubpath("fleek"), "current-version") + + if err := os.Remove(currentVersionFilePath); err != nil && !errors.Is(err, fs.ErrNotExist) { + return usererr.WithLoggedUserMessage( + err, + "Failed to delete version-cache at %s. Please manually delete it and try again.", + currentVersionFilePath, + ) + } + return nil +} + +func SemverCompare(ver1, ver2 string) int { + if !strings.HasPrefix(ver1, "v") { + ver1 = "v" + ver1 + } + if !strings.HasPrefix(ver2, "v") { + ver2 = "v" + ver2 + } + return semver.Compare(ver1, ver2) +} + +// latestVersion returns the latest version available for the binary. +func latestVersion() string { + version := os.Getenv(envir.FleekLatestVersion) + if version == "" { + return "" + } + return "v" + version +} diff --git a/internal/vercheck/vercheck_test.go b/internal/vercheck/vercheck_test.go new file mode 100644 index 00000000..024ac51c --- /dev/null +++ b/internal/vercheck/vercheck_test.go @@ -0,0 +1,114 @@ +// Copyright 2023 Jetpack Technologies Inc and contributors. All rights reserved. +// Use of this source code is governed by the license in the LICENSE file. + +package vercheck + +import ( + "bytes" + "os" + "strings" + "testing" + + "github.com/ublue-os/fleek/internal/envir" +) + +func TestCheckVersion(t *testing.T) { + + isDevBuild = false + + // no launcher version or latest-version env var + t.Run("skip_if_no_launcher_version_or_latest_version", func(t *testing.T) { + defer os.Unsetenv(envName) + t.Setenv(envir.LauncherVersion, "") + t.Setenv(envir.FleekLatestVersion, "") + buf := new(bytes.Buffer) + CheckVersion(buf, "fleek info") + if buf.String() != "" { + t.Errorf("expected empty string, got %q", buf.String()) + } + }) + + t.Run("print_if_launcher_version_outdated", func(t *testing.T) { + defer os.Unsetenv(envName) + // set older launcher version + t.Setenv(envir.LauncherVersion, "v0.1.0") + + buf := new(bytes.Buffer) + CheckVersion(buf, "fleek info") + if !strings.Contains(buf.String(), "New launcher available") { + t.Errorf("expected notice about new launcher version, got %q", buf.String()) + } + }) + + t.Run("print_if_binary_version_outdated", func(t *testing.T) { + defer os.Unsetenv(envName) + // set the launcher version so that it is not outdated + t.Setenv(envir.LauncherVersion, strings.TrimPrefix(expectedLauncherVersion, "v")) + + // set the latest version to be greater the current binary version + t.Setenv(envir.FleekLatestVersion, "0.4.9") + + // mock the existing binary version + currentFleekVersion = "v0.4.8" + + buf := new(bytes.Buffer) + CheckVersion(buf, "fleek info") + if !strings.Contains(buf.String(), "New fleek available") { + t.Errorf("expected notice about new fleek version, got %q", buf.String()) + } + }) + + t.Run("skip_if_all_versions_up_to_date", func(t *testing.T) { + defer os.Unsetenv(envName) + + // set the launcher version so that it is not outdated + t.Setenv(envir.LauncherVersion, strings.TrimPrefix(expectedLauncherVersion, "v")) + + // mock the existing binary version + currentFleekVersion = "v0.4.8" + + // set the latest version to the same as the current binary version + t.Setenv(envir.FleekLatestVersion, "0.4.8") + + buf := new(bytes.Buffer) + CheckVersion(buf, "fleek info") + if buf.String() != "" { + t.Errorf("expected empty string, got %q", buf.String()) + } + }) + + t.Run("skip_if_dev_build", func(t *testing.T) { + defer os.Unsetenv(envName) + isDevBuild = true + defer func() { isDevBuild = false }() + + // set older launcher version + t.Setenv(envir.LauncherVersion, "v0.1.0") + + buf := new(bytes.Buffer) + CheckVersion(buf, "fleek info") + if buf.String() != "" { + t.Errorf("expected empty string, got %q", buf.String()) + } + }) + + t.Run("skip_if_command_path_skipped", func(t *testing.T) { + defer os.Unsetenv(envName) + + for _, cmdPath := range commandSkipList { + cmdPathUnderscored := strings.ReplaceAll(cmdPath, " ", "_") + t.Run("skip_if_cmd_path_is_"+cmdPathUnderscored, func(t *testing.T) { + + // set older launcher version + t.Setenv(envir.LauncherVersion, "v0.1.0") + + buf := new(bytes.Buffer) + CheckVersion(buf, cmdPath) + if buf.String() != "" { + t.Errorf("expected empty string, got %q", buf.String()) + } + }) + } + }) + +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go index ffdd5151..df04262e 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go @@ -73,7 +73,9 @@ func (c *x448) GenerateECDH(rand io.Reader) (point []byte, secret []byte, err er func (c *x448) Encaps(rand io.Reader, point []byte) (ephemeral, sharedSecret []byte, err error) { var pk, ss x448lib.Key seed, e, err := c.generateKeyPairBytes(rand) - + if err != nil { + return nil, nil, err + } copy(pk[:], point) x448lib.Shared(&ss, &seed, &pk) diff --git a/vendor/github.com/muesli/mango/README.md b/vendor/github.com/muesli/mango/README.md index 5d8b5f63..3963e067 100644 --- a/vendor/github.com/muesli/mango/README.md +++ b/vendor/github.com/muesli/mango/README.md @@ -1,12 +1,14 @@ # mango -[![Build Status](https://github.com/muesli/mango/workflows/build/badge.svg)](https://github.com/muesli/mango/actions) -[![Go ReportCard](https://goreportcard.com/badge/muesli/mango)](https://goreportcard.com/report/muesli/mango) -[![GoDoc](https://godoc.org/github.com/golang/gddo?status.svg)](https://pkg.go.dev/github.com/muesli/mango) +[![Latest Release](https://img.shields.io/github/release/muesli/mango.svg?style=for-the-badge)](https://github.com/muesli/mango/releases) +[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=for-the-badge)](/LICENSE) +[![Build Status](https://img.shields.io/github/workflow/status/muesli/mango/build?style=for-the-badge)](https://github.com/muesli/mango/actions) +[![Go ReportCard](https://goreportcard.com/badge/github.com/muesli/mango?style=for-the-badge)](https://goreportcard.com/report/muesli/mango) +[![Go Doc](https://img.shields.io/badge/godoc-reference-blue.svg?style=for-the-badge)](https://pkg.go.dev/github.com/muesli/mango) -mango is a man-page generator for the Go flag, pflag, cobra, and coral packages. -It extracts commands, flags, and arguments from your program and enables it to -self-document. +mango is a man-page generator for the Go flag, pflag, cobra, coral, and kong +packages. It extracts commands, flags, and arguments from your program and +enables it to self-document. ## Adapters @@ -15,6 +17,7 @@ Currently the following adapters exist: - flag: support for Go's standard flag package - [mango-cobra](https://github.com/muesli/mango-cobra): an adapter for [cobra](https://github.com/spf13/cobra) - [mango-coral](https://github.com/muesli/mango-coral): an adapter for [coral](https://github.com/muesli/coral) +- [mango-kong](https://github.com/alecthomas/mango-kong): an adapter for [kong](https://github.com/alecthomas/kong) - [mango-pflag](https://github.com/muesli/mango-pflag): an adapter for the [pflag](https://github.com/spf13/pflag) package ## Usage with flag: @@ -37,7 +40,7 @@ var ( func main() { flag.Parse() - manPage := mango.NewManPage(1, "mango", "mango - a man-page generator"). + manPage := mango.NewManPage(1, "mango", "a man-page generator"). WithLongDescription("mango is a man-page generator for Go.\n"+ "Features:\n"+ "* User-friendly\n"+ @@ -70,7 +73,7 @@ import ( func main() { flag.Parse() - manPage := mango.NewManPage(1, "mango", "mango - a man-page generator"). + manPage := mango.NewManPage(1, "mango", "a man-page generator"). WithLongDescription("mango is a man-page generator for Go."). WithSection("Copyright", "(C) 2022 Christian Muehlhaeuser.\n"+ "Released under MIT license.") diff --git a/vendor/github.com/muesli/mango/mango.go b/vendor/github.com/muesli/mango/mango.go index fee6a041..a7f00d00 100644 --- a/vendor/github.com/muesli/mango/mango.go +++ b/vendor/github.com/muesli/mango/mango.go @@ -22,6 +22,7 @@ type Command struct { Name string Short string Usage string + Example string Flags map[string]Flag Commands map[string]*Command } @@ -124,7 +125,7 @@ func (m ManPage) buildCommand(w Builder, c Command) { } if opt.Short != "" { - w.TextBold(fmt.Sprintf("%[1]s%[2]s %[1]s%[3]s", prefix, opt.Short, opt.Name)) + w.TextBold(fmt.Sprintf("-%[2]s, %[1]s%[3]s", prefix, opt.Short, opt.Name)) } else { w.TextBold(prefix + opt.Name) } @@ -176,6 +177,24 @@ func (m ManPage) buildCommand(w Builder, c Command) { w.IndentEnd() } } + + if c.Example != "" { + if c.Name == m.Root.Name { + w.Section("Examples") + w.TaggedParagraph(-1) + } else { + w.TaggedParagraph(-1) + w.TextBold("EXAMPLES") + w.Indent(4) + } + w.Text(c.Example) + + if c.Name == m.Root.Name { + w.EndSection() + } else { + w.IndentEnd() + } + } } // Build generates the man page. diff --git a/vendor/github.com/pterm/pterm/README.md b/vendor/github.com/pterm/pterm/README.md index 2648375b..f05f2d93 100644 --- a/vendor/github.com/pterm/pterm/README.md +++ b/vendor/github.com/pterm/pterm/README.md @@ -44,8 +44,8 @@ PTerm -

Show Demo Code

+

Show Demo Code

@@ -92,6 +92,8 @@ go get github.com/pterm/pterm ### Printers (Components) +
+ | Feature | Feature | Feature | Feature | Feature | | :-------: | :-------: | :-------: | :-------: | :-------: | @@ -99,18 +101,21 @@ go get github.com/pterm/pterm | Bulletlist
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/bulletlist) |Center
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/center) |Coloring
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/coloring) |Demo
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/demo) |Header
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/header) | | Interactive confirm
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/interactive_confirm) |Interactive continue
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/interactive_continue) |Interactive multiselect
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/interactive_multiselect) |Interactive select
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/interactive_select) |Interactive textinput
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/interactive_textinput) | | Logger
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/logger) |Multiple-live-printers
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/multiple-live-printers) |Panel
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/panel) |Paragraph
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/paragraph) |Prefix
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/prefix) | -| Progressbar
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/progressbar) |Section
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/section) |Spinner
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/spinner) |Style
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/style) |Table
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/table) | -| Theme
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/theme) |Tree
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/tree) | | | | +| Progressbar
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/progressbar) |Section
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/section) |Slog
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/slog) |Spinner
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/spinner) |Style
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/style) | +| Table
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/table) |Theme
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/theme) |Tree
[(Examples)](https://github.com/pterm/pterm/tree/master/_examples/tree) | | | +
+ +---
-### 🦸‍♂️ Supporters +### 🦸‍♂️ Sponsors + + -|-|User|💸| -|---|---|---| -|![Jens Lauterbach](https://avatars.githubusercontent.com/u/1292368?s=25)|[@jenslauterbach](https://github.com/jenslauterbach)|25$| +---
@@ -2442,6 +2447,38 @@ func main() { +### slog/demo + +![Animation](https://raw.githubusercontent.com/pterm/pterm/master/_examples/slog/demo/animation.svg) + +
+ +SHOW SOURCE + +```go +package main + +import ( + "github.com/pterm/pterm" + "log/slog" +) + +func main() { + handler := pterm.NewSlogHandler(&pterm.DefaultLogger) + logger := slog.New(handler) + + logger.Debug("This is a debug message that won't show") + pterm.DefaultLogger.Level = pterm.LogLevelDebug // Enable debug messages + logger.Debug("This is a debug message", "changedLevel", true) + logger.Info("This is an info message") + logger.Warn("This is a warning message") + logger.Error("This is an error message") +} + +``` + +
+ ### spinner/demo ![Animation](https://raw.githubusercontent.com/pterm/pterm/master/_examples/spinner/demo/animation.svg) diff --git a/vendor/github.com/pterm/pterm/interactive_multiselect_printer.go b/vendor/github.com/pterm/pterm/interactive_multiselect_printer.go index e3d592c8..754ba98a 100644 --- a/vendor/github.com/pterm/pterm/interactive_multiselect_printer.go +++ b/vendor/github.com/pterm/pterm/interactive_multiselect_printer.go @@ -240,7 +240,7 @@ func (p *InteractiveMultiselectPrinter) Show(text ...string) ([]string, error) { p.selectedOptions = append(p.selectedOptions, i) } area.Update(p.renderSelectMenu()) - case keys.Up: + case keys.Up, keys.CtrlP: if len(p.fuzzySearchMatches) == 0 { return false, nil } @@ -263,7 +263,7 @@ func (p *InteractiveMultiselectPrinter) Show(text ...string) ([]string, error) { } area.Update(p.renderSelectMenu()) - case keys.Down: + case keys.Down, keys.CtrlN: if len(p.fuzzySearchMatches) == 0 { return false, nil } diff --git a/vendor/github.com/pterm/pterm/interactive_select_printer.go b/vendor/github.com/pterm/pterm/interactive_select_printer.go index 2dbab662..0c4bc995 100644 --- a/vendor/github.com/pterm/pterm/interactive_select_printer.go +++ b/vendor/github.com/pterm/pterm/interactive_select_printer.go @@ -196,7 +196,7 @@ func (p *InteractiveSelectPrinter) Show(text ...string) (string, error) { p.displayedOptions = append([]string{}, p.fuzzySearchMatches[p.displayedOptionsStart:p.displayedOptionsEnd]...) area.Update(p.renderSelectMenu()) - case keys.Up: + case keys.Up, keys.CtrlP: if len(p.fuzzySearchMatches) == 0 { return false, nil } @@ -219,7 +219,7 @@ func (p *InteractiveSelectPrinter) Show(text ...string) (string, error) { } area.Update(p.renderSelectMenu()) - case keys.Down: + case keys.Down, keys.CtrlN: if len(p.fuzzySearchMatches) == 0 { return false, nil } diff --git a/vendor/github.com/pterm/pterm/pterm.go b/vendor/github.com/pterm/pterm/pterm.go index 09557157..f9d76ca3 100644 --- a/vendor/github.com/pterm/pterm/pterm.go +++ b/vendor/github.com/pterm/pterm/pterm.go @@ -7,11 +7,7 @@ package pterm import ( - "atomicgo.dev/cursor" "github.com/gookit/color" - "os" - "os/signal" - "syscall" ) var ( @@ -30,16 +26,6 @@ var ( func init() { color.ForceColor() - - // Make the cursor visible when the program stops - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - signal.Notify(c, syscall.SIGTERM) - go func() { - for range c { - cursor.Show() - } - }() } // EnableOutput enables the output of PTerm. diff --git a/vendor/github.com/pterm/pterm/slog_handler.go b/vendor/github.com/pterm/pterm/slog_handler.go new file mode 100644 index 00000000..db35617e --- /dev/null +++ b/vendor/github.com/pterm/pterm/slog_handler.go @@ -0,0 +1,82 @@ +package pterm + +import ( + "context" + "log/slog" +) + +type SlogHandler struct { + logger *Logger + attrs []slog.Attr +} + +// Enabled returns true if the given level is enabled. +func (s *SlogHandler) Enabled(ctx context.Context, level slog.Level) bool { + switch level { + case slog.LevelDebug: + return s.logger.CanPrint(LogLevelDebug) + case slog.LevelInfo: + return s.logger.CanPrint(LogLevelInfo) + case slog.LevelWarn: + return s.logger.CanPrint(LogLevelWarn) + case slog.LevelError: + return s.logger.CanPrint(LogLevelError) + } + return false +} + +// Handle handles the given record. +func (s *SlogHandler) Handle(ctx context.Context, record slog.Record) error { + level := record.Level + message := record.Message + + // Convert slog Attrs to a map. + keyValsMap := make(map[string]interface{}) + + record.Attrs(func(attr slog.Attr) bool { + keyValsMap[attr.Key] = attr.Value + return true + }) + + for _, attr := range s.attrs { + keyValsMap[attr.Key] = attr.Value + } + + args := s.logger.ArgsFromMap(keyValsMap) + + // Wrapping args inside another slice to match [][]LoggerArgument + argsWrapped := [][]LoggerArgument{args} + + switch level { + case slog.LevelDebug: + s.logger.Debug(message, argsWrapped...) + case slog.LevelInfo: + s.logger.Info(message, argsWrapped...) + case slog.LevelWarn: + s.logger.Warn(message, argsWrapped...) + case slog.LevelError: + s.logger.Error(message, argsWrapped...) + default: + s.logger.Print(message, argsWrapped...) + } + + return nil +} + +// WithAttrs returns a new handler with the given attributes. +func (s *SlogHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + newS := *s + newS.attrs = attrs + return &newS +} + +// WithGroup is not yet supported. +func (s *SlogHandler) WithGroup(name string) slog.Handler { + // Grouping is not yet supported by pterm. + return s +} + +// NewSlogHandler returns a new logging handler that can be intrgrated with log/slog. +func NewSlogHandler(logger *Logger) *SlogHandler { + return &SlogHandler{logger: logger} +} diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go index 2a9f2dc3..4f7b4248 100644 --- a/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go +++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go @@ -1313,17 +1313,17 @@ func (dmp *DiffMatchPatch) diffLinesToStrings(text1, text2 string) (string, stri // '\x00' is a valid character, but various debuggers don't like it. So we'll insert a junk entry to avoid generating a null character. lineArray := []string{""} // e.g. lineArray[4] == 'Hello\n' + lineHash := make(map[string]int) //Each string has the index of lineArray which it points to - strIndexArray1 := dmp.diffLinesToStringsMunge(text1, &lineArray) - strIndexArray2 := dmp.diffLinesToStringsMunge(text2, &lineArray) + strIndexArray1 := dmp.diffLinesToStringsMunge(text1, &lineArray, lineHash) + strIndexArray2 := dmp.diffLinesToStringsMunge(text2, &lineArray, lineHash) return intArrayToString(strIndexArray1), intArrayToString(strIndexArray2), lineArray } // diffLinesToStringsMunge splits a text into an array of strings, and reduces the texts to a []string. -func (dmp *DiffMatchPatch) diffLinesToStringsMunge(text string, lineArray *[]string) []uint32 { +func (dmp *DiffMatchPatch) diffLinesToStringsMunge(text string, lineArray *[]string, lineHash map[string]int) []uint32 { // Walk the text, pulling out a substring for each line. text.split('\n') would would temporarily double our memory footprint. Modifying text would create many large strings to garbage collect. - lineHash := map[string]int{} // e.g. lineHash['Hello\n'] == 4 lineStart := 0 lineEnd := -1 strs := []uint32{} diff --git a/vendor/github.com/skeema/knownhosts/knownhosts.go b/vendor/github.com/skeema/knownhosts/knownhosts.go index c460031b..c2fb5160 100644 --- a/vendor/github.com/skeema/knownhosts/knownhosts.go +++ b/vendor/github.com/skeema/knownhosts/knownhosts.go @@ -5,6 +5,7 @@ package knownhosts import ( "encoding/base64" "errors" + "fmt" "io" "net" "sort" @@ -68,8 +69,19 @@ func (hkcb HostKeyCallback) HostKeys(hostWithPort string) (keys []ssh.PublicKey) // known_hosts entries (for different key types), the result will be sorted by // known_hosts filename and line number. func (hkcb HostKeyCallback) HostKeyAlgorithms(hostWithPort string) (algos []string) { - for _, key := range hkcb.HostKeys(hostWithPort) { - algos = append(algos, key.Type()) + // We ensure that algos never contains duplicates. This is done for robustness + // even though currently golang.org/x/crypto/ssh/knownhosts never exposes + // multiple keys of the same type. This way our behavior here is unaffected + // even if https://github.com/golang/go/issues/28870 is implemented, for + // example by https://github.com/golang/crypto/pull/254. + hostKeys := hkcb.HostKeys(hostWithPort) + seen := make(map[string]struct{}, len(hostKeys)) + for _, key := range hostKeys { + typ := key.Type() + if _, already := seen[typ]; !already { + algos = append(algos, typ) + seen[typ] = struct{}{} + } } return algos } @@ -140,11 +152,15 @@ func Line(addresses []string, key ssh.PublicKey) string { func WriteKnownHost(w io.Writer, hostname string, remote net.Addr, key ssh.PublicKey) error { // Always include hostname; only also include remote if it isn't a zero value // and doesn't normalize to the same string as hostname. - addresses := []string{hostname} - remoteStr := remote.String() - remoteStrNormalized := Normalize(remoteStr) - if remoteStrNormalized != "[0.0.0.0]:0" && remoteStrNormalized != Normalize(hostname) { - addresses = append(addresses, remoteStr) + hostnameNormalized := Normalize(hostname) + if strings.ContainsAny(hostnameNormalized, "\t ") { + return fmt.Errorf("knownhosts: hostname '%s' contains spaces", hostnameNormalized) + } + addresses := []string{hostnameNormalized} + remoteStrNormalized := Normalize(remote.String()) + if remoteStrNormalized != "[0.0.0.0]:0" && remoteStrNormalized != hostnameNormalized && + !strings.ContainsAny(remoteStrNormalized, "\t ") { + addresses = append(addresses, remoteStrNormalized) } line := Line(addresses, key) + "\n" _, err := w.Write([]byte(line)) diff --git a/vendor/modules.txt b/vendor/modules.txt index f9fa0da5..0e6a6d09 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -19,7 +19,7 @@ github.com/Microsoft/go-winio/internal/fs github.com/Microsoft/go-winio/internal/socket github.com/Microsoft/go-winio/internal/stringbuffer github.com/Microsoft/go-winio/pkg/guid -# github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 +# github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c ## explicit; go 1.13 github.com/ProtonMail/go-crypto/bitcurves github.com/ProtonMail/go-crypto/brainpool @@ -165,6 +165,8 @@ github.com/go-git/go-git/v5/utils/sync # github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da ## explicit github.com/golang/groupcache/lru +# github.com/golang/protobuf v1.5.3 +## explicit; go 1.9 # github.com/google/uuid v1.3.1 ## explicit github.com/google/uuid @@ -208,7 +210,7 @@ github.com/muesli/ansi/compressor # github.com/muesli/cancelreader v0.2.2 ## explicit; go 1.17 github.com/muesli/cancelreader -# github.com/muesli/mango v0.1.0 +# github.com/muesli/mango v0.2.0 ## explicit; go 1.17 github.com/muesli/mango # github.com/muesli/mango-cobra v1.2.0 @@ -240,8 +242,8 @@ github.com/pjbgf/sha1cd/ubc # github.com/pkg/errors v0.9.1 ## explicit github.com/pkg/errors -# github.com/pterm/pterm v0.12.66 -## explicit; go 1.18 +# github.com/pterm/pterm v0.12.69 +## explicit; go 1.21 github.com/pterm/pterm github.com/pterm/pterm/internal # github.com/rivo/uniseg v0.4.4 @@ -253,10 +255,10 @@ github.com/riywo/loginshell # github.com/samber/lo v1.38.1 ## explicit; go 1.18 github.com/samber/lo -# github.com/sergi/go-diff v1.2.0 +# github.com/sergi/go-diff v1.3.1 ## explicit; go 1.12 github.com/sergi/go-diff/diffmatchpatch -# github.com/skeema/knownhosts v1.2.0 +# github.com/skeema/knownhosts v1.2.1 ## explicit; go 1.17 github.com/skeema/knownhosts # github.com/spf13/cobra v1.7.0 @@ -289,8 +291,8 @@ golang.org/x/crypto/ssh golang.org/x/crypto/ssh/agent golang.org/x/crypto/ssh/internal/bcrypt_pbkdf golang.org/x/crypto/ssh/knownhosts -# golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 -## explicit; go 1.18 +# golang.org/x/exp v0.0.0-20230905200255-921286631fa9 +## explicit; go 1.20 golang.org/x/exp/constraints # golang.org/x/mod v0.12.0 ## explicit; go 1.17 @@ -344,6 +346,8 @@ golang.org/x/tools/internal/pkgbits golang.org/x/tools/internal/tokeninternal golang.org/x/tools/internal/typeparams golang.org/x/tools/internal/typesinternal +# google.golang.org/protobuf v1.26.0 +## explicit; go 1.9 # gopkg.in/warnings.v0 v0.1.2 ## explicit gopkg.in/warnings.v0