diff --git a/go.mod b/go.mod index 878620e4566b..fb92e4d71567 100644 --- a/go.mod +++ b/go.mod @@ -16,19 +16,13 @@ require ( cloud.google.com/go/storage v1.48.0 github.com/BobuSumisu/aho-corasick v1.0.3 github.com/TheZeroSlave/zapsentry v1.23.0 - github.com/adrg/strutil v0.3.1 github.com/alecthomas/kingpin/v2 v2.4.0 github.com/avast/apkparser v0.0.0-20240729092610-90591e0804ae github.com/aws/aws-sdk-go v1.55.5 - github.com/aymanbagabas/go-osc52 v1.2.1 github.com/bill-rich/go-syslog v0.0.0-20220413021637-49edb52a574c github.com/bitfinexcom/bitfinex-api-go v0.0.0-20210608095005-9e0b26f200fb github.com/bradleyfalzon/ghinstallation/v2 v2.12.0 github.com/brianvoe/gofakeit/v7 v7.1.2 - github.com/charmbracelet/bubbles v0.18.0 - github.com/charmbracelet/bubbletea v0.27.0 - github.com/charmbracelet/glamour v0.7.0 - github.com/charmbracelet/lipgloss v0.10.0 github.com/coinbase/waas-client-library-go v1.0.8 github.com/couchbase/gocb/v2 v2.9.3 github.com/crewjam/rfc5424 v0.1.0 @@ -66,13 +60,10 @@ require ( github.com/klauspost/pgzip v1.2.6 github.com/kylelemons/godebug v1.1.0 github.com/lib/pq v1.10.9 - github.com/lrstanley/bubblezone v0.0.0-20240125042004-b7bafc493195 github.com/marusama/semaphore/v2 v2.5.0 - github.com/mattn/go-isatty v0.0.20 github.com/mholt/archives v0.0.0-20241207175349-5e373c52f8aa github.com/microsoft/go-mssqldb v1.8.0 github.com/mitchellh/go-ps v1.0.0 - github.com/muesli/reflow v0.3.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/paulbellamy/ratecounter v0.2.0 github.com/pkg/errors v0.9.1 @@ -140,15 +131,11 @@ require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.0.0 // indirect github.com/STARRY-S/zip v0.2.1 // indirect - github.com/alecthomas/chroma/v2 v2.8.0 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/andybalholm/brotli v1.1.1 // indirect github.com/apache/arrow/go/v14 v14.0.2 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/atotto/clipboard v0.1.4 // indirect github.com/aws/smithy-go v1.20.1 // indirect - github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bodgit/plumbing v1.3.0 // indirect github.com/bodgit/sevenzip v1.6.0 // indirect @@ -156,10 +143,6 @@ require ( github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/charmbracelet/x/ansi v0.1.4 // indirect - github.com/charmbracelet/x/input v0.1.0 // indirect - github.com/charmbracelet/x/term v0.1.1 // indirect - github.com/charmbracelet/x/windows v0.1.0 // indirect github.com/cloudflare/circl v1.3.8 // indirect github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 // indirect github.com/containerd/containerd v1.7.18 // indirect @@ -175,7 +158,6 @@ require ( github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/dlclark/regexp2 v1.4.0 // indirect github.com/docker/cli v27.1.1+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v27.1.1+incompatible // indirect @@ -187,7 +169,6 @@ require ( github.com/elastic/elastic-transport-go/v8 v8.6.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/envoyproxy/go-control-plane v0.13.0 // indirect - github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/form3tech-oss/jwt-go v3.2.5+incompatible // indirect github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect @@ -213,7 +194,6 @@ require ( github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 // indirect github.com/google/s2a-go v0.1.8 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect - github.com/gorilla/css v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect @@ -228,13 +208,11 @@ require ( github.com/kjk/lzma v0.0.0-20161016003348-3fd93898850d // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-localereader v0.0.1 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/microcosm-cc/bluemonday v1.0.27 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -246,13 +224,9 @@ require ( github.com/montanaflynn/stats v0.7.1 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/mtibben/percent v0.2.1 // indirect - github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect - github.com/muesli/cancelreader v0.2.2 // indirect - github.com/muesli/termenv v0.15.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nwaples/rardecode/v2 v2.0.0-beta.4.0.20241112120701-034e449c6e78 // indirect github.com/oklog/ulid v1.3.1 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/onsi/ginkgo v1.16.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect @@ -266,7 +240,6 @@ require ( github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rivo/uniseg v0.4.7 // indirect - github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f // indirect github.com/sendgrid/rest v2.6.9+incompatible // indirect github.com/shirou/gopsutil/v3 v3.23.12 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect @@ -288,10 +261,7 @@ require ( github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect - github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect - github.com/yuin/goldmark v1.5.4 // indirect - github.com/yuin/goldmark-emoji v1.0.2 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect go.einride.tech/aip v0.60.0 // indirect diff --git a/go.sum b/go.sum index 0cae83336f21..02a05087aedd 100644 --- a/go.sum +++ b/go.sum @@ -11,8 +11,6 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= -cloud.google.com/go/auth v0.11.0 h1:Ic5SZz2lsvbYcWT5dfjNWgw6tTlGi2Wc8hyQSC9BstA= -cloud.google.com/go/auth v0.11.0/go.mod h1:xxA5AqpDrvS+Gkmo9RqrGGRh6WSNKKOXhY3zNOr38tI= cloud.google.com/go/auth v0.12.1 h1:n2Bj25BUMM0nvE9D2XLTiImanwZhO3DkfWSYS/SAJP4= cloud.google.com/go/auth v0.12.1/go.mod h1:BFMu+TNpF3DmvfBO9ClqTR/SiqVIm7LukKF9mbendF4= cloud.google.com/go/auth/oauth2adapt v0.2.6 h1:V6a6XDu2lTwPZWOawrAa9HUK+DB2zfJyTuciBG5hFkU= @@ -93,16 +91,8 @@ github.com/STARRY-S/zip v0.2.1 h1:pWBd4tuSGm3wtpoqRZZ2EAwOmcHK6XFf7bU9qcJXyFg= github.com/STARRY-S/zip v0.2.1/go.mod h1:xNvshLODWtC4EJ702g7cTYn13G53o1+X9BWnPFpcWV4= github.com/TheZeroSlave/zapsentry v1.23.0 h1:TKyzfEL7LRlRr+7AvkukVLZ+jZPC++ebCUv7ZJHl1AU= github.com/TheZeroSlave/zapsentry v1.23.0/go.mod h1:3DRFLu4gIpnCTD4V9HMCBSaqYP8gYU7mZickrs2/rIY= -github.com/adrg/strutil v0.3.1 h1:OLvSS7CSJO8lBii4YmBt8jiK9QOtB9CzCzwl4Ic/Fz4= -github.com/adrg/strutil v0.3.1/go.mod h1:8h90y18QLrs11IBffcGX3NW/GFBXCMcNg4M7H6MspPA= -github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink= -github.com/alecthomas/assert/v2 v2.2.1/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= -github.com/alecthomas/chroma/v2 v2.8.0 h1:w9WJUjFFmHHB2e8mRpL9jjy3alYDlU0QLDezj1xE264= -github.com/alecthomas/chroma/v2 v2.8.0/go.mod h1:yrkMI9807G1ROx13fhe1v6PN2DDeaR73L3d+1nmYQtw= github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY= github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= -github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= -github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= @@ -117,20 +107,12 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= -github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/avast/apkparser v0.0.0-20240729092610-90591e0804ae h1:rDNramK9mnAbvUBJyIRZnzHchM45cXexHIX9pS9da4Q= github.com/avast/apkparser v0.0.0-20240729092610-90591e0804ae/go.mod h1:GNvprXNmXaDjpHmN3RFxz5QdK5VXTUvmQludCbjoBy4= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw= github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= -github.com/aymanbagabas/go-osc52 v1.2.1 h1:q2sWUyDcozPLcLabEMd+a+7Ea2DitxZVN9hTxab9L4E= -github.com/aymanbagabas/go-osc52 v1.2.1/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= -github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= -github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= -github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= -github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -156,22 +138,6 @@ github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMr github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0= -github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= -github.com/charmbracelet/bubbletea v0.27.0 h1:Mznj+vvYuYagD9Pn2mY7fuelGvP0HAXtZYGgRBCbHvU= -github.com/charmbracelet/bubbletea v0.27.0/go.mod h1:5MdP9XH6MbQkgGhnlxUqCNmBXf9I74KRQ8HIidRxV1Y= -github.com/charmbracelet/glamour v0.7.0 h1:2BtKGZ4iVJCDfMF229EzbeR1QRKLWztO9dMtjmqZSng= -github.com/charmbracelet/glamour v0.7.0/go.mod h1:jUMh5MeihljJPQbJ/wf4ldw2+yBP59+ctV36jASy7ps= -github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s= -github.com/charmbracelet/lipgloss v0.10.0/go.mod h1:Wig9DSfvANsxqkRsqj6x87irdy123SR4dOXlKa91ciE= -github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM= -github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= -github.com/charmbracelet/x/input v0.1.0 h1:TEsGSfZYQyOtp+STIjyBq6tpRaorH0qpwZUj8DavAhQ= -github.com/charmbracelet/x/input v0.1.0/go.mod h1:ZZwaBxPF7IG8gWWzPUVqHEtWhc1+HXJPNuerJGRGZ28= -github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI= -github.com/charmbracelet/x/term v0.1.1/go.mod h1:wB1fHt5ECsu3mXYusyzcngVWWlu1KKUmmLhfgr/Flxw= -github.com/charmbracelet/x/windows v0.1.0 h1:gTaxdvzDM5oMa/I2ZNF7wN78X/atWemG9Wph7Ika2k4= -github.com/charmbracelet/x/windows v0.1.0/go.mod h1:GLEO/l+lizvFDBPLIOk+49gdX49L9YWMB5t+DZd0jkQ= github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM= github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY= github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= @@ -228,8 +194,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= -github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE= github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= @@ -265,8 +229,6 @@ github.com/envoyproxy/go-control-plane v0.13.0/go.mod h1:GRaKG3dwvFoTg4nj7aXdZnv github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM= github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4= -github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= -github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/fgprof v0.9.5 h1:8+vR6yu2vvSKn08urWyEuxx75NWPEvybbkBirEpsbVY= @@ -373,8 +335,6 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -423,8 +383,6 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.14.0 h1:f+jMrjBPl+DL9nI4IQzLUxMq7XrAqFYB7hBPqMNIe8o= github.com/googleapis/gax-go/v2 v2.14.0/go.mod h1:lhBCnjdLrWRaPvLWhmc8IS24m9mr07qSYnHncrgo+zk= -github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= -github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -454,8 +412,6 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= -github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= @@ -483,8 +439,6 @@ github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZ github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jedib0t/go-pretty v4.3.0+incompatible h1:CGs8AVhEKg/n9YbUenWmNStRW2PHJzaeDodcfvRAbIo= github.com/jedib0t/go-pretty v4.3.0+incompatible/go.mod h1:XemHduiw8R651AF9Pt4FwCTKeG3oo7hrHJAoznj9nag= -github.com/jedib0t/go-pretty/v6 v6.6.3 h1:nGqgS0tgIO1Hto47HSaaK4ac/I/Bu7usmdD3qvs0WvM= -github.com/jedib0t/go-pretty/v6 v6.6.3/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= github.com/jedib0t/go-pretty/v6 v6.6.4 h1:B51RjA+Sytv0C0Je7PHGDXZBF2JpS5dZEWWRueBLP6U= github.com/jedib0t/go-pretty/v6 v6.6.4/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= github.com/jlaffaye/ftp v0.2.0 h1:lXNvW7cBu7R/68bknOX3MrRIIqZ61zELs1P2RAiA3lg= @@ -529,10 +483,6 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+ github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lrstanley/bubblezone v0.0.0-20240125042004-b7bafc493195 h1:zcxmFnwisGZSaEzgvkOrs4belfcRlKyIUfa3sOQSttQ= -github.com/lrstanley/bubblezone v0.0.0-20240125042004-b7bafc493195/go.mod h1:v5lEwWaguF1o2MW/ucO0ZIA/IZymdBYJJ+2cMRLE7LU= -github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -545,16 +495,10 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= -github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mholt/archives v0.0.0-20241207175349-5e373c52f8aa h1:SzCiDuxF6489FegHHZe/ktxpRIDhu5IemNnWlW1Fquo= github.com/mholt/archives v0.0.0-20241207175349-5e373c52f8aa/go.mod h1:j/Ire/jm42GN7h90F5kzj6hf6ZFzEH66de+hmjEKu+I= -github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= -github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= github.com/microsoft/go-mssqldb v1.8.0 h1:7cyZ/AT7ycDsEoWPIXibd+aVKFtteUNhDGf3aobP+tw= github.com/microsoft/go-mssqldb v1.8.0/go.mod h1:6znkekS3T2vp0waiMhen4GPU1BiAsrP+iXHcE7a7rFo= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= @@ -581,14 +525,6 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= -github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= -github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= -github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= -github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= -github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= -github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= -github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= -github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= @@ -602,8 +538,6 @@ github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= @@ -655,7 +589,6 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw= github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o= -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.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -664,8 +597,6 @@ github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDN github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= -github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y= -github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/sassoftware/go-rpmutils v0.4.0 h1:ojND82NYBxgwrV+mX1CWsd5QJvvEZTKddtCdFLPWhpg= github.com/sassoftware/go-rpmutils v0.4.0/go.mod h1:3goNWi7PGAT3/dlql2lv3+MSN5jNYPjT5mVcQcIsYzI= github.com/schollz/progressbar/v3 v3.17.1 h1:bI1MTaoQO+v5kzklBjYNRQLoVpe0zbyRZNK6DFkVC5U= @@ -775,20 +706,13 @@ github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofm github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xo/dburl v0.23.2 h1:Fl88cvayrgE56JA/sqhNMLljCW/b7RmG1mMkKMZUFgA= github.com/xo/dburl v0.23.2/go.mod h1:uazlaAQxj4gkshhfuuYyvwCBouOmNnG2aDxTCFZpmL4= -github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= -github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.7/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/goldmark v1.5.4 h1:2uY/xC0roWy8IBEGLgB1ywIoEJFGmRrX21YQcvGZzjU= -github.com/yuin/goldmark v1.5.4/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/goldmark-emoji v1.0.2 h1:c/RgTShNgHTtc6xdz2KKI74jJr6rWi7FPgnP9GAsO5s= -github.com/yuin/goldmark-emoji v1.0.2/go.mod h1:RhP/RWpexdp+KHs7ghKnifRoIs/Bq4nDS7tRbCkOwKY= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= @@ -857,8 +781,6 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58 golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -869,10 +791,6 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d h1:0olWaB5pg3+oychR51GUVCEsGkeCU/2JxjBgIo4f3M0= -golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= -golang.org/x/exp v0.0.0-20241210172134-14434422244c h1:G0f8LmhCW7rzpybldgSjhhKDCwW7mYO0Qr6HZDb0HJA= -golang.org/x/exp v0.0.0-20241210172134-14434422244c/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/exp v0.0.0-20241210194714-1829a127f884 h1:Y/Mj/94zIQQGHVSv1tTtQBDaQaJe62U9bkDZKKyhPCU= golang.org/x/exp v0.0.0-20241210194714-1829a127f884/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -976,7 +894,6 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1074,8 +991,6 @@ google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.210.0 h1:HMNffZ57OoZCRYSbdWVRoqOa8V8NIHLL0CzdBPLztWk= -google.golang.org/api v0.210.0/go.mod h1:B9XDZGnx2NtyjzVkOVTGrFSAVZgPcbedzKg/gTLwqBs= google.golang.org/api v0.211.0 h1:IUpLjq09jxBSV1lACO33CGY3jsRcbctfGzhj+ZSE/Bg= google.golang.org/api v0.211.0/go.mod h1:XOloB4MXFH4UTlQSGuNUxw0UT74qdENK8d6JNsXKLi0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -1100,12 +1015,8 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk= google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc= -google.golang.org/genproto/googleapis/api v0.0.0-20241113202542-65e8d215514f h1:M65LEviCfuZTfrfzwwEoxVtgvfkFkBUbFnRbxCXuXhU= -google.golang.org/genproto/googleapis/api v0.0.0-20241113202542-65e8d215514f/go.mod h1:Yo94eF2nj7igQt+TiJ49KxjIH8ndLYPZMIRSiRcEbg0= google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 h1:pgr/4QbFyktUv9CtQ/Fq4gzEE6/Xs7iCXbktaGzLHbQ= google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697/go.mod h1:+D9ySVjN8nY8YCVjc5O7PZDIdZporIDY3KaGfJunh88= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 h1:LWZqQOEjDyONlF1H6afSWpAL/znlREo2tHfLoe+8LMA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= google.golang.org/genproto/googleapis/rpc v0.0.0-20241206012308-a4fef0638583 h1:IfdSdTcLFy4lqUQrQJLkLt1PB+AsqVz6lwkWPzWEz10= google.golang.org/genproto/googleapis/rpc v0.0.0-20241206012308-a4fef0638583/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= diff --git a/main.go b/main.go index f6558257256c..4110a013a542 100644 --- a/main.go +++ b/main.go @@ -19,7 +19,6 @@ import ( "github.com/felixge/fgprof" "github.com/go-logr/logr" "github.com/jpillora/overseer" - "github.com/mattn/go-isatty" "go.uber.org/automaxprocs/maxprocs" "github.com/trufflesecurity/trufflehog/v3/pkg/analyzer" @@ -34,7 +33,6 @@ import ( "github.com/trufflesecurity/trufflehog/v3/pkg/log" "github.com/trufflesecurity/trufflehog/v3/pkg/output" "github.com/trufflesecurity/trufflehog/v3/pkg/sources" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui" "github.com/trufflesecurity/trufflehog/v3/pkg/updater" "github.com/trufflesecurity/trufflehog/v3/pkg/version" ) @@ -244,7 +242,6 @@ var ( huggingfaceIncludePrs = huggingfaceScan.Flag("include-prs", "Include pull requests in scan.").Bool() analyzeCmd = analyzer.Command(cli) - usingTUI = false ) func init() { @@ -263,18 +260,6 @@ func init() { // Support -h for help cli.HelpFlag.Short('h') - if len(os.Args) <= 1 && isatty.IsTerminal(os.Stdout.Fd()) { - args := tui.Run() - if len(args) == 0 { - os.Exit(0) - } - - // Overwrite the Args slice so overseer works properly. - os.Args = os.Args[:1] - os.Args = append(os.Args, args...) - usingTUI = true - } - cmd = kingpin.MustParse(cli.Parse(os.Args[1:])) // Configure logging. @@ -328,7 +313,7 @@ func main() { if !*noUpdate { topLevelCmd, _, _ := strings.Cut(cmd, " ") - updateCfg.Fetcher = updater.Fetcher(topLevelCmd, usingTUI) + updateCfg.Fetcher = updater.Fetcher(topLevelCmd) } if version.BuildVersion == "dev" { updateCfg.Fetcher = nil diff --git a/pkg/analyzer/cli.go b/pkg/analyzer/cli.go index d3f8004e4a47..3765ebdd21ae 100644 --- a/pkg/analyzer/cli.go +++ b/pkg/analyzer/cli.go @@ -5,6 +5,7 @@ import ( "strings" "github.com/alecthomas/kingpin/v2" + "github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/analyzers" "github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/analyzers/airbrake" "github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/analyzers/asana" @@ -27,17 +28,22 @@ import ( "github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/analyzers/stripe" "github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/analyzers/twilio" "github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/config" - "github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/tui" ) var ( // TODO: Add list of supported key types. analyzeKeyType *string + analyzeKey *string + + showAll *bool + log *bool ) func Command(app *kingpin.Application) *kingpin.CmdClause { cli := app.Command("analyze", "Analyze API keys for fine-grained permissions information.") + showAll = cli.Flag("show-all", "Show all data, including permissions not available to this account + publicly-available data related to this account.").Default("false").Bool() + log = cli.Flag("log", "Log all HTTP requests sent during analysis to a file").Default("false").Bool() keyTypeHelp := fmt.Sprintf( "Type of key to analyze. Omit to interactively choose. Available key types: %s", strings.Join(analyzers.AvailableAnalyzers(), ", "), @@ -47,60 +53,62 @@ func Command(app *kingpin.Application) *kingpin.CmdClause { for i, a := range analyzers.AvailableAnalyzers() { availableAnalyzers[i] = strings.ToLower(a) } - analyzeKeyType = cli.Arg("key-type", keyTypeHelp).Enum(availableAnalyzers...) + analyzeKeyType = cli.Flag("type", keyTypeHelp).Enum(availableAnalyzers...) + analyzeKey = cli.Flag("key", "The key to analyze.").String() return cli } func Run(cmd string) { - keyType, secretInfo, err := tui.Run(*analyzeKeyType) - if err != nil { - // TODO: Log error. - return + // Initialize configuration + cfg := &config.Config{ + LoggingEnabled: *log, + ShowAll: *showAll, } - if secretInfo.Cfg == nil { - secretInfo.Cfg = &config.Config{} - } - switch strings.ToLower(keyType) { + + key := *analyzeKey + switch strings.ToLower(*analyzeKeyType) { case "github": - github.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + github.AnalyzeAndPrintPermissions(cfg, key) case "sendgrid": - sendgrid.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + sendgrid.AnalyzeAndPrintPermissions(cfg, key) case "openai": - openai.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + openai.AnalyzeAndPrintPermissions(cfg, key) case "postgres": - postgres.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + postgres.AnalyzeAndPrintPermissions(cfg, key) case "mysql": - mysql.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + mysql.AnalyzeAndPrintPermissions(cfg, key) case "slack": - slack.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + slack.AnalyzeAndPrintPermissions(cfg, key) case "twilio": - twilio.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["sid"], secretInfo.Parts["key"]) + parts := strings.SplitN(key, ":", 2) + twilio.AnalyzeAndPrintPermissions(cfg, parts[0], parts[1]) case "airbrake": - airbrake.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + airbrake.AnalyzeAndPrintPermissions(cfg, key) case "huggingface": - huggingface.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + huggingface.AnalyzeAndPrintPermissions(cfg, key) case "stripe": - stripe.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + stripe.AnalyzeAndPrintPermissions(cfg, key) case "gitlab": - gitlab.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + gitlab.AnalyzeAndPrintPermissions(cfg, key) case "mailchimp": - mailchimp.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + mailchimp.AnalyzeAndPrintPermissions(cfg, key) case "postman": - postman.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + postman.AnalyzeAndPrintPermissions(cfg, key) case "bitbucket": - bitbucket.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + bitbucket.AnalyzeAndPrintPermissions(cfg, key) case "asana": - asana.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + asana.AnalyzeAndPrintPermissions(cfg, key) case "mailgun": - mailgun.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + mailgun.AnalyzeAndPrintPermissions(cfg, key) case "square": - square.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + square.AnalyzeAndPrintPermissions(cfg, key) case "sourcegraph": - sourcegraph.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + sourcegraph.AnalyzeAndPrintPermissions(cfg, key) case "shopify": - shopify.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"], secretInfo.Parts["url"]) + parts := strings.SplitN(key, ":", 2) + shopify.AnalyzeAndPrintPermissions(cfg, parts[0], parts[1]) case "opsgenie": - opsgenie.AnalyzeAndPrintPermissions(secretInfo.Cfg, secretInfo.Parts["key"]) + opsgenie.AnalyzeAndPrintPermissions(cfg, key) } } diff --git a/pkg/analyzer/tui/form.go b/pkg/analyzer/tui/form.go deleted file mode 100644 index d335e5c19b8e..000000000000 --- a/pkg/analyzer/tui/form.go +++ /dev/null @@ -1,122 +0,0 @@ -package tui - -import ( - "fmt" - "slices" - "strings" - - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/analyzers" - "github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/config" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/styles" -) - -type FormPage struct { - Common *common.Common - KeyType string - form textinputs.Model -} - -func NewFormPage(c *common.Common, keyType string) FormPage { - var inputs []textinputs.InputConfig - switch strings.ToLower(keyType) { - case "twilio": - inputs = []textinputs.InputConfig{{ - Label: "SID", - Key: "sid", - Required: true, - }, { - Label: "Token", - Key: "key", - Required: true, - RedactInput: true, - }} - case "shopify": - inputs = []textinputs.InputConfig{{ - Label: "Secret", - Key: "key", - Required: true, - RedactInput: true, - }, { - Label: "Shopify URL", - Key: "url", - Required: true, - }} - default: - inputs = []textinputs.InputConfig{{ - Label: "Secret", - Key: "key", - Required: true, - RedactInput: true, - }} - } - - // Always append a log file option. - inputs = append(inputs, textinputs.InputConfig{ - Label: "Log file", - Help: "Log HTTP requests that analysis performs to this file", - Key: "log_file", - }) - - form := textinputs.New(inputs). - SetHeader(titleStyle.Render(fmt.Sprintf("Configuring %s analyzer", keyType))). - SetFooter("āš ļø Running TruffleHog Analyze will send a lot of requests āš ļø\n\nšŸš§ Please confirm you have permission to run TruffleHog Analyze against this secret šŸš§"). - SetSubmitMsg("Run TruffleHog Analyze") - return FormPage{ - Common: c, - KeyType: keyType, - form: form, - } -} - -func (FormPage) Init() tea.Cmd { - return nil -} - -func (ui FormPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - // TODO: Check form focus. - if msg, ok := msg.(tea.KeyMsg); ok { - switch { - case key.Matches(msg, ui.Common.KeyMap.Back): - return ui.PrevPage() - } - } - if _, ok := msg.(textinputs.SelectNextMsg); ok { - values := make(map[string]string) - for k, v := range ui.form.GetInputs() { - values[k] = v.Value - } - secretInfoCmd := func() tea.Msg { - // TODO: Set Config - logFile := values["log_file"] - cfg := config.Config{ - LogFile: logFile, - LoggingEnabled: logFile != "", - } - return SecretInfo{Cfg: &cfg, Parts: values} - } - return nil, secretInfoCmd - } - form, cmd := ui.form.Update(msg) - ui.form = form.(textinputs.Model) - return ui, cmd -} - -func (ui FormPage) View() string { - return styles.AppStyle.Render(ui.form.View()) -} - -func (ui FormPage) PrevPage() (tea.Model, tea.Cmd) { - page := NewKeyTypePage(ui.Common) - // Select what was previously selected. - index, ok := slices.BinarySearch(analyzers.AvailableAnalyzers(), ui.KeyType) - if !ok { - // Should be impossible. - index = 0 - } - page.list.Select(index) - return page, nil -} diff --git a/pkg/analyzer/tui/keytype.go b/pkg/analyzer/tui/keytype.go deleted file mode 100644 index 485df873496d..000000000000 --- a/pkg/analyzer/tui/keytype.go +++ /dev/null @@ -1,96 +0,0 @@ -package tui - -import ( - "github.com/charmbracelet/bubbles/key" - "github.com/charmbracelet/bubbles/list" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/analyzers" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/styles" -) - -var ( - selectedItemStyle = lipgloss.NewStyle(). - Border(lipgloss.NormalBorder(), false, false, false, true). - BorderForeground(lipgloss.AdaptiveColor{Dark: styles.Colors["sprout"], Light: styles.Colors["bronze"]}). - Foreground(lipgloss.AdaptiveColor{Dark: styles.Colors["sprout"], Light: styles.Colors["fern"]}). - Padding(0, 0, 0, 1) - - titleStyle = lipgloss.NewStyle(). - Foreground(lipgloss.Color("#FFFDF5")). - Background(lipgloss.Color(styles.Colors["bronze"])). - Padding(0, 1) -) - -type KeyTypePage struct { - Common *common.Common - - list list.Model -} - -func (ui KeyTypePage) Init() tea.Cmd { - return nil -} - -func NewKeyTypePage(c *common.Common) KeyTypePage { - items := make([]list.Item, len(analyzers.AvailableAnalyzers())) - for i, analyzerType := range analyzers.AvailableAnalyzers() { - items[i] = KeyTypeItem(analyzerType) - } - delegate := list.NewDefaultDelegate() - delegate.ShowDescription = false - delegate.SetSpacing(0) - delegate.Styles.SelectedTitle = selectedItemStyle - - list := list.New(items, delegate, c.Width, c.Height) - list.Title = "Select an analyzer type" - list.SetShowStatusBar(false) - list.Styles.Title = titleStyle - return KeyTypePage{ - Common: c, - list: list, - } -} - -func (ui KeyTypePage) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - if !ui.list.SettingFilter() { - switch msg := msg.(type) { - case tea.KeyMsg: - switch { - case key.Matches(msg, ui.Common.KeyMap.Back): - return nil, tea.Quit - case key.Matches(msg, ui.Common.KeyMap.Select): - chosen := string(ui.list.SelectedItem().(KeyTypeItem)) - return NewFormPage(ui.Common, chosen), SetKeyTypeCmd(chosen) - } - } - } - - var cmd tea.Cmd - ui.list, cmd = ui.list.Update(msg) - return ui, cmd -} - -func (ui KeyTypePage) View() string { - return styles.AppStyle.Render(ui.list.View()) -} - -func (ui KeyTypePage) NextPage(keyType string) (tea.Model, tea.Cmd) { - return NewFormPage(ui.Common, keyType), SetKeyTypeCmd(keyType) -} - -type KeyTypeItem string - -func (i KeyTypeItem) ID() string { return string(i) } -func (i KeyTypeItem) Title() string { return string(i) } -func (i KeyTypeItem) Description() string { return "" } -func (i KeyTypeItem) FilterValue() string { return string(i) } - -func init() { - // Preload HasDarkBackground call. For some reason, if we don't do - // this, the TUI can take a noticeably long time to start. We should - // investigate further, but this is a good-enough bandaid for now. - // See: https://github.com/charmbracelet/lipgloss/issues/73 - _ = lipgloss.HasDarkBackground() -} diff --git a/pkg/analyzer/tui/tui.go b/pkg/analyzer/tui/tui.go deleted file mode 100644 index 66954124b14d..000000000000 --- a/pkg/analyzer/tui/tui.go +++ /dev/null @@ -1,122 +0,0 @@ -package tui - -import ( - "errors" - "fmt" - "strings" - - tea "github.com/charmbracelet/bubbletea" - "github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/analyzers" - "github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/config" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/keymap" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/styles" -) - -// TUI is the main TUI model. -type TUI struct { - keyType string - secretInfo *SecretInfo - common *common.Common - model tea.Model -} - -type SecretInfo struct { - Parts map[string]string - Cfg *config.Config -} - -var AbortError error = errors.New("command aborted") - -func Run(keyType string) (string, *SecretInfo, error) { - // If a keyType is provided, make sure it's in the list of AvailableAnalyzers. - if keyType != "" { - var found bool - for _, a := range analyzers.AvailableAnalyzers() { - if strings.EqualFold(a, keyType) { - keyType = a - found = true - break - } - } - if !found { - return "", nil, fmt.Errorf("Unrecognized command %q", keyType) - } - } - - t := &TUI{ - keyType: keyType, - common: &common.Common{ - KeyMap: keymap.DefaultKeyMap(), - }, - } - if _, err := tea.NewProgram(t).Run(); err != nil { - return "", nil, err - } - if t.secretInfo == nil { - return "", nil, AbortError - } - return t.keyType, t.secretInfo, nil -} - -func (ui *TUI) Init() tea.Cmd { - return nil -} - -func (ui *TUI) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - if msg, ok := msg.(tea.WindowSizeMsg); ok { - ui.SetSize(msg) - } - // Always be able to force quit. - if msg, ok := msg.(tea.KeyMsg); ok && msg.Type.String() == "ctrl+c" { - return ui, tea.Quit - } - - switch m := msg.(type) { - case SetKeyTypeMsg: - ui.keyType = string(m) - case SecretInfo: - ui.secretInfo = &m - return ui, tea.Quit - } - - if ui.model == nil { - return ui, nil - } - - var cmd tea.Cmd - ui.model, cmd = ui.model.Update(msg) - return ui, cmd -} - -func (ui *TUI) View() string { - if ui.model == nil { - return "Loading..." - } - return ui.model.View() -} - -func (ui *TUI) SetSize(msg tea.WindowSizeMsg) { - h, v := styles.AppStyle.GetFrameSize() - h, v = msg.Width-h, msg.Height-v - ui.common.SetSize(h, v) - if ui.model != nil { - return - } - - // Set the model only after we have size information. - // TODO: Responsive pages. - if ui.keyType == "" { - ui.model = NewKeyTypePage(ui.common) - } else { - ui.model = NewFormPage(ui.common, ui.keyType) - } -} - -type SetKeyTypeMsg string - -func SetKeyTypeCmd(keyType string) tea.Cmd { - return func() tea.Msg { - return SetKeyTypeMsg(keyType) - } -} diff --git a/pkg/tui/common/common.go b/pkg/tui/common/common.go deleted file mode 100644 index 9b8cf4a996f9..000000000000 --- a/pkg/tui/common/common.go +++ /dev/null @@ -1,24 +0,0 @@ -package common - -import ( - "github.com/aymanbagabas/go-osc52" - zone "github.com/lrstanley/bubblezone" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/keymap" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/styles" -) - -// Common is a struct all components should embed. -type Common struct { - Copy *osc52.Output - Styles *styles.Styles - KeyMap *keymap.KeyMap - Width int - Height int - Zone *zone.Manager -} - -// SetSize sets the width and height of the common struct. -func (c *Common) SetSize(width, height int) { - c.Width = width - c.Height = height -} diff --git a/pkg/tui/common/component.go b/pkg/tui/common/component.go deleted file mode 100644 index ed8b9bf05cd3..000000000000 --- a/pkg/tui/common/component.go +++ /dev/null @@ -1,13 +0,0 @@ -package common - -import ( - "github.com/charmbracelet/bubbles/help" - tea "github.com/charmbracelet/bubbletea" -) - -// Component represents a Bubble Tea model that implements a SetSize function. -type Component interface { - tea.Model - help.KeyMap - SetSize(width, height int) -} diff --git a/pkg/tui/common/error.go b/pkg/tui/common/error.go deleted file mode 100644 index fe9729805622..000000000000 --- a/pkg/tui/common/error.go +++ /dev/null @@ -1,13 +0,0 @@ -package common - -import tea "github.com/charmbracelet/bubbletea" - -// ErrorMsg is a Bubble Tea message that represents an error. -type ErrorMsg error - -// ErrorCmd returns an ErrorMsg from error. -func ErrorCmd(err error) tea.Cmd { - return func() tea.Msg { - return ErrorMsg(err) - } -} diff --git a/pkg/tui/common/style.go b/pkg/tui/common/style.go deleted file mode 100644 index 8b91d9afa08d..000000000000 --- a/pkg/tui/common/style.go +++ /dev/null @@ -1,27 +0,0 @@ -package common - -import ( - "github.com/charmbracelet/glamour" - gansi "github.com/charmbracelet/glamour/ansi" -) - -func strptr(s string) *string { - return &s -} - -// StyleConfig returns the default Glamour style configuration. -func StyleConfig() gansi.StyleConfig { - noColor := strptr("") - s := glamour.DarkStyleConfig - s.H1.BackgroundColor = noColor - s.H1.Prefix = "# " - s.H1.Suffix = "" - s.H1.Color = strptr("39") - s.Document.StylePrimitive.Color = noColor - s.CodeBlock.Chroma.Text.Color = noColor - s.CodeBlock.Chroma.Name.Color = noColor - // This fixes an issue with the default style config. For example - // highlighting empty spaces with red in Dockerfile type. - s.CodeBlock.Chroma.Error.BackgroundColor = noColor - return s -} diff --git a/pkg/tui/common/utils.go b/pkg/tui/common/utils.go deleted file mode 100644 index 2d7e15d3f1c8..000000000000 --- a/pkg/tui/common/utils.go +++ /dev/null @@ -1,28 +0,0 @@ -package common - -import ( - "strings" - - "github.com/muesli/reflow/truncate" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" -) - -// TruncateString is a convenient wrapper around truncate.TruncateString. -func TruncateString(s string, max int) string { - if max < 0 { - max = 0 - } - return truncate.StringWithTail(s, uint(max), "ā€¦") -} - -func SummarizeSource(keys []string, inputs map[string]textinputs.Input, labels map[string]string) string { - summary := strings.Builder{} - for _, key := range keys { - if inputs[key].Value != "" { - summary.WriteString("\t" + labels[key] + ": " + inputs[key].Value + "\n") - } - } - - summary.WriteString("\n") - return summary.String() -} diff --git a/pkg/tui/components/confirm/confirm.go b/pkg/tui/components/confirm/confirm.go deleted file mode 100644 index 0ca4069697f7..000000000000 --- a/pkg/tui/components/confirm/confirm.go +++ /dev/null @@ -1,115 +0,0 @@ -package confirm - -import ( - "fmt" - "unicode" - - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" -) - -type Confirm struct { - common common.Common - message string - affirmativeChoice string - negativeChoice string - affirmativeUpdate func() (tea.Model, tea.Cmd) - negativeUpdate func() (tea.Model, tea.Cmd) - choice bool -} - -type Msg struct { - Choice bool - Message string -} - -type ConfirmOpt func(*Confirm) - -func WithAffirmativeMessage(msg string) ConfirmOpt { - return func(c *Confirm) { c.affirmativeChoice = msg } -} - -func WithNegativeMessage(msg string) ConfirmOpt { - return func(c *Confirm) { c.negativeChoice = msg } -} - -func WithDefault(choice bool) ConfirmOpt { - return func(c *Confirm) { c.choice = choice } -} - -func WithAffirmativeTransition(m tea.Model, cmd tea.Cmd) ConfirmOpt { - return func(c *Confirm) { - c.affirmativeUpdate = func() (tea.Model, tea.Cmd) { - return m, cmd - } - } -} - -func WithNegativeTransition(m tea.Model, cmd tea.Cmd) ConfirmOpt { - return func(c *Confirm) { - c.negativeUpdate = func() (tea.Model, tea.Cmd) { - return m, cmd - } - } -} - -func New(c common.Common, msg string, opts ...ConfirmOpt) Confirm { - confirm := Confirm{ - common: c, - message: msg, - affirmativeChoice: "Yes", - negativeChoice: "Cancel", - affirmativeUpdate: func() (tea.Model, tea.Cmd) { return nil, nil }, - negativeUpdate: func() (tea.Model, tea.Cmd) { return nil, nil }, - } - for _, opt := range opts { - opt(&confirm) - } - return confirm -} - -func (Confirm) Init() tea.Cmd { - return nil -} - -func (c Confirm) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - keyMsg, ok := msg.(tea.KeyMsg) - if !ok { - return c, nil - } - switch { - case key.Matches(keyMsg, c.common.KeyMap.Left) || keyMatchesFirstChar(keyMsg, c.negativeChoice): - c.choice = false - case key.Matches(keyMsg, c.common.KeyMap.Right) || keyMatchesFirstChar(keyMsg, c.affirmativeChoice): - c.choice = true - case key.Matches(keyMsg, c.common.KeyMap.Select): - model, cmd := c.negativeUpdate() - if c.choice { - model, cmd = c.affirmativeUpdate() - } - - return model, cmd - } - return c, nil -} - -func (c Confirm) View() string { - var affirmative, negative string - if c.choice { - affirmative = fmt.Sprintf("[ %s ]", c.affirmativeChoice) - negative = fmt.Sprintf(" %s ", c.negativeChoice) - } else { - affirmative = fmt.Sprintf(" %s ", c.affirmativeChoice) - negative = fmt.Sprintf("[ %s ]", c.negativeChoice) - } - return fmt.Sprintf("%s\t%s\t%s", c.message, negative, affirmative) -} - -func keyMatchesFirstChar(msg tea.KeyMsg, s string) bool { - if s == "" { - return false - } - firstChar := rune(s[0]) - return msg.String() == string(unicode.ToLower(firstChar)) -} diff --git a/pkg/tui/components/footer/footer.go b/pkg/tui/components/footer/footer.go deleted file mode 100644 index 68ca0842edee..000000000000 --- a/pkg/tui/components/footer/footer.go +++ /dev/null @@ -1,96 +0,0 @@ -package footer - -import ( - "github.com/charmbracelet/bubbles/help" - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" -) - -// ToggleFooterMsg is a message sent to show/hide the footer. -type ToggleFooterMsg struct{} - -// Footer is a Bubble Tea model that displays help and other info. -type Footer struct { - common common.Common - help help.Model - keymap help.KeyMap -} - -// New creates a new Footer. -func New(c common.Common, keymap help.KeyMap) *Footer { - h := help.New() - h.Styles.ShortKey = c.Styles.HelpKey - h.Styles.ShortDesc = c.Styles.HelpValue - h.Styles.FullKey = c.Styles.HelpKey - h.Styles.FullDesc = c.Styles.HelpValue - f := &Footer{ - common: c, - help: h, - keymap: keymap, - } - f.SetSize(c.Width, c.Height) - return f -} - -// SetSize implements common.Component. -func (f *Footer) SetSize(width, height int) { - f.common.SetSize(width, height) - f.help.Width = width - - f.common.Styles.Footer.GetHorizontalFrameSize() -} - -// Init implements tea.Model. -func (f *Footer) Init() tea.Cmd { - return nil -} - -// Update implements tea.Model. -func (f *Footer) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - return f, nil -} - -// View implements tea.Model. -func (f *Footer) View() string { - if f.keymap == nil { - return "" - } - s := f.common.Styles.Footer.Copy(). - Width(f.common.Width) - helpView := f.help.View(f.keymap) - return f.common.Zone.Mark( - "footer", - s.Render(helpView), - ) -} - -// ShortHelp returns the short help key bindings. -func (f *Footer) ShortHelp() []key.Binding { - return f.keymap.ShortHelp() -} - -// FullHelp returns the full help key bindings. -func (f *Footer) FullHelp() [][]key.Binding { - return f.keymap.FullHelp() -} - -// ShowAll returns whether the full help is shown. -func (f *Footer) ShowAll() bool { - return f.help.ShowAll -} - -// SetShowAll sets whether the full help is shown. -func (f *Footer) SetShowAll(show bool) { - f.help.ShowAll = show -} - -// Height returns the height of the footer. -func (f *Footer) Height() int { - return lipgloss.Height(f.View()) -} - -// ToggleFooterCmd sends a ToggleFooterMsg to show/hide the help footer. -func ToggleFooterCmd() tea.Msg { - return ToggleFooterMsg{} -} diff --git a/pkg/tui/components/formfield/formfield.go b/pkg/tui/components/formfield/formfield.go deleted file mode 100644 index ab00749fcd80..000000000000 --- a/pkg/tui/components/formfield/formfield.go +++ /dev/null @@ -1,38 +0,0 @@ -package formfield - -import ( - "strings" - - tea "github.com/charmbracelet/bubbletea" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/styles" -) - -type FormField struct { - Label string - Required bool - Help string - Component tea.Model -} - -func NewFormField(common common.Common) *FormField { - return &FormField{} -} - -func (field *FormField) ViewLabel() string { - var label strings.Builder - if field.Required { - label.WriteString(styles.BoldTextStyle.Render(field.Label) + "*\n") - } else { - label.WriteString(styles.BoldTextStyle.Render(field.Label) + "\n") - } - - return label.String() -} - -func (field *FormField) ViewHelp() string { - var help strings.Builder - help.WriteString(styles.HintTextStyle.Render(field.Help) + "\n") - - return help.String() -} diff --git a/pkg/tui/components/header/header.go b/pkg/tui/components/header/header.go deleted file mode 100644 index f83c191ad3a7..000000000000 --- a/pkg/tui/components/header/header.go +++ /dev/null @@ -1,42 +0,0 @@ -package header - -import ( - "strings" - - tea "github.com/charmbracelet/bubbletea" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" -) - -// Header represents a header component. -type Header struct { - common common.Common - text string -} - -// New creates a new header component. -func New(c common.Common, text string) *Header { - return &Header{ - common: c, - text: text, - } -} - -// SetSize implements common.Component. -func (h *Header) SetSize(width, height int) { - h.common.SetSize(width, height) -} - -// Init implements tea.Model. -func (h *Header) Init() tea.Cmd { - return nil -} - -// Update implements tea.Model. -func (h *Header) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - return h, nil -} - -// View implements tea.Model. -func (h *Header) View() string { - return h.common.Styles.ServerName.Render(strings.TrimSpace(h.text)) -} diff --git a/pkg/tui/components/selector/selector.go b/pkg/tui/components/selector/selector.go deleted file mode 100644 index 3b1b2ebb08e0..000000000000 --- a/pkg/tui/components/selector/selector.go +++ /dev/null @@ -1,216 +0,0 @@ -package selector - -import ( - "github.com/charmbracelet/bubbles/key" - "github.com/charmbracelet/bubbles/list" - tea "github.com/charmbracelet/bubbletea" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" -) - -// Selector is a list of items that can be selected. -type Selector struct { - list.Model - common common.Common - active int - filterState list.FilterState -} - -// IdentifiableItem is an item that can be identified by a string. Implements -// list.DefaultItem. -type IdentifiableItem interface { - list.DefaultItem - ID() string -} - -// ItemDelegate is a wrapper around list.ItemDelegate. -type ItemDelegate interface { - list.ItemDelegate -} - -// SelectMsg is a message that is sent when an item is selected. -type SelectMsg struct{ IdentifiableItem } - -// ActiveMsg is a message that is sent when an item is active but not selected. -type ActiveMsg struct{ IdentifiableItem } - -// New creates a new selector. -func New(common common.Common, items []IdentifiableItem, delegate ItemDelegate) *Selector { - itms := make([]list.Item, len(items)) - for i, item := range items { - itms[i] = item - } - l := list.New(itms, delegate, common.Width, common.Height) - s := &Selector{ - Model: l, - common: common, - } - s.SetSize(common.Width, common.Height) - return s -} - -// PerPage returns the number of items per page. -func (s *Selector) PerPage() int { - return s.Model.Paginator.PerPage -} - -// SetPage sets the current page. -func (s *Selector) SetPage(page int) { - s.Model.Paginator.Page = page -} - -// Page returns the current page. -func (s *Selector) Page() int { - return s.Model.Paginator.Page -} - -// TotalPages returns the total number of pages. -func (s *Selector) TotalPages() int { - return s.Model.Paginator.TotalPages -} - -// Select selects the item at the given index. -func (s *Selector) Select(index int) { - s.Model.Select(index) -} - -// SetShowTitle sets the show title flag. -func (s *Selector) SetShowTitle(show bool) { - s.Model.SetShowTitle(show) -} - -// SetShowHelp sets the show help flag. -func (s *Selector) SetShowHelp(show bool) { - s.Model.SetShowHelp(show) -} - -// SetShowStatusBar sets the show status bar flag. -func (s *Selector) SetShowStatusBar(show bool) { - s.Model.SetShowStatusBar(show) -} - -// DisableQuitKeybindings disables the quit keybindings. -func (s *Selector) DisableQuitKeybindings() { - s.Model.DisableQuitKeybindings() -} - -// SetShowFilter sets the show filter flag. -func (s *Selector) SetShowFilter(show bool) { - s.Model.SetShowFilter(show) -} - -// SetShowPagination sets the show pagination flag. -func (s *Selector) SetShowPagination(show bool) { - s.Model.SetShowPagination(show) -} - -// SetFilteringEnabled sets the filtering enabled flag. -func (s *Selector) SetFilteringEnabled(enabled bool) { - s.Model.SetFilteringEnabled(enabled) -} - -// SetSize implements common.Component. -func (s *Selector) SetSize(width, height int) { - s.common.SetSize(width, height) - s.Model.SetSize(width, height) -} - -// SetItems sets the items in the selector. -func (s *Selector) SetItems(items []IdentifiableItem) tea.Cmd { - its := make([]list.Item, len(items)) - for i, item := range items { - its[i] = item - } - return s.Model.SetItems(its) -} - -// Index returns the index of the selected item. -func (s *Selector) Index() int { - return s.Model.Index() -} - -// Init implements tea.Model. -func (s *Selector) Init() tea.Cmd { - return s.activeCmd -} - -// Update implements tea.Model. -func (s *Selector) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - cmds := make([]tea.Cmd, 0) - switch msg := msg.(type) { - case tea.KeyMsg: - filterState := s.Model.FilterState() - switch { - case key.Matches(msg, s.common.KeyMap.Help): - if filterState == list.Filtering { - return s, tea.Batch(cmds...) - } - case key.Matches(msg, s.common.KeyMap.Select): - if filterState != list.Filtering { - cmds = append(cmds, s.selectCmd) - } - } - case list.FilterMatchesMsg: - cmds = append(cmds, s.activeFilterCmd) - } - m, cmd := s.Model.Update(msg) - s.Model = m - if cmd != nil { - cmds = append(cmds, cmd) - } - // Track filter state and update active item when filter state changes. - filterState := s.Model.FilterState() - if s.filterState != filterState { - cmds = append(cmds, s.activeFilterCmd) - } - s.filterState = filterState - // Send ActiveMsg when index change. - if s.active != s.Model.Index() { - cmds = append(cmds, s.activeCmd) - } - s.active = s.Model.Index() - return s, tea.Batch(cmds...) -} - -// View implements tea.Model. -func (s *Selector) View() string { - return s.Model.View() -} - -// SelectItem is a command that selects the currently active item. -func (s *Selector) SelectItem() tea.Msg { - return s.selectCmd() -} - -func (s *Selector) selectCmd() tea.Msg { - item := s.Model.SelectedItem() - i, ok := item.(IdentifiableItem) - if !ok { - return SelectMsg{} - } - return SelectMsg{i} -} - -func (s *Selector) activeCmd() tea.Msg { - item := s.Model.SelectedItem() - i, ok := item.(IdentifiableItem) - if !ok { - return ActiveMsg{} - } - return ActiveMsg{i} -} - -func (s *Selector) activeFilterCmd() tea.Msg { - // Here we use VisibleItems because when list.FilterMatchesMsg is sent, - // VisibleItems is the only way to get the list of filtered items. The list - // bubble should export something like list.FilterMatchesMsg.Items(). - items := s.Model.VisibleItems() - if len(items) == 0 { - return nil - } - item := items[0] - i, ok := item.(IdentifiableItem) - if !ok { - return nil - } - return ActiveMsg{i} -} diff --git a/pkg/tui/components/statusbar/statusbar.go b/pkg/tui/components/statusbar/statusbar.go deleted file mode 100644 index a486784bf98f..000000000000 --- a/pkg/tui/components/statusbar/statusbar.go +++ /dev/null @@ -1,88 +0,0 @@ -package statusbar - -import ( - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/muesli/reflow/truncate" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" -) - -// StatusBarMsg is a message sent to the status bar. -type StatusBarMsg struct { - Key string - Value string - Info string - Branch string -} - -// StatusBar is a status bar model. -type StatusBar struct { - common common.Common - msg StatusBarMsg -} - -// Model is an interface that supports setting the status bar information. -type Model interface { - StatusBarValue() string - StatusBarInfo() string -} - -// New creates a new status bar component. -func New(c common.Common) *StatusBar { - s := &StatusBar{ - common: c, - } - return s -} - -// SetSize implements common.Component. -func (s *StatusBar) SetSize(width, height int) { - s.common.Width = width - s.common.Height = height -} - -// Init implements tea.Model. -func (s *StatusBar) Init() tea.Cmd { - return nil -} - -// Update implements tea.Model. -func (s *StatusBar) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - switch msg := msg.(type) { - case StatusBarMsg: - s.msg = msg - } - return s, nil -} - -// View implements tea.Model. -func (s *StatusBar) View() string { - st := s.common.Styles - w := lipgloss.Width - help := s.common.Zone.Mark( - "repo-help", - st.StatusBarHelp.Render("? Help"), - ) - key := st.StatusBarKey.Render(s.msg.Key) - info := "" - if s.msg.Info != "" { - info = st.StatusBarInfo.Render(s.msg.Info) - } - branch := st.StatusBarBranch.Render(s.msg.Branch) - maxWidth := s.common.Width - w(key) - w(info) - w(branch) - w(help) - v := truncate.StringWithTail(s.msg.Value, uint(maxWidth-st.StatusBarValue.GetHorizontalFrameSize()), "ā€¦") - value := st.StatusBarValue. - Width(maxWidth). - Render(v) - - return lipgloss.NewStyle().MaxWidth(s.common.Width). - Render( - lipgloss.JoinHorizontal(lipgloss.Top, - key, - value, - info, - branch, - help, - ), - ) -} diff --git a/pkg/tui/components/tabs/tabs.go b/pkg/tui/components/tabs/tabs.go deleted file mode 100644 index 6ab13e23b3be..000000000000 --- a/pkg/tui/components/tabs/tabs.go +++ /dev/null @@ -1,113 +0,0 @@ -package tabs - -import ( - "strings" - - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" -) - -// SelectTabMsg is a message that contains the index of the tab to select. -type SelectTabMsg int - -// ActiveTabMsg is a message that contains the index of the current active tab. -type ActiveTabMsg int - -// Tabs is bubbletea component that displays a list of tabs. -type Tabs struct { - common common.Common - tabs []string - activeTab int - TabSeparator lipgloss.Style - TabInactive lipgloss.Style - TabActive lipgloss.Style - TabDot lipgloss.Style - UseDot bool -} - -// New creates a new Tabs component. -func New(c common.Common, tabs []string) *Tabs { - r := &Tabs{ - common: c, - tabs: tabs, - activeTab: 0, - TabSeparator: c.Styles.TabSeparator, - TabInactive: c.Styles.TabInactive, - TabActive: c.Styles.TabActive, - } - return r -} - -// SetSize implements common.Component. -func (t *Tabs) SetSize(width, height int) { - t.common.SetSize(width, height) -} - -// Init implements tea.Model. -func (t *Tabs) Init() tea.Cmd { - t.activeTab = 0 - return nil -} - -// Update implements tea.Model. -func (t *Tabs) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - cmds := make([]tea.Cmd, 0) - switch msg := msg.(type) { - case tea.KeyMsg: - switch msg.String() { - case "tab": - t.activeTab = (t.activeTab + 1) % len(t.tabs) - cmds = append(cmds, t.activeTabCmd) - case "shift+tab": - t.activeTab = (t.activeTab - 1 + len(t.tabs)) % len(t.tabs) - cmds = append(cmds, t.activeTabCmd) - } - case SelectTabMsg: - tab := int(msg) - if tab >= 0 && tab < len(t.tabs) { - t.activeTab = int(msg) - } - } - return t, tea.Batch(cmds...) -} - -// View implements tea.Model. -func (t *Tabs) View() string { - s := strings.Builder{} - sep := t.TabSeparator - for i, tab := range t.tabs { - style := t.TabInactive.Copy() - prefix := " " - if i == t.activeTab { - style = t.TabActive.Copy() - prefix = t.TabDot.Render("ā€¢ ") - } - if t.UseDot { - s.WriteString(prefix) - } - s.WriteString( - t.common.Zone.Mark( - tab, - style.Render(tab), - ), - ) - if i != len(t.tabs)-1 { - s.WriteString(sep.String()) - } - } - return lipgloss.NewStyle(). - MaxWidth(t.common.Width). - Render(s.String()) -} - -func (t *Tabs) activeTabCmd() tea.Msg { - return ActiveTabMsg(t.activeTab) -} - -// SelectTabCmd is a bubbletea command that selects the tab at the given index. -func SelectTabCmd(tab int) tea.Cmd { - return func() tea.Msg { - return SelectTabMsg(tab) - } -} diff --git a/pkg/tui/components/textinput/textinput.go b/pkg/tui/components/textinput/textinput.go deleted file mode 100644 index 14a1675cac08..000000000000 --- a/pkg/tui/components/textinput/textinput.go +++ /dev/null @@ -1,51 +0,0 @@ -package textinput - -import ( - "github.com/charmbracelet/bubbles/textinput" - tea "github.com/charmbracelet/bubbletea" -) - -type ( - errMsg error -) - -type TextInput struct { - textInput textinput.Model - err error -} - -func New(placeholder string) TextInput { - ti := textinput.New() - ti.Placeholder = placeholder - ti.Focus() - ti.CharLimit = 156 - ti.Width = 60 - - return TextInput{ - textInput: ti, - err: nil, - } -} - -func (m TextInput) Init() tea.Cmd { - return textinput.Blink -} - -func (m TextInput) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - var cmd tea.Cmd - - switch msg := msg.(type) { - - // We handle errors just like any other message - case errMsg: - m.err = msg - return m, nil - } - - m.textInput, cmd = m.textInput.Update(msg) - return m, cmd -} - -func (m TextInput) View() string { - return m.textInput.View() -} diff --git a/pkg/tui/components/textinputs/textinputs.go b/pkg/tui/components/textinputs/textinputs.go deleted file mode 100644 index 3b53bd9d111f..000000000000 --- a/pkg/tui/components/textinputs/textinputs.go +++ /dev/null @@ -1,276 +0,0 @@ -package textinputs - -// from https://github.com/charmbracelet/bubbletea/blob/master/examples/textinputs/main.go - -import ( - "fmt" - "strings" - - "github.com/charmbracelet/bubbles/textinput" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" -) - -var ( - focusedStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("205")) - blurredStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("240")) - noStyle = lipgloss.NewStyle() - helpStyle = blurredStyle.Copy() - // cursorStyle = focusedStyle.Copy() - // cursorModeHelpStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("244")) - - focusedSkipButton = lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Render("[ Run with defaults ]") - blurredSkipButton = fmt.Sprintf("[ %s ]", lipgloss.NewStyle().Foreground(lipgloss.Color("240")).Render("Run with defaults")) -) - -// SelectNextMsg used for emitting events when the 'Next' button is selected. -type SelectNextMsg int - -// SelectSkipMsg used for emitting events when the 'Skip' button is selected. -type SelectSkipMsg int - -type Model struct { - focusIndex int - inputs []textinput.Model - configs []InputConfig - // cursorMode cursor.Mode - skipButton bool - submitMsg string - header string - footer string -} - -type InputConfig struct { - Label string - Key string - Help string - Required bool - Placeholder string - RedactInput bool -} - -type Input struct { - Value string - IsDefault bool -} - -func (m Model) GetInputs() map[string]Input { - inputs := make(map[string]Input) - - for i, input := range m.inputs { - isDefault := false - value := input.Value() - if value == "" && m.configs[i].Required { - isDefault = true - value = input.Placeholder - } - inputs[m.configs[i].Key] = Input{Value: value, IsDefault: isDefault} - } - - return inputs -} - -func (m Model) GetLabels() map[string]string { - labels := make(map[string]string) - - for _, config := range m.configs { - labels[config.Key] = config.Label - } - - return labels -} - -func New(config []InputConfig) Model { - m := Model{ - inputs: make([]textinput.Model, len(config)), - submitMsg: "Next", - } - - for i, conf := range config { - input := textinput.New() - input.Placeholder = conf.Placeholder - - if i == 0 { - input.Focus() - input.TextStyle = focusedStyle - input.PromptStyle = focusedStyle - } - - m.inputs[i] = input - } - - m.configs = config - return m -} - -func (m Model) Init() tea.Cmd { - return textinput.Blink -} - -func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - switch msg := msg.(type) { - case tea.KeyMsg: - switch msg.String() { - // Set focus to next input - case "enter", "up", "down": - s := msg.String() - - // Did the user press enter while the submit or skip button was focused? - // If so, emit the appropriate command. - if s == "enter" && m.focusIndex == len(m.inputs) { - return m, func() tea.Msg { return SelectNextMsg(0) } - } else if s == "enter" && m.focusIndex == -1 { - return m, func() tea.Msg { return SelectSkipMsg(0) } - } - - // Cycle indexes - if s == "up" { - m.focusIndex-- - } else { - m.focusIndex++ - } - - if m.focusIndex > len(m.inputs) { - m.focusIndex = 0 - } else if !m.skipButton && m.focusIndex < 0 { - m.focusIndex = len(m.inputs) - } else if m.skipButton && m.focusIndex < -1 { - m.focusIndex = len(m.inputs) - } - - cmds := make([]tea.Cmd, len(m.inputs)) - for i := 0; i < len(m.inputs); i++ { - if i == m.focusIndex { - // Set focused state - cmds[i] = m.focusInput(i) - continue - } - // Remove focused state - m.unfocusInput(i) - } - - return m, tea.Batch(cmds...) - } - } - - // Handle character input and blinking - cmd := m.updateInputs(msg) - - return m, cmd -} - -func (m *Model) updateInputs(msg tea.Msg) tea.Cmd { - cmds := make([]tea.Cmd, len(m.inputs)) - - // Only text inputs with Focus() set will respond, so it's safe to simply - // update all of them here without any further logic. - for i := range m.inputs { - m.inputs[i], cmds[i] = m.inputs[i].Update(msg) - } - - return tea.Batch(cmds...) -} - -func (m Model) View() string { - var b strings.Builder - - if m.header != "" { - fmt.Fprintf(&b, "%s\n\n", m.header) - } - - if m.skipButton { - button := &blurredSkipButton - if m.focusIndex == -1 { - button = &focusedSkipButton - } - fmt.Fprintf(&b, "%s\n\n\n", *button) - } - - for i := range m.inputs { - if m.configs[i].Label != "" { - b.WriteString(m.GetLabel(m.configs[i])) - } - - input := m.inputs[i] - if val := input.Value(); len(val) > 4 && m.configs[i].RedactInput { - if len(val) > 10 { - // start***end - input.SetValue(val[:4] + strings.Repeat("*", len(val)-8) + val[len(val)-4:]) - } else { - // start*** - input.SetValue(val[:4] + strings.Repeat("*", len(val)-4)) - } - } - b.WriteString(input.View()) - b.WriteRune('\n') - if i < len(m.inputs)-1 { - b.WriteRune('\n') - } - } - - if m.footer != "" { - fmt.Fprintf(&b, "\n\n%s", m.footer) - } - - button := blurredStyle.Render(m.submitMsg) - if m.focusIndex == len(m.inputs) { - button = focusedStyle.Render(fmt.Sprintf("[ %s ]", m.submitMsg)) - } - fmt.Fprintf(&b, "\n\n%s\n\n", button) - - return b.String() -} - -func (m Model) GetLabel(c InputConfig) string { - var label strings.Builder - - label.WriteString(c.Label) - if c.Required { - label.WriteString("*") - } - - if len(c.Help) > 0 { - label.WriteString("\n" + helpStyle.Render(c.Help)) - } - - label.WriteString("\n") - return label.String() -} - -func (m Model) SetSkip(skip bool) Model { - m.skipButton = skip - if m.skipButton { - if len(m.inputs) > 0 { - m.unfocusInput(0) - } - m.focusIndex = -1 - } - return m -} - -func (m Model) SetSubmitMsg(msg string) Model { - m.submitMsg = msg - return m -} - -func (m Model) SetFooter(foot string) Model { - m.footer = foot - return m -} - -func (m Model) SetHeader(head string) Model { - m.header = head - return m -} - -func (m *Model) unfocusInput(index int) { - m.inputs[index].Blur() - m.inputs[index].PromptStyle = noStyle - m.inputs[index].TextStyle = noStyle -} - -func (m *Model) focusInput(index int) tea.Cmd { - m.inputs[index].PromptStyle = focusedStyle - m.inputs[index].TextStyle = focusedStyle - return m.inputs[index].Focus() -} diff --git a/pkg/tui/components/viewport/viewport.go b/pkg/tui/components/viewport/viewport.go deleted file mode 100644 index 77fa618285b7..000000000000 --- a/pkg/tui/components/viewport/viewport.go +++ /dev/null @@ -1,97 +0,0 @@ -package viewport - -import ( - "github.com/charmbracelet/bubbles/viewport" - tea "github.com/charmbracelet/bubbletea" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" -) - -// Viewport represents a viewport component. -type Viewport struct { - common common.Common - *viewport.Model -} - -// New returns a new Viewport. -func New(c common.Common) *Viewport { - vp := viewport.New(c.Width, c.Height) - vp.MouseWheelEnabled = true - return &Viewport{ - common: c, - Model: &vp, - } -} - -// SetSize implements common.Component. -func (v *Viewport) SetSize(width, height int) { - v.common.SetSize(width, height) - v.Model.Width = width - v.Model.Height = height -} - -// Init implements tea.Model. -func (v *Viewport) Init() tea.Cmd { - return nil -} - -// Update implements tea.Model. -func (v *Viewport) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - vp, cmd := v.Model.Update(msg) - v.Model = &vp - return v, cmd -} - -// View implements tea.Model. -func (v *Viewport) View() string { - return v.Model.View() -} - -// SetContent sets the viewport's content. -func (v *Viewport) SetContent(content string) { - v.Model.SetContent(content) -} - -// GotoTop moves the viewport to the top of the log. -func (v *Viewport) GotoTop() { - v.Model.GotoTop() -} - -// GotoBottom moves the viewport to the bottom of the log. -func (v *Viewport) GotoBottom() { - v.Model.GotoBottom() -} - -// HalfViewDown moves the viewport down by half the viewport height. -func (v *Viewport) HalfViewDown() { - v.Model.HalfViewDown() -} - -// HalfViewUp moves the viewport up by half the viewport height. -func (v *Viewport) HalfViewUp() { - v.Model.HalfViewUp() -} - -// ViewUp moves the viewport up by a page. -func (v *Viewport) ViewUp() []string { - return v.Model.ViewUp() -} - -// ViewDown moves the viewport down by a page. -func (v *Viewport) ViewDown() []string { - return v.Model.ViewDown() -} - -// LineUp moves the viewport up by the given number of lines. -func (v *Viewport) LineUp(n int) []string { - return v.Model.LineUp(n) -} - -// LineDown moves the viewport down by the given number of lines. -func (v *Viewport) LineDown(n int) []string { - return v.Model.LineDown(n) -} - -// ScrollPercent returns the viewport's scroll percentage. -func (v *Viewport) ScrollPercent() float64 { - return v.Model.ScrollPercent() -} diff --git a/pkg/tui/keymap/keymap.go b/pkg/tui/keymap/keymap.go deleted file mode 100644 index 6ef71357543f..000000000000 --- a/pkg/tui/keymap/keymap.go +++ /dev/null @@ -1,241 +0,0 @@ -package keymap - -import "github.com/charmbracelet/bubbles/key" - -// KeyMap is a map of key bindings for the UI. -type KeyMap struct { - Quit key.Binding - CmdQuit key.Binding - Left key.Binding - Right key.Binding - Up key.Binding - Down key.Binding - UpDown key.Binding - LeftRight key.Binding - Arrows key.Binding - Select key.Binding - Section key.Binding - Back key.Binding - PrevPage key.Binding - NextPage key.Binding - Help key.Binding - - SelectItem key.Binding - BackItem key.Binding - - Copy key.Binding -} - -// DefaultKeyMap returns the default key map. -func DefaultKeyMap() *KeyMap { - km := new(KeyMap) - - km.Quit = key.NewBinding( - key.WithKeys( - "ctrl+c", - ), - key.WithHelp( - "ctrl+c", - "quit", - ), - ) - - km.CmdQuit = key.NewBinding( - key.WithKeys( - "q", - "ctrl+c", - ), - key.WithHelp( - "q", - "quit", - ), - ) - - km.Up = key.NewBinding( - key.WithKeys( - "up", - "k", - ), - key.WithHelp( - "ā†‘/k", - "up", - ), - ) - - km.Down = key.NewBinding( - key.WithKeys( - "down", - "j", - ), - key.WithHelp( - "ā†“/j", - "down", - ), - ) - - km.UpDown = key.NewBinding( - key.WithKeys( - "up", - "down", - "k", - "j", - ), - key.WithHelp( - "ā†‘ā†“", - "navigate", - ), - ) - - km.Left = key.NewBinding( - key.WithKeys( - "left", - "h", - ), - key.WithHelp( - "ā†/h", - "left", - ), - ) - - km.Right = key.NewBinding( - key.WithKeys( - "right", - "l", - ), - key.WithHelp( - "ā†’/l", - "right", - ), - ) - - km.LeftRight = key.NewBinding( - key.WithKeys( - "left", - "h", - "right", - "l", - ), - key.WithHelp( - "ā†ā†’", - "navigate", - ), - ) - - km.Arrows = key.NewBinding( - key.WithKeys( - "up", - "right", - "down", - "left", - "k", - "j", - "h", - "l", - ), - key.WithHelp( - "ā†‘ā†ā†“ā†’", - "navigate", - ), - ) - - km.Select = key.NewBinding( - key.WithKeys( - "enter", - ), - key.WithHelp( - "enter", - "select", - ), - ) - - km.Section = key.NewBinding( - key.WithKeys( - "tab", - "shift+tab", - ), - key.WithHelp( - "tab", - "section", - ), - ) - - km.Back = key.NewBinding( - key.WithKeys( - "esc", - ), - key.WithHelp( - "esc", - "back", - ), - ) - - km.PrevPage = key.NewBinding( - key.WithKeys( - "pgup", - "b", - "u", - ), - key.WithHelp( - "pgup", - "prev page", - ), - ) - - km.NextPage = key.NewBinding( - key.WithKeys( - "pgdown", - "f", - "d", - ), - key.WithHelp( - "pgdn", - "next page", - ), - ) - - km.Help = key.NewBinding( - key.WithKeys( - "?", - ), - key.WithHelp( - "?", - "toggle help", - ), - ) - - km.SelectItem = key.NewBinding( - key.WithKeys( - "l", - "right", - ), - key.WithHelp( - "ā†’", - "select", - ), - ) - - km.BackItem = key.NewBinding( - key.WithKeys( - "h", - "left", - "backspace", - ), - key.WithHelp( - "ā†", - "back", - ), - ) - - km.Copy = key.NewBinding( - key.WithKeys( - "c", - "ctrl+c", - ), - key.WithHelp( - "c", - "copy text", - ), - ) - - return km -} diff --git a/pkg/tui/pages/contact_enterprise/contact_enterprise.go b/pkg/tui/pages/contact_enterprise/contact_enterprise.go deleted file mode 100644 index 83ada4a38cc6..000000000000 --- a/pkg/tui/pages/contact_enterprise/contact_enterprise.go +++ /dev/null @@ -1,60 +0,0 @@ -package contact_enterprise - -import ( - "strings" - - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/styles" -) - -type ContactEnterprise struct { - common.Common - viewed bool -} - -var ( - linkStyle = lipgloss.NewStyle().Foreground( - lipgloss.Color("28")) // green -) - -func New(c common.Common) *ContactEnterprise { - return &ContactEnterprise{ - Common: c, - viewed: false, - } -} - -func (m *ContactEnterprise) Init() tea.Cmd { - return nil -} - -func (m *ContactEnterprise) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - if m.viewed { - return m, tea.Quit - } - - return m, func() tea.Msg { return nil } -} - -func (m *ContactEnterprise) View() string { - - s := strings.Builder{} - s.WriteString("Interested in TruffleHog enterprise?\n") - s.WriteString(linkStyle.Render("šŸ”— https://trufflesecurity.com/contact")) - - m.viewed = true - return styles.AppStyle.Render(s.String()) -} - -func (m *ContactEnterprise) ShortHelp() []key.Binding { - // TODO: actually return something - return nil -} - -func (m *ContactEnterprise) FullHelp() [][]key.Binding { - // TODO: actually return something - return nil -} diff --git a/pkg/tui/pages/source_configure/item.go b/pkg/tui/pages/source_configure/item.go deleted file mode 100644 index 70110b673b06..000000000000 --- a/pkg/tui/pages/source_configure/item.go +++ /dev/null @@ -1,23 +0,0 @@ -package source_configure - -type Item struct { - title string - description string -} - -func (i Item) ID() string { return i.title } - -func (i Item) Title() string { - return i.title -} -func (i Item) Description() string { - return i.description -} - -func (i Item) SetDescription(d string) Item { - i.description = d - return i -} - -// We shouldn't be filtering for these list items. -func (i Item) FilterValue() string { return "" } diff --git a/pkg/tui/pages/source_configure/run_component.go b/pkg/tui/pages/source_configure/run_component.go deleted file mode 100644 index db700259fb31..000000000000 --- a/pkg/tui/pages/source_configure/run_component.go +++ /dev/null @@ -1,118 +0,0 @@ -package source_configure - -import ( - "strings" - - "github.com/charmbracelet/bubbles/key" - "github.com/charmbracelet/bubbles/list" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/styles" -) - -type SetArgsMsg string - -type RunComponent struct { - common.Common - parent *SourceConfigure - reviewList list.Model - reviewListItems []list.Item -} - -func NewRunComponent(common common.Common, parent *SourceConfigure) *RunComponent { - // Make list of SourceItems. - listItems := []list.Item{ - Item{title: "šŸ”Ž Source configuration"}, - Item{title: "šŸ½ TruffleHog configuration"}, - Item{title: "šŸ’ø Sales pitch", description: "\tContinuous monitoring, state tracking, remediations, and more\n\tšŸ”— https://trufflesecurity.com/trufflehog"}, - } - - // Setup list - delegate := list.NewDefaultDelegate() - delegate.Styles.SelectedTitle.Foreground(lipgloss.Color("white")) - delegate.Styles.SelectedDesc.Foreground(lipgloss.Color("white")) - delegate.SetHeight(3) - - reviewList := list.New(listItems, delegate, common.Width, common.Height) - - reviewList.SetShowTitle(false) - reviewList.SetShowStatusBar(false) - reviewList.SetFilteringEnabled(false) - - return &RunComponent{ - Common: common, - parent: parent, - reviewList: reviewList, - reviewListItems: listItems, - } -} - -func (m *RunComponent) Init() tea.Cmd { - return nil -} - -func (m *RunComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - switch msg := msg.(type) { - case tea.WindowSizeMsg: - h, v := styles.AppStyle.GetFrameSize() - m.reviewList.SetSize(msg.Width-h, msg.Height/2-v) - case tea.KeyMsg: - if msg.Type == tea.KeyEnter { - command := m.parent.sourceFields.Cmd() - if m.parent.truffleFields.Cmd() != "" { - command += " " + m.parent.truffleFields.Cmd() - } - cmd := func() tea.Msg { return SetArgsMsg(command) } - return m, cmd - } - } - if len(m.reviewListItems) > 0 && m.parent != nil && m.parent.sourceFields != nil { - m.reviewListItems[0] = m.reviewListItems[0].(Item).SetDescription(m.parent.sourceFields.Summary()) - m.reviewListItems[1] = m.reviewListItems[1].(Item).SetDescription(m.parent.truffleFields.Summary()) - } - var cmd tea.Cmd - m.reviewList, cmd = m.reviewList.Update(msg) - return m, tea.Batch(cmd) -} - -func (m *RunComponent) View() string { - var view strings.Builder - - view.WriteString("\nšŸ”Ž Source configuration\n") - view.WriteString(m.parent.sourceFields.Summary()) - - view.WriteString("\nšŸ½ TruffleHog configuration\n") - view.WriteString(m.parent.truffleFields.Summary()) - - view.WriteString("\nšŸ’ø Sales pitch\n") - view.WriteString("\tContinuous monitoring, state tracking, remediations, and more\n") - view.WriteString("\tšŸ”— https://trufflesecurity.com/trufflehog\n\n") - - view.WriteString(styles.BoldTextStyle.Render("\n\nšŸ· Run TruffleHog for "+m.parent.configTabSource) + " šŸ·\n\n") - - view.WriteString("Generated TruffleHog command\n") - view.WriteString(styles.HintTextStyle.Render("Save this if you want to run it again later!") + "\n") - - command := m.parent.sourceFields.Cmd() - if m.parent.truffleFields.Cmd() != "" { - command += " " + m.parent.truffleFields.Cmd() - } - view.WriteString(styles.CodeTextStyle.Render(command)) - - focusedStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("205")) - view.WriteString("\n\n" + focusedStyle.Render("[ Run TruffleHog ]") + "\n\n") - - // view.WriteString(m.reviewList.View()) - return view.String() -} - -func (m *RunComponent) ShortHelp() []key.Binding { - // TODO: actually return something - return nil -} - -func (m *RunComponent) FullHelp() [][]key.Binding { - // TODO: actually return something - return nil -} diff --git a/pkg/tui/pages/source_configure/source_component.go b/pkg/tui/pages/source_configure/source_component.go deleted file mode 100644 index f5ad69e3b6c9..000000000000 --- a/pkg/tui/pages/source_configure/source_component.go +++ /dev/null @@ -1,71 +0,0 @@ -package source_configure - -import ( - "strings" - - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/sources" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/styles" -) - -type SourceComponent struct { - common.Common - parent *SourceConfigure - form tea.Model -} - -func NewSourceComponent(common common.Common, parent *SourceConfigure) *SourceComponent { - return &SourceComponent{ - Common: common, - parent: parent, - } -} - -func (m *SourceComponent) SetForm(form tea.Model) { - m.form = form -} - -func (m *SourceComponent) Init() tea.Cmd { - return nil -} - -func (m *SourceComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - // TODO: Add a focus variable. - if m.form != nil { - model, cmd := m.form.Update(msg) - m.form = model - return m, cmd - } - return m, nil -} - -func (m *SourceComponent) View() string { - var view strings.Builder - - view.WriteString(styles.BoldTextStyle.Render("\nConfiguring "+styles.PrimaryTextStyle.Render(m.parent.configTabSource)) + "\n") - - view.WriteString(styles.HintTextStyle.Render("* required field") + "\n\n") - - sourceNote := sources.GetSourceNotes(m.parent.configTabSource) - if len(sourceNote) > 0 { - view.WriteString("ā­ " + sourceNote + " ā­\n\n") - } - - if m.form != nil { - view.WriteString(m.form.View()) - view.WriteString("\n") - } - return view.String() -} - -func (m *SourceComponent) ShortHelp() []key.Binding { - // TODO: actually return something - return nil -} - -func (m *SourceComponent) FullHelp() [][]key.Binding { - // TODO: actually return something - return nil -} diff --git a/pkg/tui/pages/source_configure/source_configure.go b/pkg/tui/pages/source_configure/source_configure.go deleted file mode 100644 index d543a3f01c1c..000000000000 --- a/pkg/tui/pages/source_configure/source_configure.go +++ /dev/null @@ -1,139 +0,0 @@ -package source_configure - -import ( - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/tabs" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/sources" -) - -type SetSourceMsg struct { - Source string -} - -type tab int - -const ( - configTab tab = iota - truffleConfigTab - runTab -) - -func (t tab) String() string { - return []string{ - "1. Source Configuration", - "2. TruffleHog Configuration", - "3. Run", - }[t] -} - -type SourceConfigure struct { - common.Common - activeTab tab - tabs *tabs.Tabs - configTabSource string - tabComponents []common.Component - sourceFields sources.CmdModel - truffleFields sources.CmdModel -} - -func (m SourceConfigure) Init() tea.Cmd { - return m.tabs.Init() -} - -func New(c common.Common) *SourceConfigure { - conf := SourceConfigure{Common: c, truffleFields: GetTrufflehogConfiguration()} - conf.tabs = tabs.New(c, []string{configTab.String(), truffleConfigTab.String(), runTab.String()}) - - conf.tabComponents = []common.Component{ - configTab: NewSourceComponent(c, &conf), - truffleConfigTab: NewTrufflehogComponent(c, &conf), - runTab: NewRunComponent(c, &conf), - } - return &conf -} - -func (m *SourceConfigure) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - var cmds []tea.Cmd - - switch msg := msg.(type) { - case tea.WindowSizeMsg: - for i := range m.tabComponents { - model, cmd := m.tabComponents[i].Update(msg) - m.tabComponents[i] = model.(common.Component) - cmds = append(cmds, cmd) - } - - case tabs.ActiveTabMsg: - m.activeTab = tab(msg) - t, cmd := m.tabs.Update(msg) - m.tabs = t.(*tabs.Tabs) - - if cmd != nil { - cmds = append(cmds, cmd) - } - case tabs.SelectTabMsg: - m.activeTab = tab(msg) - t, cmd := m.tabs.Update(msg) - m.tabs = t.(*tabs.Tabs) - - if cmd != nil { - cmds = append(cmds, cmd) - } - case tea.KeyMsg: - t, cmd := m.tabs.Update(msg) - m.tabs = t.(*tabs.Tabs) - if cmd != nil { - cmds = append(cmds, cmd) - } - case SetSourceMsg: - m.configTabSource = msg.Source - // TODO: Use actual messages or something? - m.tabComponents[truffleConfigTab].(*TrufflehogComponent).SetForm(m.truffleFields) - fields := sources.GetSourceFields(m.configTabSource) - - if fields != nil { - m.sourceFields = fields - m.tabComponents[configTab].(*SourceComponent).SetForm(fields) - } - - case textinputs.SelectNextMsg, textinputs.SelectSkipMsg: - if m.activeTab < runTab { - m.activeTab++ - } - t, cmd := m.tabs.Update(tabs.SelectTabMsg(int(m.activeTab))) - m.tabs = t.(*tabs.Tabs) - - if cmd != nil { - cmds = append(cmds, cmd) - } - } - - tab, cmd := m.tabComponents[m.activeTab].Update(msg) - m.tabComponents[m.activeTab] = tab.(common.Component) - if cmd != nil { - cmds = append(cmds, cmd) - } - - return m, tea.Batch(cmds...) -} - -func (m *SourceConfigure) View() string { - return lipgloss.JoinVertical(lipgloss.Top, - m.tabs.View(), - m.tabComponents[m.activeTab].View(), - ) -} - -func (m *SourceConfigure) ShortHelp() []key.Binding { - // TODO: actually return something - return nil -} - -func (m *SourceConfigure) FullHelp() [][]key.Binding { - // TODO: actually return something - return nil -} diff --git a/pkg/tui/pages/source_configure/trufflehog_component.go b/pkg/tui/pages/source_configure/trufflehog_component.go deleted file mode 100644 index 13c8a56b3ed6..000000000000 --- a/pkg/tui/pages/source_configure/trufflehog_component.go +++ /dev/null @@ -1,66 +0,0 @@ -package source_configure - -import ( - "strings" - - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/styles" -) - -type TrufflehogComponent struct { - common.Common - parent *SourceConfigure - form tea.Model -} - -func NewTrufflehogComponent(common common.Common, parent *SourceConfigure) *TrufflehogComponent { - return &TrufflehogComponent{ - Common: common, - parent: parent, - } -} - -func (m *TrufflehogComponent) SetForm(form tea.Model) { - m.form = form -} - -func (m *TrufflehogComponent) Init() tea.Cmd { - return nil -} - -func (m *TrufflehogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - // TODO: Add a focus variable. - if m.form != nil { - model, cmd := m.form.Update(msg) - m.form = model - - return m, cmd - } - return m, nil -} - -func (m *TrufflehogComponent) View() string { - var view strings.Builder - - view.WriteString(styles.BoldTextStyle.Render("\nConfiguring "+styles.PrimaryTextStyle.Render("TruffleHog")) + "\n") - view.WriteString(styles.HintTextStyle.Render("You can skip this completely and run with defaults") + "\n\n") - - if m.form != nil { - view.WriteString(m.form.View()) - view.WriteString("\n") - } - - return view.String() -} - -func (m *TrufflehogComponent) ShortHelp() []key.Binding { - // TODO: actually return something - return nil -} - -func (m *TrufflehogComponent) FullHelp() [][]key.Binding { - // TODO: actually return something - return nil -} diff --git a/pkg/tui/pages/source_configure/trufflehog_configure.go b/pkg/tui/pages/source_configure/trufflehog_configure.go deleted file mode 100644 index c3de73d535b4..000000000000 --- a/pkg/tui/pages/source_configure/trufflehog_configure.go +++ /dev/null @@ -1,116 +0,0 @@ -package source_configure - -import ( - "runtime" - "strconv" - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" -) - -type truffleCmdModel struct { - textinputs.Model -} - -func GetTrufflehogConfiguration() truffleCmdModel { - verification := textinputs.InputConfig{ - Label: "Skip Verification", - Key: "no-verification", - Required: false, - Help: "Check if a suspected secret is real or not", - Placeholder: "false", - } - - verifiedResults := textinputs.InputConfig{ - Label: "Verified results", - Key: "only-verified", - Required: false, - Help: "Return only verified results", - Placeholder: "false", - } - - jsonOutput := textinputs.InputConfig{ - Label: "JSON output", - Key: "json", - Required: false, - Help: "Output results to JSON", - Placeholder: "false", - } - - excludeDetectors := textinputs.InputConfig{ - Label: "Exclude detectors", - Key: "exclude_detectors", - Required: false, - Help: "Comma separated list of detector types to exclude. Protobuf name or IDs may be used, as well as ranges. IDs defined here take precedence over the include list.", - Placeholder: "", - } - - concurrency := textinputs.InputConfig{ - Label: "Concurrency", - Key: "concurrency", - Required: false, - Help: "Number of concurrent workers.", - Placeholder: strconv.Itoa(runtime.NumCPU()), - } - - return truffleCmdModel{textinputs.New([]textinputs.InputConfig{jsonOutput, verification, verifiedResults, excludeDetectors, concurrency}).SetSkip(true)} -} - -func (m truffleCmdModel) Cmd() string { - var command []string - inputs := m.GetInputs() - - if isTrue(inputs["json"].Value) { - command = append(command, "--json") - } - - if isTrue(inputs["no-verification"].Value) { - command = append(command, "--no-verification") - } - - if isTrue(inputs["only-verified"].Value) { - command = append(command, "--results=verified") - } - - if inputs["exclude_detectors"].Value != "" { - cmd := "--exclude-detectors=" + strings.ReplaceAll(inputs["exclude_detectors"].Value, " ", "") - command = append(command, cmd) - } - - if inputs["concurrency"].Value != "" { - command = append(command, "--concurrency="+inputs["concurrency"].Value) - } - - return strings.Join(command, " ") -} - -func (m truffleCmdModel) Summary() string { - summary := strings.Builder{} - keys := []string{"no-verification", "only-verified", "json", "exclude_detectors", "concurrency"} - - inputs := m.GetInputs() - labels := m.GetLabels() - for _, key := range keys { - if inputs[key].Value != "" { - summary.WriteString("\t" + labels[key] + ": " + inputs[key].Value + "\n") - } - } - - if summary.Len() == 0 { - summary.WriteString("\tRunning with defaults\n") - - } - - summary.WriteString("\n") - return summary.String() -} - -func isTrue(val string) bool { - value := strings.ToLower(val) - isTrue, _ := strconv.ParseBool(value) - - if isTrue || value == "yes" || value == "y" { - return true - } - return false -} diff --git a/pkg/tui/pages/source_select/item.go b/pkg/tui/pages/source_select/item.go deleted file mode 100644 index dd57a1244480..000000000000 --- a/pkg/tui/pages/source_select/item.go +++ /dev/null @@ -1,32 +0,0 @@ -package source_select - -type SourceItem struct { - title string - description string - enterprise bool -} - -func OssItem(title, description string) SourceItem { - return SourceItem{title, description, false} -} - -func EnterpriseItem(title, description string) SourceItem { - return SourceItem{title, description, true} -} - -func (i SourceItem) ID() string { return i.title } - -func (i SourceItem) Title() string { - if i.enterprise { - return "šŸ’ø " + i.title - } - return i.title -} -func (i SourceItem) Description() string { - if i.enterprise { - return i.description + " (Enterprise only)" - } - return i.description -} - -func (i SourceItem) FilterValue() string { return i.title + i.description } diff --git a/pkg/tui/pages/source_select/source_select.go b/pkg/tui/pages/source_select/source_select.go deleted file mode 100644 index 723bf68d8e2e..000000000000 --- a/pkg/tui/pages/source_select/source_select.go +++ /dev/null @@ -1,226 +0,0 @@ -package source_select - -import ( - "time" - - "github.com/charmbracelet/bubbles/key" - "github.com/charmbracelet/bubbles/list" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/selector" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/styles" -) - -// TODO: Review light theme styling -var ( - titleStyle = lipgloss.NewStyle(). - Foreground(lipgloss.Color("#FFFDF5")). - Background(lipgloss.Color(styles.Colors["bronze"])). - Padding(0, 1) - - // FIXME: Hon pls help - errorStatusMessageStyle = lipgloss.NewStyle(). - Foreground(lipgloss.AdaptiveColor{Dark: "#ff0000"}). - Render - - selectedSourceItemStyle = lipgloss.NewStyle(). - Border(lipgloss.NormalBorder(), false, false, false, true). - BorderForeground(lipgloss.AdaptiveColor{Dark: styles.Colors["sprout"], Light: styles.Colors["bronze"]}). - Foreground(lipgloss.AdaptiveColor{Dark: styles.Colors["sprout"], Light: styles.Colors["fern"]}). - Padding(0, 0, 0, 1) - - selectedDescription = selectedSourceItemStyle.Copy(). - Foreground(lipgloss.AdaptiveColor{Dark: styles.Colors["sprout"], Light: styles.Colors["sprout"]}) -) - -type listKeyMap struct { - toggleHelpMenu key.Binding -} - -type ( - SourceSelect struct { - common.Common - sourcesList list.Model - keys *listKeyMap - delegateKeys *delegateKeyMap - selector *selector.Selector - } -) - -func New(c common.Common) *SourceSelect { - var ( - delegateKeys = newDelegateKeyMap() - listKeys = &listKeyMap{ - toggleHelpMenu: key.NewBinding( - key.WithKeys("H"), - key.WithHelp("H", "toggle help"), - ), - } - ) - - // Make list of SourceItems. - SourceItems := []list.Item{ - // Open source sources. - OssItem("Git", "Scan git repositories."), - OssItem("GitHub", "Scan GitHub repositories and/or organizations."), - OssItem("Filesystem", "Scan your filesystem by selecting what directories to scan."), - OssItem("Hugging Face", "Scan Hugging Face, an AI/ML community."), - OssItem("Jenkins", "Scan Jenkins, a CI/CD platform. (Recently open-sourced from enterprise!)"), - OssItem("Elasticsearch", "Scan your Elasticsearch cluster or Elastic Cloud instance."), - OssItem("Postman", "Scan a collection, workspace, or environment from Postman, the API platform."), - OssItem("GitLab", "Scan GitLab repositories."), - OssItem("AWS S3", "Scan Amazon S3 buckets."), - OssItem("CircleCI", "Scan CircleCI, a CI/CD platform."), - OssItem("Syslog", "Scan syslog, event data logs."), - OssItem("Docker", "Scan a Docker instance, a containerized application."), - OssItem("GCS (Google Cloud Storage)", "Scan a Google Cloud Storage instance."), - // Enterprise sources. - EnterpriseItem("Artifactory", "Scan JFrog Artifactory packages."), - EnterpriseItem("Azure Repos", "Scan Microsoft Azure repositories."), - EnterpriseItem("BitBucket", "Scan Atlassian's Git-based source code repository hosting service."), - EnterpriseItem("Buildkite", "Scan Buildkite, a CI/CD platform."), - EnterpriseItem("Confluence", "Scan Atlassian's web-based wiki and knowledge base."), - EnterpriseItem("Gerrit", "Scan Gerrit, a code collaboration tool"), - EnterpriseItem("Jira", "Scan Atlassian's issue & project tracking software."), - EnterpriseItem("Slack", "Scan Slack, a messaging and communication platform."), - EnterpriseItem("Microsoft Teams", "Scan Microsoft Teams, a messaging and communication platform."), - EnterpriseItem("Microsoft Sharepoint", "Scan Microsoft Sharepoint, a collaboration and document management platform."), - EnterpriseItem("Google Drive", "Scan Google Drive, a cloud-based storage and file sync service."), - } - - // Setup list - delegate := newSourceItemDelegate(delegateKeys) - delegate.Styles.SelectedTitle = selectedSourceItemStyle - delegate.Styles.SelectedDesc = selectedDescription - - sourcesList := list.New(SourceItems, delegate, 0, 0) - sourcesList.Title = "Sources" - sourcesList.Styles.Title = titleStyle - sourcesList.StatusMessageLifetime = 10 * time.Second - - sourcesList.AdditionalFullHelpKeys = func() []key.Binding { - return []key.Binding{ - listKeys.toggleHelpMenu, - } - } - - sourcesList.SetShowStatusBar(false) - sel := selector.New(c, []selector.IdentifiableItem{}, delegate) - - return &SourceSelect{ - Common: c, - sourcesList: sourcesList, - keys: listKeys, - delegateKeys: delegateKeys, - selector: sel, - } -} - -func (m *SourceSelect) Init() tea.Cmd { - return nil -} - -func (m *SourceSelect) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - var cmds []tea.Cmd - - switch msg := msg.(type) { - case tea.WindowSizeMsg: - h, v := styles.AppStyle.GetFrameSize() - m.sourcesList.SetSize(msg.Width-h, msg.Height-v) - - case tea.KeyMsg: - // Don't match any of the keys below if we're actively filtering. - if m.sourcesList.FilterState() == list.Filtering { - break - } - - switch { - case key.Matches(msg, m.keys.toggleHelpMenu): - m.sourcesList.SetShowHelp(!m.sourcesList.ShowHelp()) - return m, nil - } - } - - // This will also call our delegate's update function. - newListModel, cmd := m.sourcesList.Update(msg) - m.sourcesList = newListModel - cmds = append(cmds, cmd) - - if m.selector != nil { - sel, cmd := m.selector.Update(msg) - m.selector = sel.(*selector.Selector) - cmds = append(cmds, cmd) - } - - return m, tea.Batch(cmds...) -} - -func (m *SourceSelect) View() string { - return styles.AppStyle.Render(m.sourcesList.View()) -} - -func (m *SourceSelect) ShortHelp() []key.Binding { - // TODO: actually return something - return nil -} - -func (m *SourceSelect) FullHelp() [][]key.Binding { - // TODO: actually return something - return nil -} - -func newSourceItemDelegate(keys *delegateKeyMap) list.DefaultDelegate { - d := list.NewDefaultDelegate() - - d.UpdateFunc = func(msg tea.Msg, m *list.Model) tea.Cmd { - selectedSourceItem, ok := m.SelectedItem().(SourceItem) - if !ok { - return nil - } - - if msg, ok := msg.(tea.KeyMsg); ok && key.Matches(msg, keys.choose) { - if selectedSourceItem.enterprise { - return m.NewStatusMessage(errorStatusMessageStyle( - "That's an enterprise only source. Learn more at trufflesecurity.com", - )) - } - - return func() tea.Msg { - return selector.SelectMsg{IdentifiableItem: selectedSourceItem} - } - } - return nil - } - - help := []key.Binding{keys.choose} - d.ShortHelpFunc = func() []key.Binding { return help } - d.FullHelpFunc = func() [][]key.Binding { return [][]key.Binding{help} } - - return d -} - -type delegateKeyMap struct { - choose key.Binding -} - -// Additional short help entries. This satisfies the help.KeyMap interface and -// is entirely optional. -func (d delegateKeyMap) ShortHelp() []key.Binding { - return []key.Binding{d.choose} -} - -// Additional full help entries. This satisfies the help.KeyMap interface and -// is entirely optional. -func (d delegateKeyMap) FullHelp() [][]key.Binding { - return [][]key.Binding{{d.choose}} -} - -func newDelegateKeyMap() *delegateKeyMap { - return &delegateKeyMap{ - choose: key.NewBinding( - key.WithKeys("enter"), - key.WithHelp("enter", "choose"), - ), - } -} diff --git a/pkg/tui/pages/view_oss/view_oss.go b/pkg/tui/pages/view_oss/view_oss.go deleted file mode 100644 index 1382900334a6..000000000000 --- a/pkg/tui/pages/view_oss/view_oss.go +++ /dev/null @@ -1,59 +0,0 @@ -package view_oss - -import ( - "strings" - - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/styles" -) - -type ViewOSS struct { - common.Common - viewed bool -} - -var ( - linkStyle = lipgloss.NewStyle().Foreground( - lipgloss.Color("28")) // green -) - -func New(c common.Common) *ViewOSS { - return &ViewOSS{ - Common: c, - viewed: false, - } -} - -func (m *ViewOSS) Init() tea.Cmd { - return nil -} - -func (m *ViewOSS) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - if m.viewed { - return m, tea.Quit - } - - return m, func() tea.Msg { return nil } -} - -func (m *ViewOSS) View() string { - s := strings.Builder{} - s.WriteString("View our open-source project on GitHub\n") - s.WriteString(linkStyle.Render("šŸ”— https://github.com/trufflesecurity/trufflehog ")) - - m.viewed = true - return styles.AppStyle.Render(s.String()) -} - -func (m *ViewOSS) ShortHelp() []key.Binding { - // TODO: actually return something - return nil -} - -func (m *ViewOSS) FullHelp() [][]key.Binding { - // TODO: actually return something - return nil -} diff --git a/pkg/tui/pages/wizard_intro/item.go b/pkg/tui/pages/wizard_intro/item.go deleted file mode 100644 index f9eef55d9ab3..000000000000 --- a/pkg/tui/pages/wizard_intro/item.go +++ /dev/null @@ -1,137 +0,0 @@ -package wizard_intro - -import ( - "fmt" - "io" - "strings" - - "github.com/charmbracelet/bubbles/key" - "github.com/charmbracelet/bubbles/list" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" -) - -// Item represents a single item in the selector. -type Item int - -// ID implements selector.IdentifiableItem. -func (i Item) ID() string { - return i.String() -} - -// Title returns the item title. Implements list.DefaultItem. -func (i Item) Title() string { return i.String() } - -// Description returns the item description. Implements list.DefaultItem. -func (i Item) Description() string { return "" } - -// FilterValue implements list.Item. -func (i Item) FilterValue() string { return i.Title() } - -// Command returns the item Command view. -func (i Item) Command() string { - return i.Title() -} - -// ItemDelegate is the delegate for the item. -type ItemDelegate struct { - common *common.Common -} - -// Width returns the item width. -func (d ItemDelegate) Width() int { - width := d.common.Styles.MenuItem.GetHorizontalFrameSize() + d.common.Styles.MenuItem.GetWidth() - return width -} - -// Height returns the item height. Implements list.ItemDelegate. -func (d ItemDelegate) Height() int { - height := d.common.Styles.MenuItem.GetVerticalFrameSize() + d.common.Styles.MenuItem.GetHeight() - return height -} - -// Spacing returns the spacing between items. Implements list.ItemDelegate. -func (d ItemDelegate) Spacing() int { return 1 } - -// Update implements list.ItemDelegate. -func (d ItemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd { - idx := m.Index() - item, ok := m.SelectedItem().(Item) - if !ok { - return nil - } - switch msg := msg.(type) { - case tea.KeyMsg: - switch { - case key.Matches(msg, d.common.KeyMap.Copy): - d.common.Copy.Copy(item.Command()) - return m.SetItem(idx, item) - } - } - return nil -} - -// Render implements list.ItemDelegate. -func (d ItemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) { - i := listItem.(Item) - s := strings.Builder{} - var matchedRunes []int - - // Conditions - var ( - isSelected = index == m.Index() - isFiltered = m.FilterState() == list.Filtering || m.FilterState() == list.FilterApplied - ) - - styles := d.common.Styles.RepoSelector.Normal - if isSelected { - styles = d.common.Styles.RepoSelector.Active - } - - title := i.Title() - title = common.TruncateString(title, m.Width()-styles.Base.GetHorizontalFrameSize()) - // if i.repo.IsPrivate() { - // title += " šŸ”’" - // } - if isSelected { - title += " " - } - updatedStr := " Updated" - if m.Width()-styles.Base.GetHorizontalFrameSize()-lipgloss.Width(updatedStr)-lipgloss.Width(title) <= 0 { - updatedStr = "" - } - updatedStyle := styles.Updated.Copy(). - Align(lipgloss.Right). - Width(m.Width() - styles.Base.GetHorizontalFrameSize() - lipgloss.Width(title)) - updated := updatedStyle.Render(updatedStr) - - if isFiltered && index < len(m.VisibleItems()) { - // Get indices of matched characters - matchedRunes = m.MatchesForItem(index) - } - - if isFiltered { - unmatched := styles.Title.Copy().Inline(true) - matched := unmatched.Copy().Underline(true) - title = lipgloss.StyleRunes(title, matchedRunes, matched, unmatched) - } - title = styles.Title.Render(title) - desc := i.Description() - desc = common.TruncateString(desc, m.Width()-styles.Base.GetHorizontalFrameSize()) - desc = styles.Desc.Render(desc) - - s.WriteString(lipgloss.JoinHorizontal(lipgloss.Bottom, title, updated)) - s.WriteRune('\n') - s.WriteString(desc) - s.WriteRune('\n') - cmd := common.TruncateString(i.Command(), m.Width()-styles.Base.GetHorizontalFrameSize()) - cmd = styles.Command.Render(cmd) - - s.WriteString(cmd) - fmt.Fprint(w, - d.common.Zone.Mark(i.ID(), - styles.Base.Render(s.String()), - ), - ) -} diff --git a/pkg/tui/pages/wizard_intro/wizard_intro.go b/pkg/tui/pages/wizard_intro/wizard_intro.go deleted file mode 100644 index 4e54e9dfea1e..000000000000 --- a/pkg/tui/pages/wizard_intro/wizard_intro.go +++ /dev/null @@ -1,113 +0,0 @@ -package wizard_intro - -import ( - "strings" - - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/selector" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/styles" -) - -const ( - ScanSourceWithWizard Item = iota - // ScanSourceWithConfig - AnalyzeSecret - ViewHelpDocs - ViewOSSProject - EnterpriseInquire - Quit -) - -func (w Item) String() string { - switch w { - case ScanSourceWithWizard: - return "Scan a source using wizard" - case AnalyzeSecret: - return "Analyze a secret's permissions" - //case ScanSourceWithConfig: - // return "Scan a source with a config file" - case ViewHelpDocs: - return "View help docs" - case ViewOSSProject: - return "View open-source project" - case EnterpriseInquire: - return "Inquire about TruffleHog Enterprise" - case Quit: - return "Quit" - } - panic("unreachable") -} - -type WizardIntro struct { - common.Common - selector *selector.Selector -} - -func New(cmn common.Common) *WizardIntro { - sel := selector.New(cmn, - []selector.IdentifiableItem{ - ScanSourceWithWizard, - AnalyzeSecret, - // ScanSourceWithConfig, - ViewHelpDocs, - ViewOSSProject, - EnterpriseInquire, - Quit, - }, - ItemDelegate{&cmn}) - - return &WizardIntro{Common: cmn, selector: sel} -} - -func (m *WizardIntro) Init() tea.Cmd { - m.selector.Select(0) - return nil -} - -func (m *WizardIntro) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - cmds := make([]tea.Cmd, 0) - - s, cmd := m.selector.Update(msg) - m.selector = s.(*selector.Selector) - if cmd != nil { - cmds = append(cmds, cmd) - } - - return m, tea.Batch(cmds...) -} - -func (m *WizardIntro) View() string { - s := strings.Builder{} - s.WriteString("What do you want to do?\n\n") - - for i, selectorItem := range m.selector.Items() { - // Cast the interface to the concrete Item struct. - item := selectorItem.(Item) - if m.selector.Index() == i { - selectedStyle := lipgloss.NewStyle().Foreground(lipgloss.Color(styles.Colors["sprout"])) - s.WriteString(selectedStyle.Render(" (ā€¢) " + item.Title())) - } else { - s.WriteString(" ( ) " + item.Title()) - } - s.WriteString("\n") - } - - return styles.AppStyle.Render(s.String()) -} - -func (m *WizardIntro) ShortHelp() []key.Binding { - kb := make([]key.Binding, 0) - kb = append(kb, - m.Common.KeyMap.UpDown, - m.Common.KeyMap.Section, - ) - return kb -} - -func (m *WizardIntro) FullHelp() [][]key.Binding { - // TODO: actually return something - return nil -} diff --git a/pkg/tui/sources/circleci/circleci.go b/pkg/tui/sources/circleci/circleci.go deleted file mode 100644 index db8b7bfd4b6a..000000000000 --- a/pkg/tui/sources/circleci/circleci.go +++ /dev/null @@ -1,41 +0,0 @@ -package circleci - -import ( - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" -) - -type circleCiCmdModel struct { - textinputs.Model -} - -func GetFields() circleCiCmdModel { - token := textinputs.InputConfig{ - Label: "API Token", - Key: "token", - Required: true, - Placeholder: "top secret token", - } - - return circleCiCmdModel{textinputs.New([]textinputs.InputConfig{token})} -} - -func (m circleCiCmdModel) Cmd() string { - var command []string - command = append(command, "trufflehog", "circleci") - - inputs := m.GetInputs() - command = append(command, "--token="+inputs["token"].Value) - - return strings.Join(command, " ") -} - -func (m circleCiCmdModel) Summary() string { - inputs := m.GetInputs() - labels := m.GetLabels() - keys := []string{"token"} - - return common.SummarizeSource(keys, inputs, labels) -} diff --git a/pkg/tui/sources/docker/docker.go b/pkg/tui/sources/docker/docker.go deleted file mode 100644 index 32b407afba30..000000000000 --- a/pkg/tui/sources/docker/docker.go +++ /dev/null @@ -1,50 +0,0 @@ -package docker - -import ( - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" -) - -type dockerCmdModel struct { - textinputs.Model -} - -func GetFields() dockerCmdModel { - images := textinputs.InputConfig{ - Label: "Docker image(s)", - Key: "images", - Required: true, - Help: "Separate by space if multiple.", - Placeholder: "trufflesecurity/secrets", - } - - return dockerCmdModel{textinputs.New([]textinputs.InputConfig{images})} -} - -func (m dockerCmdModel) Cmd() string { - - var command []string - command = append(command, "trufflehog", "docker") - - inputs := m.GetInputs() - vals := inputs["images"].Value - - if vals != "" { - images := strings.Fields(vals) - for _, image := range images { - command = append(command, "--image="+image) - } - } - - return strings.Join(command, " ") -} - -func (m dockerCmdModel) Summary() string { - inputs := m.GetInputs() - labels := m.GetLabels() - keys := []string{"images"} - - return common.SummarizeSource(keys, inputs, labels) -} diff --git a/pkg/tui/sources/elasticsearch/elasticsearch.go b/pkg/tui/sources/elasticsearch/elasticsearch.go deleted file mode 100644 index 105174108e9c..000000000000 --- a/pkg/tui/sources/elasticsearch/elasticsearch.go +++ /dev/null @@ -1,116 +0,0 @@ -package elasticsearch - -import ( - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" -) - -type elasticSearchCmdModel struct { - textinputs.Model -} - -func GetNote() string { - return "To connect to a local cluster, please provide the node IPs and either (username AND password) OR service token. ā­\nā­ To connect to a cloud cluster, please provide cloud ID AND API key." -} - -func GetFields() elasticSearchCmdModel { - return elasticSearchCmdModel{textinputs.New([]textinputs.InputConfig{ - { - Label: "Elastic node(s)", - Key: "nodes", - Required: false, - Help: "Elastic node IPs - for scanning local clusters. Separate by space if multiple.", - }, - { - Label: "Username", - Key: "username", - Required: false, - Help: "Elasticsearch username. Pairs with password. For scanning local clusters.", - }, - { - Label: "Password", - Key: "password", - Required: false, - Help: "Elasticsearch password. Pairs with username. For scanning local clusters.", - }, - { - Label: "Service Token", - Key: "serviceToken", - Required: false, - Help: "Elastic service token. For scanning local clusters.", - }, - { - Label: "Cloud ID", - Key: "cloudId", - Required: false, - Help: "Elastic cloud ID. Pairs with API key. For scanning cloud clusters.", - }, - { - Label: "API Key", - Key: "apiKey", - Required: false, - Help: "Elastic API key. Pairs with cloud ID. For scanning cloud clusters.", - }})} -} - -func findFirstNonEmptyKey(inputs map[string]textinputs.Input, keys []string) string { - for _, key := range keys { - if val, ok := inputs[key]; ok && val.Value != "" { - return key - } - } - return "" -} - -func getConnectionKeys(inputs map[string]textinputs.Input) []string { - keys := []string{"username", "password", "serviceToken", "cloudId", "apiKey"} - key := findFirstNonEmptyKey(inputs, keys) - - keyMap := map[string][]string{ - "username": {"username", "password", "nodes"}, - "password": {"username", "password", "nodes"}, - "serviceToken": {"serviceToken", "nodes"}, - "cloudId": {"cloudId", "apiKey"}, - "apiKey": {"cloudId", "apiKey"}, - } - - if val, ok := keyMap[key]; ok { - return val - } - - return nil -} - -func (m elasticSearchCmdModel) Cmd() string { - var command []string - command = append(command, "trufflehog", "elasticsearch") - inputs := m.GetInputs() - - for _, key := range getConnectionKeys(inputs) { - val, ok := inputs[key] - if !ok || val.Value == "" { - continue - } - - if key == "nodes" { - nodes := strings.Fields(val.Value) - for _, node := range nodes { - command = append(command, "--nodes="+node) - } - } else { - command = append(command, "--"+key+"="+val.Value) - } - } - - return strings.Join(command, " ") -} - -func (m elasticSearchCmdModel) Summary() string { - inputs := m.GetInputs() - labels := m.GetLabels() - - summaryKeys := getConnectionKeys(inputs) - return common.SummarizeSource(summaryKeys, inputs, labels) -} diff --git a/pkg/tui/sources/filesystem/filesystem.go b/pkg/tui/sources/filesystem/filesystem.go deleted file mode 100644 index e501518f23ab..000000000000 --- a/pkg/tui/sources/filesystem/filesystem.go +++ /dev/null @@ -1,42 +0,0 @@ -package filesystem - -import ( - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" -) - -type fsModel struct { - textinputs.Model -} - -func GetFields() fsModel { - path := textinputs.InputConfig{ - Label: "Path", - Key: "path", - Required: true, - Help: "Files and directories to scan. Separate by space if multiple.", - Placeholder: "path/to/file.txt path/to/another/dir", - } - - return fsModel{textinputs.New([]textinputs.InputConfig{path})} -} - -func (m fsModel) Cmd() string { - var command []string - command = append(command, "trufflehog", "filesystem") - - inputs := m.GetInputs() - command = append(command, inputs["path"].Value) - - return strings.Join(command, " ") -} - -func (m fsModel) Summary() string { - inputs := m.GetInputs() - labels := m.GetLabels() - - keys := []string{"path"} - return common.SummarizeSource(keys, inputs, labels) -} diff --git a/pkg/tui/sources/gcs/gcs.go b/pkg/tui/sources/gcs/gcs.go deleted file mode 100644 index fa78510d12af..000000000000 --- a/pkg/tui/sources/gcs/gcs.go +++ /dev/null @@ -1,43 +0,0 @@ -package gcs - -import ( - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" -) - -type gcsCmdModel struct { - textinputs.Model -} - -func GetFields() gcsCmdModel { - projectId := textinputs.InputConfig{ - Label: "Project ID", - Key: "project-id", - Required: true, - Placeholder: "trufflehog-testing", - } - - return gcsCmdModel{textinputs.New([]textinputs.InputConfig{projectId})} -} - -func (m gcsCmdModel) Cmd() string { - var command []string - command = append(command, "trufflehog", "gcs") - - inputs := m.GetInputs() - - command = append(command, "--project-id="+inputs["project-id"].Value) - - command = append(command, "--cloud-environment") - return strings.Join(command, " ") -} - -func (m gcsCmdModel) Summary() string { - inputs := m.GetInputs() - labels := m.GetLabels() - - keys := []string{"project-id"} - return common.SummarizeSource(keys, inputs, labels) -} diff --git a/pkg/tui/sources/git/git.go b/pkg/tui/sources/git/git.go deleted file mode 100644 index 54e137461672..000000000000 --- a/pkg/tui/sources/git/git.go +++ /dev/null @@ -1,43 +0,0 @@ -package git - -import ( - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" -) - -type gitCmdModel struct { - textinputs.Model -} - -func GetFields() gitCmdModel { - uri := textinputs.InputConfig{ - Label: "Git URI", - Key: "uri", - Help: "file:// for local git repos", - Required: true, - Placeholder: "git@github.com:trufflesecurity/trufflehog.git", - } - - return gitCmdModel{textinputs.New([]textinputs.InputConfig{uri})} -} - -func (m gitCmdModel) Cmd() string { - var command []string - command = append(command, "trufflehog", "git") - - inputs := m.GetInputs() - - command = append(command, inputs["uri"].Value) - - return strings.Join(command, " ") -} - -func (m gitCmdModel) Summary() string { - inputs := m.GetInputs() - labels := m.GetLabels() - - keys := []string{"uri"} - return common.SummarizeSource(keys, inputs, labels) -} diff --git a/pkg/tui/sources/github/github.go b/pkg/tui/sources/github/github.go deleted file mode 100644 index 13b841ddea39..000000000000 --- a/pkg/tui/sources/github/github.go +++ /dev/null @@ -1,75 +0,0 @@ -package github - -import ( - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" -) - -type githubCmdModel struct { - textinputs.Model -} - -func GetNote() string { - return "Please enter an organization OR repository." -} - -func GetFields() githubCmdModel { - org := textinputs.InputConfig{ - Label: "Organization", - Key: "org", - Required: true, - Help: "GitHub organization to scan.", - Placeholder: "trufflesecurity", - } - - repo := textinputs.InputConfig{ - Label: "Repository", - Key: "repo", - Required: true, - Help: "GitHub repo to scan.", - Placeholder: "https://github.com/trufflesecurity/test_keys", - } - - return githubCmdModel{textinputs.New([]textinputs.InputConfig{org, repo})} -} - -// Handle default values since GitHub flags are OR operations -func (m githubCmdModel) GetSpecialInputs() map[string]textinputs.Input { - inputs := m.GetInputs() - if inputs["org"].IsDefault != inputs["repo"].IsDefault { - if inputs["org"].IsDefault { - delete(inputs, "org") - } - if inputs["repo"].IsDefault { - delete(inputs, "repo") - } - } - - return inputs -} - -func (m githubCmdModel) Cmd() string { - var command []string - command = append(command, "trufflehog", "github") - inputs := m.GetSpecialInputs() - - if inputs["org"].Value != "" { - command = append(command, "--org="+inputs["org"].Value) - } - - if inputs["repo"].Value != "" { - command = append(command, "--repo="+inputs["repo"].Value) - } - - return strings.Join(command, " ") -} - -func (m githubCmdModel) Summary() string { - inputs := m.GetSpecialInputs() - labels := m.GetLabels() - - keys := []string{"org", "repo"} - return common.SummarizeSource(keys, inputs, labels) -} diff --git a/pkg/tui/sources/gitlab/gitlab.go b/pkg/tui/sources/gitlab/gitlab.go deleted file mode 100644 index a35664051b6b..000000000000 --- a/pkg/tui/sources/gitlab/gitlab.go +++ /dev/null @@ -1,43 +0,0 @@ -package gitlab - -import ( - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" -) - -type gitlabCmdModel struct { - textinputs.Model -} - -func GetFields() gitlabCmdModel { - token := textinputs.InputConfig{ - Label: "GitLab token", - Key: "token", - Required: true, - Help: "Personal access token with read access", - Placeholder: "glpat-", - } - - return gitlabCmdModel{textinputs.New([]textinputs.InputConfig{token})} -} - -func (m gitlabCmdModel) Cmd() string { - var command []string - command = append(command, "trufflehog", "gitlab") - - inputs := m.GetInputs() - - command = append(command, "--token="+inputs["token"].Value) - - return strings.Join(command, " ") -} - -func (m gitlabCmdModel) Summary() string { - inputs := m.GetInputs() - labels := m.GetLabels() - - keys := []string{"token"} - return common.SummarizeSource(keys, inputs, labels) -} diff --git a/pkg/tui/sources/huggingface/huggingface.go b/pkg/tui/sources/huggingface/huggingface.go deleted file mode 100644 index bee86206dcc4..000000000000 --- a/pkg/tui/sources/huggingface/huggingface.go +++ /dev/null @@ -1,77 +0,0 @@ -package huggingface - -import ( - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" -) - -type huggingFaceCmdModel struct { - textinputs.Model -} - -func GetNote() string { - return "Please enter the organization, user, model, space, or dataset you would like to scan." -} - -func GetFields() huggingFaceCmdModel { - org := textinputs.InputConfig{ - Label: "Organization", - Key: "org", - Required: false, - Help: "Hugging Face organization name. This will scan all models, datasets, and spaces belonging to the organization.", - } - user := textinputs.InputConfig{ - Label: "Username", - Key: "user", - Required: false, - Help: "Hugging Face user. This will scan all models, datasets, and spaces belonging to the user.", - } - model := textinputs.InputConfig{ - Label: "Model", - Key: "model", - Required: false, - Help: "Hugging Face model. Example: org/model_name or user/model_name", - } - space := textinputs.InputConfig{ - Label: "Space", - Key: "space", - Required: false, - Help: "Hugging Face space. Example: org/space_name or user/space_name.", - } - dataset := textinputs.InputConfig{ - Label: "Dataset", - Key: "dataset", - Required: false, - Help: "Hugging Face dataset. Example: org/dataset_name or user/dataset_name.", - } - - return huggingFaceCmdModel{textinputs.New([]textinputs.InputConfig{org, user, model, space, dataset})} -} - -func (m huggingFaceCmdModel) Cmd() string { - var command []string - command = append(command, "trufflehog", "huggingface") - - inputs := m.GetInputs() - keys := []string{"org", "user", "model", "space", "dataset"} - - for _, key := range keys { - val, ok := inputs[key] - if !ok || val.Value == "" { - continue - } - - command = append(command, "--"+key+"="+val.Value) - } - - return strings.Join(command, " ") -} - -func (m huggingFaceCmdModel) Summary() string { - inputs := m.GetInputs() - labels := m.GetLabels() - keys := []string{"org", "user", "model", "space", "dataset"} - return common.SummarizeSource(keys, inputs, labels) -} diff --git a/pkg/tui/sources/jenkins/jenkins.go b/pkg/tui/sources/jenkins/jenkins.go deleted file mode 100644 index 59886fbe61a7..000000000000 --- a/pkg/tui/sources/jenkins/jenkins.go +++ /dev/null @@ -1,79 +0,0 @@ -package jenkins - -import ( - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" -) - -type jenkinsCmdModel struct { - textinputs.Model -} - -func GetNote() string { - return "If no username and password are provided, TruffleHog will attempt an unauthenticated Jenkins scan." -} - -func GetFields() jenkinsCmdModel { - return jenkinsCmdModel{textinputs.New([]textinputs.InputConfig{ - { - Label: "Endpoint URL", - Key: "url", - Required: true, - Help: "URL of the Jenkins server.", - Placeholder: "https://jenkins.example.com", - }, - { - Label: "Username", - Key: "username", - Required: false, - Help: "For authenticated scans - pairs with password.", - }, - { - Label: "Password", - Key: "password", - Required: false, - Help: "For authenticated scans - pairs with username.", - }})} -} - -func checkIsAuthenticated(inputs map[string]textinputs.Input) bool { - username := inputs["username"].Value - password := inputs["password"].Value - - return username != "" && password != "" -} - -func (m jenkinsCmdModel) Cmd() string { - var command []string - command = append(command, "trufflehog", "jenkins") - inputs := m.GetInputs() - - keys := []string{"url"} - if checkIsAuthenticated(inputs) { - keys = append(keys, "username", "password") - } - - for _, key := range keys { - val, ok := inputs[key] - if !ok || val.Value == "" { - continue - } - command = append(command, "--"+key+"="+val.Value) - } - - return strings.Join(command, " ") -} - -func (m jenkinsCmdModel) Summary() string { - inputs := m.GetInputs() - labels := m.GetLabels() - - summaryKeys := []string{"url"} - if checkIsAuthenticated(inputs) { - summaryKeys = append(summaryKeys, "username", "password") - } - - return common.SummarizeSource(summaryKeys, inputs, labels) -} diff --git a/pkg/tui/sources/postman/postman.go b/pkg/tui/sources/postman/postman.go deleted file mode 100644 index 7b0451f86e46..000000000000 --- a/pkg/tui/sources/postman/postman.go +++ /dev/null @@ -1,83 +0,0 @@ -package postman - -import ( - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" -) - -type postmanCmdModel struct { - textinputs.Model -} - -func GetNote() string { - return "Please enter an ID for a workspace, collection, or environment." -} - -func GetFields() postmanCmdModel { - token := textinputs.InputConfig{ - Label: "Postman token", - Key: "token", - Required: true, - Help: "Postman API key", - Placeholder: "PMAK-", - } - workspace := textinputs.InputConfig{ - Label: "Workspace ID", - Key: "workspace", - Required: false, - Help: "ID for workspace", - } - collection := textinputs.InputConfig{ - Label: "Collection ID", - Key: "collection", - Required: false, - Help: "ID for an API collection", - } - environment := textinputs.InputConfig{ - Label: "Environment ID", - Key: "environment", - Required: false, - Help: "ID for an environment", - } - - return postmanCmdModel{textinputs.New([]textinputs.InputConfig{token, workspace, collection, environment})} -} - -func findFirstNonEmptyKey(inputs map[string]textinputs.Input, keys []string) string { - for _, key := range keys { - if val, ok := inputs[key]; ok && val.Value != "" { - return key - } - } - return "" -} - -func (m postmanCmdModel) Cmd() string { - var command []string - command = append(command, "trufflehog", "postman") - - inputs := m.GetInputs() - keys := []string{"workspace", "collection", "environment"} - - command = append(command, "--token="+inputs["token"].Value) - key := findFirstNonEmptyKey(inputs, keys) - if key != "" { - command = append(command, "--"+key+"="+inputs[key].Value) - } - return strings.Join(command, " ") -} - -func (m postmanCmdModel) Summary() string { - inputs := m.GetInputs() - labels := m.GetLabels() - keys := []string{"token", "workspace", "collection", "environment"} - - summaryKeys := []string{"token"} - key := findFirstNonEmptyKey(inputs, keys[1:]) - if key != "" { - summaryKeys = append(summaryKeys, key) - } - return common.SummarizeSource(summaryKeys, inputs, labels) -} diff --git a/pkg/tui/sources/s3/s3.go b/pkg/tui/sources/s3/s3.go deleted file mode 100644 index dadb43784631..000000000000 --- a/pkg/tui/sources/s3/s3.go +++ /dev/null @@ -1,48 +0,0 @@ -package s3 - -import ( - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" -) - -type s3CmdModel struct { - textinputs.Model -} - -func GetFields() s3CmdModel { - bucket := textinputs.InputConfig{ - Label: "S3 bucket name(s)", - Key: "buckets", - Required: true, - Placeholder: "truffletestbucket", - Help: "Buckets to scan. Separate by space if multiple.", - } - - return s3CmdModel{textinputs.New([]textinputs.InputConfig{bucket})} -} - -func (m s3CmdModel) Cmd() string { - var command []string - command = append(command, "trufflehog", "s3") - - inputs := m.GetInputs() - vals := inputs["buckets"].Value - if vals != "" { - buckets := strings.Fields(vals) - for _, bucket := range buckets { - command = append(command, "--bucket="+bucket) - } - } - - return strings.Join(command, " ") -} - -func (m s3CmdModel) Summary() string { - inputs := m.GetInputs() - labels := m.GetLabels() - - keys := []string{"buckets"} - return common.SummarizeSource(keys, inputs, labels) -} diff --git a/pkg/tui/sources/sources.go b/pkg/tui/sources/sources.go deleted file mode 100644 index 47166c43cfa8..000000000000 --- a/pkg/tui/sources/sources.go +++ /dev/null @@ -1,80 +0,0 @@ -package sources - -import ( - "strings" - - tea "github.com/charmbracelet/bubbletea" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/sources/circleci" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/sources/docker" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/sources/elasticsearch" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/sources/filesystem" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/sources/gcs" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/sources/git" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/sources/github" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/sources/gitlab" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/sources/huggingface" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/sources/jenkins" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/sources/postman" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/sources/s3" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/sources/syslog" -) - -func GetSourceNotes(sourceName string) string { - source := strings.ToLower(sourceName) - switch source { - case "github": - return github.GetNote() - case "postman": - return postman.GetNote() - case "elasticsearch": - return elasticsearch.GetNote() - case "huggingface": - return huggingface.GetNote() - case "jenkins": - return jenkins.GetNote() - - default: - return "" - } -} - -type CmdModel interface { - tea.Model - Cmd() string - Summary() string -} - -func GetSourceFields(sourceName string) CmdModel { - source := strings.ToLower(sourceName) - - switch source { - case "aws s3": - return s3.GetFields() - case "circleci": - return circleci.GetFields() - case "docker": - return docker.GetFields() - case "elasticsearch": - return elasticsearch.GetFields() - case "filesystem": - return filesystem.GetFields() - case "gcs (google cloud storage)": - return gcs.GetFields() - case "git": - return git.GetFields() - case "github": - return github.GetFields() - case "gitlab": - return gitlab.GetFields() - case "hugging face": - return huggingface.GetFields() - case "jenkins": - return jenkins.GetFields() - case "postman": - return postman.GetFields() - case "syslog": - return syslog.GetFields() - } - - return nil -} diff --git a/pkg/tui/sources/syslog/syslog.go b/pkg/tui/sources/syslog/syslog.go deleted file mode 100644 index 26a1b0d96774..000000000000 --- a/pkg/tui/sources/syslog/syslog.go +++ /dev/null @@ -1,80 +0,0 @@ -package syslog - -import ( - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs" -) - -type syslogCmdModel struct { - textinputs.Model -} - -// TODO: review fields -func GetFields() syslogCmdModel { - protocol := textinputs.InputConfig{ - Label: "Protocol", - Key: "protocol", - Required: true, - Help: "udp or tcp", - Placeholder: "tcp", - } - - listenAddress := textinputs.InputConfig{ - Label: "Address", - Key: "address", - Help: "Address and port to listen on for syslog", - Required: true, - Placeholder: "127.0.0.1:514", - } - - tlsCert := textinputs.InputConfig{ - Label: "TLS Certificate", - Key: "cert", - Required: true, - Help: "Path to TLS certificate", - Placeholder: "/path/to/cert", - } - - tlsKey := textinputs.InputConfig{ - Label: "TLS Key", - Key: "key", - Required: true, - Help: "Path to TLS key", - Placeholder: "/path/to/key", - } - - format := textinputs.InputConfig{ - Label: "Log format", - Key: "format", - Required: true, - Help: "Can be rfc3164 or rfc5424", - Placeholder: "rfc3164", - } - - return syslogCmdModel{textinputs.New([]textinputs.InputConfig{listenAddress, protocol, tlsCert, tlsKey, format})} -} - -func (m syslogCmdModel) Cmd() string { - var command []string - command = append(command, "trufflehog", "syslog") - - inputs := m.GetInputs() - syslogKeys := [5]string{"address", "protocol", "cert", "key", "format"} - - for _, key := range syslogKeys { - flag := "--" + key + "=" + inputs[key].Value - command = append(command, flag) - } - - return strings.Join(command, " ") -} - -func (m syslogCmdModel) Summary() string { - inputs := m.GetInputs() - labels := m.GetLabels() - keys := []string{"address", "protocol", "cert", "key", "format"} - - return common.SummarizeSource(keys, inputs, labels) -} diff --git a/pkg/tui/styles/styles.go b/pkg/tui/styles/styles.go deleted file mode 100644 index 09c9252119b2..000000000000 --- a/pkg/tui/styles/styles.go +++ /dev/null @@ -1,493 +0,0 @@ -package styles - -import ( - "github.com/charmbracelet/lipgloss" -) - -// XXX: For now, this is in its own package so that it can be shared between -// different packages without incurring an illegal import cycle. - -// https://github.com/charmbracelet/lipgloss#colors -var Colors = map[string]string{ - "softblack": "#1e1e1e", - "charcoal": "#252525", - "stone": "#5a5a5a", - "smoke": "#999999", - "sand": "#e1deda", - "cloud": "#f4efe9", - "offwhite": "#faf8f7", - "fern": "#38645a", - "sprout": "#5bb381", - "gold": "#ae8c57", - "bronze": "#89553d", - "coral": "#c15750", - "violet": "#6b5b9a", -} - -var ( - BoldTextStyle = lipgloss.NewStyle().Bold(true) - - PrimaryTextStyle = lipgloss.NewStyle().Foreground( - lipgloss.Color("28")) // green - - HintTextStyle = lipgloss.NewStyle().Foreground( - lipgloss.Color("8")) // grey - - CodeTextStyle = lipgloss.NewStyle().Background(lipgloss.Color("130")).Foreground(lipgloss.Color("15")) -) - -var AppStyle = lipgloss.NewStyle().Padding(1, 2) - -// Styles defines styles for the UI. -type Styles struct { - ActiveBorderColor lipgloss.Color - InactiveBorderColor lipgloss.Color - - App lipgloss.Style - ServerName lipgloss.Style - TopLevelNormalTab lipgloss.Style - TopLevelActiveTab lipgloss.Style - TopLevelActiveTabDot lipgloss.Style - - MenuItem lipgloss.Style - MenuLastUpdate lipgloss.Style - - RepoSelector struct { - Normal struct { - Base lipgloss.Style - Title lipgloss.Style - Desc lipgloss.Style - Command lipgloss.Style - Updated lipgloss.Style - } - Active struct { - Base lipgloss.Style - Title lipgloss.Style - Desc lipgloss.Style - Command lipgloss.Style - Updated lipgloss.Style - } - } - - Repo struct { - Base lipgloss.Style - Title lipgloss.Style - Command lipgloss.Style - Body lipgloss.Style - Header lipgloss.Style - HeaderName lipgloss.Style - HeaderDesc lipgloss.Style - } - - Footer lipgloss.Style - Branch lipgloss.Style - HelpKey lipgloss.Style - HelpValue lipgloss.Style - HelpDivider lipgloss.Style - URLStyle lipgloss.Style - - Error lipgloss.Style - ErrorTitle lipgloss.Style - ErrorBody lipgloss.Style - - AboutNoReadme lipgloss.Style - - LogItem struct { - Normal struct { - Base lipgloss.Style - Hash lipgloss.Style - Title lipgloss.Style - Desc lipgloss.Style - Keyword lipgloss.Style - } - Active struct { - Base lipgloss.Style - Hash lipgloss.Style - Title lipgloss.Style - Desc lipgloss.Style - Keyword lipgloss.Style - } - } - - Log struct { - Commit lipgloss.Style - CommitHash lipgloss.Style - CommitAuthor lipgloss.Style - CommitDate lipgloss.Style - CommitBody lipgloss.Style - CommitStatsAdd lipgloss.Style - CommitStatsDel lipgloss.Style - Paginator lipgloss.Style - } - - Ref struct { - Normal struct { - Item lipgloss.Style - ItemTag lipgloss.Style - } - Active struct { - Item lipgloss.Style - ItemTag lipgloss.Style - } - ItemSelector lipgloss.Style - ItemBranch lipgloss.Style - Paginator lipgloss.Style - } - - Tree struct { - Normal struct { - FileName lipgloss.Style - FileDir lipgloss.Style - FileMode lipgloss.Style - FileSize lipgloss.Style - } - Active struct { - FileName lipgloss.Style - FileDir lipgloss.Style - FileMode lipgloss.Style - FileSize lipgloss.Style - } - Selector lipgloss.Style - FileContent lipgloss.Style - Paginator lipgloss.Style - NoItems lipgloss.Style - } - - Spinner lipgloss.Style - - CodeNoContent lipgloss.Style - - StatusBar lipgloss.Style - StatusBarKey lipgloss.Style - StatusBarValue lipgloss.Style - StatusBarInfo lipgloss.Style - StatusBarBranch lipgloss.Style - StatusBarHelp lipgloss.Style - - Tabs lipgloss.Style - TabInactive lipgloss.Style - TabActive lipgloss.Style - TabSeparator lipgloss.Style -} - -// DefaultStyles returns default styles for the UI. -func DefaultStyles() *Styles { - highlightColor := lipgloss.Color("210") - highlightColorDim := lipgloss.Color("174") - selectorColor := lipgloss.Color("167") - hashColor := lipgloss.Color("185") - - s := new(Styles) - - s.ActiveBorderColor = lipgloss.Color("62") - s.InactiveBorderColor = lipgloss.Color("241") - - s.App = lipgloss.NewStyle(). - Margin(1, 2) - - s.ServerName = lipgloss.NewStyle(). - Height(1). - MarginLeft(1). - MarginBottom(1). - Padding(0, 1). - Background(lipgloss.Color("57")). - Foreground(lipgloss.Color("229")). - Bold(true) - - s.TopLevelNormalTab = lipgloss.NewStyle(). - MarginRight(2) - - s.TopLevelActiveTab = s.TopLevelNormalTab.Copy(). - Foreground(lipgloss.Color("36")) - - s.TopLevelActiveTabDot = lipgloss.NewStyle(). - Foreground(lipgloss.Color("36")) - - s.RepoSelector.Normal.Base = lipgloss.NewStyle(). - PaddingLeft(1). - Border(lipgloss.Border{Left: " "}, false, false, false, true). - Height(3) - - s.RepoSelector.Normal.Title = lipgloss.NewStyle().Bold(true) - - s.RepoSelector.Normal.Desc = lipgloss.NewStyle(). - Foreground(lipgloss.Color("243")) - - s.RepoSelector.Normal.Command = lipgloss.NewStyle(). - Foreground(lipgloss.Color("132")) - - s.RepoSelector.Normal.Updated = lipgloss.NewStyle(). - Foreground(lipgloss.Color("243")) - - s.RepoSelector.Active.Base = s.RepoSelector.Normal.Base.Copy(). - BorderStyle(lipgloss.Border{Left: "ā”ƒ"}). - BorderForeground(lipgloss.Color("176")) - - s.RepoSelector.Active.Title = s.RepoSelector.Normal.Title.Copy(). - Foreground(lipgloss.Color("212")) - - s.RepoSelector.Active.Desc = s.RepoSelector.Normal.Desc.Copy(). - Foreground(lipgloss.Color("246")) - - s.RepoSelector.Active.Updated = s.RepoSelector.Normal.Updated.Copy(). - Foreground(lipgloss.Color("212")) - - s.RepoSelector.Active.Command = s.RepoSelector.Normal.Command.Copy(). - Foreground(lipgloss.Color("204")) - - s.MenuItem = lipgloss.NewStyle(). - PaddingLeft(1). - Border(lipgloss.Border{ - Left: " ", - }, false, false, false, true). - Height(3) - - s.MenuLastUpdate = lipgloss.NewStyle(). - Foreground(lipgloss.Color("241")). - Align(lipgloss.Right) - - s.Repo.Base = lipgloss.NewStyle() - - s.Repo.Title = lipgloss.NewStyle(). - Padding(0, 2) - - s.Repo.Command = lipgloss.NewStyle(). - Foreground(lipgloss.Color("168")) - - s.Repo.Body = lipgloss.NewStyle(). - Margin(1, 0) - - s.Repo.Header = lipgloss.NewStyle(). - Height(2). - Border(lipgloss.NormalBorder(), false, false, true, false). - BorderForeground(lipgloss.Color("236")) - - s.Repo.HeaderName = lipgloss.NewStyle(). - Foreground(lipgloss.Color("212")). - Bold(true) - - s.Repo.HeaderDesc = lipgloss.NewStyle(). - Foreground(lipgloss.Color("243")) - - s.Footer = lipgloss.NewStyle(). - MarginTop(1). - Padding(0, 1). - Height(1) - - s.Branch = lipgloss.NewStyle(). - Foreground(lipgloss.Color("203")). - Background(lipgloss.Color("236")). - Padding(0, 1) - - s.HelpKey = lipgloss.NewStyle(). - Foreground(lipgloss.Color("241")) - - s.HelpValue = lipgloss.NewStyle(). - Foreground(lipgloss.Color("239")) - - s.HelpDivider = lipgloss.NewStyle(). - Foreground(lipgloss.Color("237")). - SetString(" ā€¢ ") - - s.URLStyle = lipgloss.NewStyle(). - MarginLeft(1). - Foreground(lipgloss.Color("168")) - - s.Error = lipgloss.NewStyle(). - MarginTop(2) - - s.ErrorTitle = lipgloss.NewStyle(). - Foreground(lipgloss.Color("230")). - Background(lipgloss.Color("204")). - Bold(true). - Padding(0, 1) - - s.ErrorBody = lipgloss.NewStyle(). - Foreground(lipgloss.Color("252")). - MarginLeft(2) - - s.AboutNoReadme = lipgloss.NewStyle(). - MarginTop(1). - MarginLeft(2). - Foreground(lipgloss.Color("242")) - - s.LogItem.Normal.Base = lipgloss.NewStyle(). - Border(lipgloss.Border{ - Left: " ", - }, false, false, false, true). - PaddingLeft(1) - - s.LogItem.Active.Base = s.LogItem.Normal.Base.Copy(). - Border(lipgloss.Border{ - Left: "ā”ƒ", - }, false, false, false, true). - BorderForeground(selectorColor) - - s.LogItem.Active.Hash = s.LogItem.Normal.Hash.Copy(). - Foreground(hashColor) - - s.LogItem.Active.Hash = lipgloss.NewStyle(). - Bold(true). - Foreground(highlightColor) - - s.LogItem.Normal.Title = lipgloss.NewStyle(). - Foreground(lipgloss.Color("105")) - - s.LogItem.Active.Title = lipgloss.NewStyle(). - Foreground(highlightColor). - Bold(true) - - s.LogItem.Normal.Desc = lipgloss.NewStyle(). - Foreground(lipgloss.Color("246")) - - s.LogItem.Active.Desc = lipgloss.NewStyle(). - Foreground(lipgloss.Color("95")) - - s.LogItem.Active.Keyword = s.LogItem.Active.Desc.Copy(). - Foreground(highlightColorDim) - - s.LogItem.Normal.Hash = lipgloss.NewStyle(). - Foreground(hashColor) - - s.LogItem.Active.Hash = lipgloss.NewStyle(). - Foreground(highlightColor) - - s.Log.Commit = lipgloss.NewStyle(). - Margin(0, 2) - - s.Log.CommitHash = lipgloss.NewStyle(). - Foreground(hashColor). - Bold(true) - - s.Log.CommitBody = lipgloss.NewStyle(). - MarginTop(1). - MarginLeft(2) - - s.Log.CommitStatsAdd = lipgloss.NewStyle(). - Foreground(lipgloss.Color("42")). - Bold(true) - - s.Log.CommitStatsDel = lipgloss.NewStyle(). - Foreground(lipgloss.Color("203")). - Bold(true) - - s.Log.Paginator = lipgloss.NewStyle(). - Margin(0). - Align(lipgloss.Center) - - s.Ref.Normal.Item = lipgloss.NewStyle() - - s.Ref.ItemSelector = lipgloss.NewStyle(). - Foreground(selectorColor). - SetString("> ") - - s.Ref.Active.Item = lipgloss.NewStyle(). - Foreground(highlightColorDim) - - s.Ref.ItemBranch = lipgloss.NewStyle() - - s.Ref.Normal.ItemTag = lipgloss.NewStyle(). - Foreground(lipgloss.Color("39")) - - s.Ref.Active.ItemTag = lipgloss.NewStyle(). - Bold(true). - Foreground(highlightColor) - - s.Ref.Active.Item = lipgloss.NewStyle(). - Bold(true). - Foreground(highlightColor) - - s.Ref.Paginator = s.Log.Paginator.Copy() - - s.Tree.Selector = s.Tree.Normal.FileName.Copy(). - Width(1). - Foreground(selectorColor) - - s.Tree.Normal.FileName = lipgloss.NewStyle(). - MarginLeft(1) - - s.Tree.Active.FileName = s.Tree.Normal.FileName.Copy(). - Bold(true). - Foreground(highlightColor) - - s.Tree.Normal.FileDir = lipgloss.NewStyle(). - Foreground(lipgloss.Color("39")) - - s.Tree.Active.FileDir = lipgloss.NewStyle(). - Foreground(highlightColor) - - s.Tree.Normal.FileMode = s.Tree.Active.FileName.Copy(). - Width(10). - Foreground(lipgloss.Color("243")) - - s.Tree.Active.FileMode = s.Tree.Normal.FileMode.Copy(). - Foreground(highlightColorDim) - - s.Tree.Normal.FileSize = s.Tree.Normal.FileName.Copy(). - Foreground(lipgloss.Color("243")) - - s.Tree.Active.FileSize = s.Tree.Normal.FileName.Copy(). - Foreground(highlightColorDim) - - s.Tree.FileContent = lipgloss.NewStyle() - - s.Tree.Paginator = s.Log.Paginator.Copy() - - s.Tree.NoItems = s.AboutNoReadme.Copy() - - s.Spinner = lipgloss.NewStyle(). - MarginTop(1). - MarginLeft(2). - Foreground(lipgloss.Color("205")) - - s.CodeNoContent = lipgloss.NewStyle(). - SetString("No Content."). - MarginTop(1). - MarginLeft(2). - Foreground(lipgloss.Color("242")) - - s.StatusBar = lipgloss.NewStyle(). - Height(1) - - s.StatusBarKey = lipgloss.NewStyle(). - Bold(true). - Padding(0, 1). - Background(lipgloss.Color("206")). - Foreground(lipgloss.Color("228")) - - s.StatusBarValue = lipgloss.NewStyle(). - Padding(0, 1). - Background(lipgloss.Color("235")). - Foreground(lipgloss.Color("243")) - - s.StatusBarInfo = lipgloss.NewStyle(). - Padding(0, 1). - Background(lipgloss.Color("212")). - Foreground(lipgloss.Color("230")) - - s.StatusBarBranch = lipgloss.NewStyle(). - Padding(0, 1). - Background(lipgloss.Color("62")). - Foreground(lipgloss.Color("230")) - - s.StatusBarHelp = lipgloss.NewStyle(). - Padding(0, 1). - Background(lipgloss.Color("237")). - Foreground(lipgloss.Color("243")) - - s.Tabs = lipgloss.NewStyle(). - Height(1) - - s.TabInactive = lipgloss.NewStyle() - - s.TabActive = lipgloss.NewStyle(). - Underline(true). - Foreground(lipgloss.Color("36")) - - s.TabSeparator = lipgloss.NewStyle(). - SetString("ā”‚"). - Padding(0, 1). - Foreground(lipgloss.Color("238")) - - return s -} diff --git a/pkg/tui/tui.go b/pkg/tui/tui.go deleted file mode 100644 index e7f29f8ee126..000000000000 --- a/pkg/tui/tui.go +++ /dev/null @@ -1,197 +0,0 @@ -package tui - -import ( - "fmt" - "os" - "strings" - - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - zone "github.com/lrstanley/bubblezone" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/selector" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/keymap" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/pages/contact_enterprise" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/pages/source_configure" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/pages/source_select" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/pages/view_oss" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/pages/wizard_intro" - "github.com/trufflesecurity/trufflehog/v3/pkg/tui/styles" -) - -type page int - -const ( - wizardIntroPage page = iota - sourceSelectPage - sourceConfigurePage - viewOSSProjectPage - contactEnterprisePage -) - -type sessionState int - -const ( - startState sessionState = iota - errorState - loadedState -) - -// TUI is the main TUI model. -type TUI struct { - common common.Common - pages []common.Component - activePage page - state sessionState - args []string -} - -// New returns a new TUI model. -func New(c common.Common) *TUI { - ui := &TUI{ - common: c, - pages: make([]common.Component, 5), - activePage: wizardIntroPage, - state: startState, - } - return ui -} - -// SetSize implements common.Component. -func (ui *TUI) SetSize(width, height int) { - ui.common.SetSize(width, height) - for _, p := range ui.pages { - if p != nil { - p.SetSize(width, height) - } - } -} - -// Init implements tea.Model. -func (ui *TUI) Init() tea.Cmd { - ui.pages[wizardIntroPage] = wizard_intro.New(ui.common) - ui.pages[sourceSelectPage] = source_select.New(ui.common) - ui.pages[sourceConfigurePage] = source_configure.New(ui.common) - ui.pages[viewOSSProjectPage] = view_oss.New(ui.common) - ui.pages[contactEnterprisePage] = contact_enterprise.New(ui.common) - ui.SetSize(ui.common.Width, ui.common.Height) - cmds := make([]tea.Cmd, 0) - cmds = append(cmds, - ui.pages[wizardIntroPage].Init(), - ui.pages[sourceSelectPage].Init(), - ui.pages[sourceConfigurePage].Init(), - ui.pages[viewOSSProjectPage].Init(), - ui.pages[contactEnterprisePage].Init(), - ) - ui.state = loadedState - ui.SetSize(ui.common.Width, ui.common.Height) - return tea.Batch(cmds...) -} - -// Update implements tea.Model. -func (ui *TUI) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - cmds := make([]tea.Cmd, 0) - switch msg := msg.(type) { - case tea.WindowSizeMsg: - ui.SetSize(msg.Width, msg.Height) - for i, p := range ui.pages { - m, cmd := p.Update(msg) - ui.pages[i] = m.(common.Component) - if cmd != nil { - cmds = append(cmds, cmd) - } - } - case tea.KeyMsg, tea.MouseMsg: - switch msg := msg.(type) { - case tea.KeyMsg: - switch { - case key.Matches(msg, ui.common.KeyMap.Help): - case key.Matches(msg, ui.common.KeyMap.CmdQuit) && ui.activePage != sourceConfigurePage: - return ui, tea.Quit - case key.Matches(msg, ui.common.KeyMap.Quit): - return ui, tea.Quit - case ui.activePage > 0 && key.Matches(msg, ui.common.KeyMap.Back): - ui.activePage -= 1 - return ui, nil - } - } - case common.ErrorMsg: - return ui, nil - case selector.SelectMsg: - switch item := msg.IdentifiableItem.(type) { - case wizard_intro.Item: - switch item { - case wizard_intro.Quit: - cmds = append(cmds, tea.Quit) - case wizard_intro.ViewOSSProject: - ui.activePage = viewOSSProjectPage - case wizard_intro.ViewHelpDocs: - ui.args = []string{"--help"} - - return ui, tea.Quit - case wizard_intro.EnterpriseInquire: - ui.activePage = contactEnterprisePage - case wizard_intro.ScanSourceWithWizard: - ui.activePage = sourceSelectPage - case wizard_intro.AnalyzeSecret: - ui.args = []string{"analyze"} - return ui, tea.Quit - } - case source_select.SourceItem: - ui.activePage = sourceConfigurePage - cmds = append(cmds, func() tea.Msg { - return source_configure.SetSourceMsg{Source: item.ID()} - }) - } - case source_configure.SetArgsMsg: - ui.args = strings.Split(string(msg), " ")[1:] - return ui, tea.Quit - } - - if ui.state == loadedState { - m, cmd := ui.pages[ui.activePage].Update(msg) - ui.pages[ui.activePage] = m.(common.Component) - if cmd != nil { - cmds = append(cmds, cmd) - } - } - - // This fixes determining the height margin of the footer. - // ui.SetSize(ui.common.Width, ui.common.Height) - return ui, tea.Batch(cmds...) -} - -// View implements tea.Model. -func (ui *TUI) View() string { - var view string - switch ui.state { - case startState: - view = "Loading..." - case loadedState: - view = ui.pages[ui.activePage].View() - default: - view = "Unknown state :/ this is a bug!" - } - return ui.common.Zone.Scan( - ui.common.Styles.App.Render(view), - ) -} - -func Run() []string { - c := common.Common{ - Copy: nil, - Styles: styles.DefaultStyles(), - KeyMap: keymap.DefaultKeyMap(), - Width: 0, - Height: 0, - Zone: zone.New(), - } - m := New(c) - p := tea.NewProgram(m) - // TODO: Print normal help message. - if _, err := p.Run(); err != nil { - fmt.Printf("Alas, there's been an error: %v", err) - os.Exit(1) - } - return m.args -} diff --git a/pkg/updater/updater.go b/pkg/updater/updater.go index b8ad42020dbe..73bebc6f26f0 100644 --- a/pkg/updater/updater.go +++ b/pkg/updater/updater.go @@ -19,14 +19,13 @@ import ( "github.com/trufflesecurity/trufflehog/v3/pkg/version" ) -func Fetcher(cmd string, tui bool) fetcher.Interface { - return &OSS{Cmd: cmd, TUI: tui} +func Fetcher(cmd string) fetcher.Interface { + return &OSS{Cmd: cmd} } type OSS struct { Interval time.Duration Cmd string - TUI bool Updated bool } @@ -61,7 +60,6 @@ func (g *OSS) Fetch() (io.Reader, error) { Arch: runtime.GOARCH, CurrentVersion: version.BuildVersion, Cmd: g.Cmd, - TUI: g.TUI, Timezone: zone, Binary: "trufflehog", }