diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 29d6148..1bd215d 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -11,65 +11,111 @@ import ( pkgConfig "github.com/massalabs/DeWeb/pkg/config" "github.com/massalabs/DeWeb/pkg/website" "github.com/massalabs/station/pkg/logger" + "github.com/urfave/cli/v2" ) func main() { - err := logger.InitializeGlobal("./deweb-cli.log") - if err != nil { - log.Fatalf("failed to initialize logger: %v", err) + app := &cli.App{ + Name: "DeWeb CLI", + Usage: "CLI app for deploying websites", + UsageText: "Upload, delete & edit DeWeb site from the terminal", + Version: config.Version, + Action: func(cCtx *cli.Context) error { + err := cli.ShowAppHelp(cCtx) + if err != nil { + return fmt.Errorf("failed to show app help: %v", err) + } + return nil + }, + + Commands: []*cli.Command{ + { + Name: "upload", + Aliases: []string{"u"}, + Usage: "Upload a website", + ArgsUsage: " ", + Action: func(cCtx *cli.Context) error { + if cCtx.Args().Len() < 2 { + return fmt.Errorf("invalid number of arguments\nUsage: %s %s", cCtx.App.Name, cCtx.Command.ArgsUsage) + } + + filepath := cCtx.Args().Get(1) + config := pkgConfig.DefaultConfig(cCtx.Args().Get(0), "https://buildnet.massa.net/api/v2") + + siteAddress, err := deployWebsite(config, filepath) + if err != nil { + logger.Fatalf("failed to deploy website: %v", err) + } + + logger.Infof("successfully uploaded a website at %s", siteAddress) + + return nil + }, + }, + { + Name: "edit", + Aliases: []string{"e"}, + Usage: "Edit website", + ArgsUsage: " ", + Action: func(cCtx *cli.Context) error { + if cCtx.Args().Len() < 3 { + return fmt.Errorf("invalid number of arguments\nUsage: %s %s", cCtx.App.Name, cCtx.Command.ArgsUsage) + } + + config := pkgConfig.DefaultConfig(cCtx.Args().Get(0), "https://buildnet.massa.net/api/v2") + siteAddress := cCtx.Args().Get(1) + filepath := cCtx.Args().Get(2) + + bytecode, err := processFileForUpload(filepath) + if err != nil { + logger.Fatalf("failed to process file for upload: %v", err) + } + + err = uploadChunks(bytecode, siteAddress, config) + if err != nil { + logger.Fatalf("failed to upload chunks: %v", err) + } + + logger.Infof("%s was succesfully updated", siteAddress) + + return nil + }, + }, + { + Name: "view", + Aliases: []string{"v"}, + Usage: "View html content", + ArgsUsage: " ", + Action: func(cCtx *cli.Context) error { + if cCtx.Args().Len() < 2 { + return fmt.Errorf("invalid number of arguments\nUsage: %s %s", cCtx.App.Name, cCtx.Command.ArgsUsage) + } + + config := pkgConfig.DefaultConfig(cCtx.Args().Get(0), "https://buildnet.massa.net/api/v2") + siteAddress := cCtx.Args().Get(1) + + err := viewWebsite(siteAddress, config) + if err != nil { + logger.Fatalf("An error occured while attempting to view website %s: %v", siteAddress, err) + } + + return nil + }, + }, + }, } - logger.Infof("Hello, World from DeWeb CLI %s !", config.Version) - - if len(os.Args) < 2 { - logger.Fatalf("usage: %s ", os.Args[0]) - } - - config := pkgConfig.DefaultConfig("fullpower", "https://buildnet.massa.net/api/v2") - - address, err := deployWebsite(config) - if err != nil { - logger.Fatalf("failed to deploy website: %v", err) - } - - logger.Infof("Website uploaded successfully to address: %s", address) - - owner, err := website.GetOwner(&config.NetworkInfos, address) - if err != nil { - logger.Fatalf("failed to get website owner: %v", err) - } - - logger.Infof("Website owner: %s", owner) - - websiteBytes, err := website.Fetch(&config.NetworkInfos, address) - if err != nil { - logger.Fatalf("failed to fetch website: %v", err) - } - - logger.Infof("Website fetched successfully with size: %d", len(websiteBytes)) - - outputZipPath := fmt.Sprintf("website_%s.zip", address) - - err = os.WriteFile(outputZipPath, websiteBytes, 0o644) + err := logger.InitializeGlobal("./deweb-cli.log") if err != nil { - logger.Error("Failed to write website zip file", err) - return + log.Fatalf("failed to initialize logger: %v", err) } - logger.Info("Website successfully written to file: %s", outputZipPath) - - fileName := "index.html" - - content, err := zipper.GetFileFromZip(outputZipPath, fileName) - if err != nil { - logger.Error(err) - return + if err := app.Run(os.Args); err != nil { + fmt.Fprintf(os.Stderr, "Error: %v\n", err) } - - logger.Infof("%s content:\n %s", fileName, content) } -func deployWebsite(config *pkgConfig.Config) (string, error) { +func deployWebsite(config *pkgConfig.Config, filepath string) (string, error) { logger.Debugf("Deploying website contract with config: %+v", config) deploymentResult, err := website.Deploy(config) @@ -79,7 +125,7 @@ func deployWebsite(config *pkgConfig.Config) (string, error) { logger.Infof("Website contract deployed at address: %s", deploymentResult.Address) - chunks, err := processFileForUpload(os.Args[1]) + chunks, err := processFileForUpload(filepath) if err != nil { return "", fmt.Errorf("failed to process file for upload: %v", err) } @@ -117,3 +163,39 @@ func processFileForUpload(filepath string) ([][]byte, error) { return website.DivideIntoChunks(websiteBytes, website.ChunkSize), nil } + +func viewWebsite(address string, config *pkgConfig.Config) error { + owner, err := website.GetOwner(&config.NetworkInfos, address) + if err != nil { + logger.Warnf("failed to get owner of %s: %v", address, err) + } + + logger.Infof("Website owner: %s", owner) + + websiteBytes, err := website.Fetch(&config.NetworkInfos, address) + if err != nil { + return fmt.Errorf("failed to fetch website: %v", err) + } + + logger.Infof("Website fetched successfully with size: %d", len(websiteBytes)) + + outputZipPath := fmt.Sprintf("website_%s.zip", address) + + err = os.WriteFile(outputZipPath, websiteBytes, 0o644) + if err != nil { + return fmt.Errorf("failed to write website zip file %v", err) + } + + logger.Infof("Website successfully written to file: %s", outputZipPath) + + fileName := "index.html" + + content, err := zipper.GetFileFromZip(outputZipPath, fileName) + if err != nil { + return fmt.Errorf("failed to get file %s from zip: %v", fileName, err) + } + + logger.Infof("%s content:\n %s", fileName, content) + + return nil +} diff --git a/go.mod b/go.mod index 8f6ffa7..1b2f9fa 100644 --- a/go.mod +++ b/go.mod @@ -6,17 +6,21 @@ require ( github.com/massalabs/station v0.6.4 github.com/massalabs/station-massa-wallet v0.4.3 github.com/stretchr/testify v1.9.0 + github.com/urfave/cli/v2 v2.27.2 ) require ( github.com/awnumar/memcall v0.1.2 // indirect github.com/awnumar/memguard v0.22.3 // indirect github.com/btcsuite/btcutil v1.0.2 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/klauspost/cpuid/v2 v2.1.0 // indirect github.com/kr/text v0.2.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect + github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect github.com/ybbus/jsonrpc/v3 v3.1.4 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect diff --git a/go.sum b/go.sum index 51b0937..e7bd148 100644 --- a/go.sum +++ b/go.sum @@ -15,6 +15,8 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -46,12 +48,18 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI= +github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= github.com/ybbus/jsonrpc/v3 v3.1.4 h1:pPmgfWXnqR2GdIlealyCzmV6LV3nxm3w9gwA1B3cP3Y= github.com/ybbus/jsonrpc/v3 v3.1.4/go.mod h1:4HQTl0UzErqWGa6bSXhp8rIjifMAMa55E4D5wdhe768= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=