### Install yaml package Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/gopkg.in/yaml.v3/README.md Use 'go get' to install the yaml package. The import path is gopkg.in/yaml.v3. ```bash go get gopkg.in/yaml.v3 ``` -------------------------------- ### Create Root Logger Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/github.com/go-logr/logr/README.md Initialize the root logger early in an application's lifecycle. This example uses a hypothetical 'logimpl' implementation. ```go func main() { // ... other setup code ... // Create the "root" logger. We have chosen the "logimpl" implementation, // which takes some initial parameters and returns a logr.Logger. logger := logimpl.New(param1, param2) // ... other setup code ... } ``` -------------------------------- ### Go Client Library Usage Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt Example of using the BOSH Ali Storage CLI as a Go library for programmatic access to Ali OSS blobstore operations. ```APIDOC ## Go Client Library Usage The CLI can also be used as a Go library for programmatic access to Ali OSS blobstore operations. ### Example Usage ```go package main import ( "log" "os" "github.com/cloudfoundry/bosh-ali-storage-cli/client" "github.com/cloudfoundry/bosh-ali-storage-cli/config" ) func main() { // Load configuration from file configFile, err := os.Open("config.json") if err != nil { log.Fatal(err) } defer configFile.Close() aliConfig, err := config.NewFromReader(configFile) if err != nil { log.Fatal(err) } // Create storage client storageClient, err := client.NewStorageClient(aliConfig) if err != nil { log.Fatal(err) } // Create blobstore client blobstoreClient, err := client.New(storageClient) if err != nil { log.Fatal(err) } // Upload a file err = blobstoreClient.Put("/local/path/file.tgz", "remote/path/file.tgz") if err != nil { log.Fatal("Upload failed:", err) } // Check if blob exists exists, err := blobstoreClient.Exists("remote/path/file.tgz") if err != nil { log.Fatal("Exists check failed:", err) } log.Printf("Blob exists: %v", exists) // Download a file err = blobstoreClient.Get("remote/path/file.tgz", "/local/download/file.tgz") if err != nil { log.Fatal("Download failed:", err) } // Generate signed URL for GET (1 hour expiration) signedURL, err := blobstoreClient.Sign("remote/path/file.tgz", "get", 3600) if err != nil { log.Fatal("Signing failed:", err) } log.Printf("Signed URL: %s", signedURL) // Delete a blob err = blobstoreClient.Delete("remote/path/file.tgz") if err != nil { log.Fatal("Delete failed:", err) } } ``` ``` -------------------------------- ### Ali Storage CLI - Get Command Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/README.md Fetch a blob from the blobstore using the 'get' command. The destination file will be overwritten if it already exists. ```bash ./bosh-ali-storage-cli -c config.json get ``` -------------------------------- ### Convert format-string logs to structured logs Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/github.com/go-logr/logr/README.md Examples of refactoring klog format strings into structured logger calls using key-value pairs. ```go klog.V(4).Infof("Client is returning errors: code %v, error %v", responseCode, err) ``` ```go logger.Error(err, "client returned an error", "code", responseCode) ``` ```go klog.V(4).Infof("Got a Retry-After %ds response for attempt %d to %v", seconds, retries, url) ``` ```go logger.V(4).Info("got a retry-after response when requesting url", "attempt", retries, "after seconds", seconds, "url", url) ``` -------------------------------- ### Download Files with Get Command Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt Downloads a blob from the OSS bucket to a local path. Existing files at the destination will be overwritten. ```bash # Download a blob from the blobstore ./bosh-ali-storage-cli -c config.json get remote-blob-name /path/to/local/destination # Example: Download a release tarball ./bosh-ali-storage-cli -c config.json get releases/my-release-1.0.0.tgz ./downloads/my-release.tgz # Output on success: # 2024/01/15 10:35:20 Downloading my-bucket/releases/my-release-1.0.0.tgz # Exit code: 0 on success, 1 on failure ``` -------------------------------- ### Unmarshal and Marshal YAML data in Go Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/gopkg.in/yaml.v3/README.md This example demonstrates unmarshalling YAML data into a struct and a map, and then marshalling them back to YAML. Ensure struct fields are public for correct unmarshalling. ```Go package main import ( "fmt" "log" "gopkg.in/yaml.v3" ) var data = ` a: Easy! b: c: 2 d: [3, 4] ` // Note: struct fields must be public in order for unmarshal to // correctly populate the data. type T struct { A string B struct { RenamedC int `yaml:"c"` D []int `yaml:",flow"` } } func main() { t := T{} err := yaml.Unmarshal([]byte(data), &t) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- t:\n%v\n\n", t) d, err := yaml.Marshal(&t) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- t dump:\n%s\n\n", string(d)) m := make(map[interface{}]interface{}) err = yaml.Unmarshal([]byte(data), &m) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- m:\n%v\n\n", m) d, err = yaml.Marshal(&m) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- m dump:\n%s\n\n", string(d)) } ``` -------------------------------- ### Perform file upload and download with signed URLs via CLI Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt Use the CLI to generate temporary signed URLs for secure PUT and GET operations. ```bash UPLOAD_URL=$(./bosh-ali-storage-cli -c config.json sign data/backup-2024-01-15.tar.gz put 30m) curl -X PUT -T ./backup.tar.gz "$UPLOAD_URL" # Generate download URL and download file DOWNLOAD_URL=$(./bosh-ali-storage-cli -c config.json sign data/backup-2024-01-15.tar.gz get 1h) curl -X GET "$DOWNLOAD_URL" -o ./restored-backup.tar.gz ``` -------------------------------- ### Generate Pre-Signed URLs with Sign Command Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt Creates temporary access URLs for GET or PUT operations. Duration strings follow Go duration formats. ```bash # Generate a signed URL for downloading a blob ./bosh-ali-storage-cli -c config.json sign remote-blob-name get 1h # Generate a signed URL for uploading a blob ./bosh-ali-storage-cli -c config.json sign remote-blob-name put 30m # Example: Create a 1-hour download URL ./bosh-ali-storage-cli -c config.json sign releases/my-release-1.0.0.tgz get 3600s # Output: # http://my-bucket.oss-cn-hangzhou.aliyuncs.com/releases/my-release-1.0.0.tgz?OSSAccessKeyId=...&Expires=...&Signature=... # Duration format: Go duration strings (e.g., 1h, 60m, 3600s) ``` -------------------------------- ### Get slog.Handler from context Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/github.com/go-logr/logr/README.md Retrieves a slog.Handler from a context.Context. If an error occurs, it defaults to the slog.Default() handler. ```go func HandlerFromContext(ctx context.Context) slog.Handler { logger, err := logr.FromContext(ctx) if err == nil { return slogr.NewSlogHandler(logger) } return slog.Default().Handler() } ``` -------------------------------- ### Ali Storage CLI - Sign Command Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/README.md Create a self-signed URL for a blob in the blobstore. Specify the type of access (get or put) and the expiration time in seconds. ```bash ./bosh-ali-storage-cli -c config.json sign ``` -------------------------------- ### Run mkall.sh to Build Current OS/Arch Files Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/golang.org/x/sys/unix/README.md Use this command to generate Go files for your current operating system and architecture using the old build system. Ensure GOOS and GOARCH are set correctly. ```bash mkall.sh ``` -------------------------------- ### Show mkall.sh Commands (Old Build System) Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/golang.org/x/sys/unix/README.md View the commands that will be executed by mkall.sh without actually running them. Useful for understanding the build process. ```bash mkall.sh -n ``` -------------------------------- ### Configure Bosh Ali Storage CLI Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt The CLI requires a JSON configuration file containing Alibaba Cloud credentials and bucket details. ```json { "access_key_id": "your-access-key-id", "access_key_secret": "your-access-key-secret", "endpoint": "oss-cn-hangzhou.aliyuncs.com", "bucket_name": "my-blobstore-bucket" } ``` -------------------------------- ### Use Signed URLs with Curl Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt Demonstrates using generated pre-signed URLs with standard HTTP clients like curl. ```bash # Download a blob using a signed GET URL SIGNED_URL=$(./bosh-ali-storage-cli -c config.json sign my-blob get 1h) curl -X GET "$SIGNED_URL" -o downloaded-file.tgz # Upload a blob using a signed PUT URL SIGNED_URL=$(./bosh-ali-storage-cli -c config.json sign new-blob put 1h) curl -X PUT -T /path/to/file.tgz "$SIGNED_URL" ``` -------------------------------- ### Use Go client library for blobstore operations Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt Integrate the library into a Go application to perform CRUD operations and generate signed URLs. ```go package main import ( "log" "os" "github.com/cloudfoundry/bosh-ali-storage-cli/client" "github.com/cloudfoundry/bosh-ali-storage-cli/config" ) func main() { // Load configuration from file configFile, err := os.Open("config.json") if err != nil { log.Fatal(err) } defer configFile.Close() aliConfig, err := config.NewFromReader(configFile) if err != nil { log.Fatal(err) } // Create storage client storageClient, err := client.NewStorageClient(aliConfig) if err != nil { log.Fatal(err) } // Create blobstore client blobstoreClient, err := client.New(storageClient) if err != nil { log.Fatal(err) } // Upload a file err = blobstoreClient.Put("/local/path/file.tgz", "remote/path/file.tgz") if err != nil { log.Fatal("Upload failed:", err) } // Check if blob exists exists, err := blobstoreClient.Exists("remote/path/file.tgz") if err != nil { log.Fatal("Exists check failed:", err) } log.Printf("Blob exists: %v", exists) // Download a file err = blobstoreClient.Get("remote/path/file.tgz", "/local/download/file.tgz") if err != nil { log.Fatal("Download failed:", err) } // Generate signed URL for GET (1 hour expiration) signedURL, err := blobstoreClient.Sign("remote/path/file.tgz", "get", 3600) if err != nil { log.Fatal("Signing failed:", err) } log.Printf("Signed URL: %s", signedURL) // Delete a blob err = blobstoreClient.Delete("remote/path/file.tgz") if err != nil { log.Fatal("Delete failed:", err) } } ``` -------------------------------- ### Define a Ginkgo test suite Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/github.com/onsi/ginkgo/v2/README.md Uses Describe, Context, and It blocks to structure test scenarios for a library system. Requires the Ginkgo and Gomega packages. ```go import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ... ) var _ = Describe("Checking books out of the library", Label("library"), func() { var library *libraries.Library var book *books.Book var valjean *users.User BeforeEach(func() { library = libraries.NewClient() book = &books.Book{ Title: "Les Miserables", Author: "Victor Hugo", } valjean = users.NewUser("Jean Valjean") }) When("the library has the book in question", func() { BeforeEach(func(ctx SpecContext) { Expect(library.Store(ctx, book)).To(Succeed()) }) Context("and the book is available", func() { It("lends it to the reader", func(ctx SpecContext) { Expect(valjean.Checkout(ctx, library, "Les Miserables")).To(Succeed()) Expect(valjean.Books()).To(ContainElement(book)) Expect(library.UserWithBook(ctx, book)).To(Equal(valjean)) }, SpecTimeout(time.Second * 5)) }) Context("but the book has already been checked out", func() { var javert *users.User BeforeEach(func(ctx SpecContext) { javert = users.NewUser("Javert") Expect(javert.Checkout(ctx, library, "Les Miserables")).To(Succeed()) }) It("tells the user", func(ctx SpecContext) { err := valjean.Checkout(ctx, library, "Les Miserables") Expect(err).To(MatchError("Les Miserables is currently checked out")) }, SpecTimeout(time.Second * 5)) It("lets the user place a hold and get notified later", func(ctx SpecContext) { Expect(valjean.Hold(ctx, library, "Les Miserables")).To(Succeed()) Expect(valjean.Holds(ctx)).To(ContainElement(book)) By("when Javert returns the book") Expect(javert.Return(ctx, library, book)).To(Succeed()) By("it eventually informs Valjean") notification := "Les Miserables is ready for pick up" Eventually(ctx, valjean.Notifications).Should(ContainElement(notification)) Expect(valjean.Checkout(ctx, library, "Les Miserables")).To(Succeed()) Expect(valjean.Books(ctx)).To(ContainElement(book)) Expect(valjean.Holds(ctx)).To(BeEmpty()) }, SpecTimeout(time.Second * 10)) }) }) When("the library does not have the book in question", func() { It("tells the reader the book is unavailable", func(ctx SpecContext) { err := valjean.Checkout(ctx, library, "Les Miserables") Expect(err).To(MatchError("Les Miserables is not in the library catalog")) }, SpecTimeout(time.Second * 5)) }) }) ``` -------------------------------- ### System Call Dispatch Entry Points Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/golang.org/x/sys/unix/README.md These are the entry points in the hand-written assembly file for system call dispatch. They differ in the number of arguments passed to the kernel and low-level usage. ```go func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) ``` -------------------------------- ### Configuration Structure Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt Details the AliStorageConfig struct for configuring the connection to Ali OSS. ```APIDOC ## Configuration Structure The AliStorageConfig struct defines the required configuration fields for connecting to Ali OSS. ### Configuration Fields ```go package config import ( "encoding/json" "io" ) // AliStorageConfig holds the configuration for Ali OSS connection type AliStorageConfig struct { AccessKeyID string `json:"access_key_id"` // Alibaba Cloud Access Key ID AccessKeySecret string `json:"access_key_secret"` // Alibaba Cloud Access Key Secret Endpoint string `json:"endpoint"` // OSS endpoint (e.g., oss-cn-hangzhou.aliyuncs.com) BucketName string `json:"bucket_name"` // Target bucket name } // NewFromReader creates a new configuration from a JSON reader func NewFromReader(reader io.Reader) (AliStorageConfig, error) { bytes, err := io.ReadAll(reader) if err != nil { return AliStorageConfig{}, err } config := AliStorageConfig{} err = json.Unmarshal(bytes, &config) if err != nil { return AliStorageConfig{}, err } return config, nil } ``` ``` -------------------------------- ### Using Signed URLs with curl - Download Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/README.md Download a blob from Ali OSS using a pre-generated signed URL with curl. ```bash curl -X GET ``` -------------------------------- ### Upload/Download Workflow with Signed URLs Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt Demonstrates a complete workflow for uploading and downloading files using signed URLs generated by the CLI. ```APIDOC ## Upload/Download Workflow with Signed URLs This section shows how to generate signed URLs for uploading and downloading files to and from Alibaba Cloud OSS using the CLI. ### Generate upload URL and upload file ```bash # Generate upload URL and upload file UPLOAD_URL=$(./bosh-ali-storage-cli -c config.json sign data/backup-2024-01-15.tar.gz put 30m) curl -X PUT -T ./backup.tar.gz "$UPLOAD_URL" ``` ### Generate download URL and download file ```bash # Generate download URL and download file DOWNLOAD_URL=$(./bosh-ali-storage-cli -c config.json sign data/backup-2024-01-15.tar.gz get 1h) curl -X GET "$DOWNLOAD_URL" -o ./restored-backup.tar.gz ``` ``` -------------------------------- ### Using Signed URLs with curl - Upload Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/README.md Upload a blob to Ali OSS using a pre-generated signed URL with curl. ```bash curl -X PUT -T path/to/file ``` -------------------------------- ### Ali Storage CLI - Put Command Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/README.md Upload a blob to the blobstore using the 'put' command. Ensure the config.json file is correctly set up. ```bash ./bosh-ali-storage-cli -c config.json put ``` -------------------------------- ### Run Go Vet Linter Locally Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/github.com/onsi/gomega/CONTRIBUTING.md Check for potential issues in Go code using the 'go vet' command. Ensure no warnings are reported before submitting a Pull Request. ```bash go vet ./... ``` -------------------------------- ### Version Flag Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt How to display the CLI version information. ```APIDOC ## Version Flag Display the CLI version information. ### Check CLI version ```bash # Check CLI version ./bosh-ali-storage-cli -v # Output: # version 1.0.0 ``` ``` -------------------------------- ### StorageClient Interface Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt Defines the StorageClient interface for Ali OSS storage operations, allowing for mock implementations. ```APIDOC ## StorageClient Interface The StorageClient interface defines the contract for storage operations, enabling mock implementations for testing. ### Interface Definition ```go package client // StorageClient defines the interface for Ali OSS storage operations type StorageClient interface { // Upload uploads a file to the blobstore with MD5 verification Upload(sourceFilePath string, sourceFileMD5 string, destinationObject string) error // Download downloads a blob to a local file Download(sourceObject string, destinationFilePath string) error // Delete removes a blob from the blobstore Delete(object string) error // Exists checks if a blob exists in the blobstore Exists(object string) (bool, error) // SignedUrlPut generates a pre-signed URL for PUT operations SignedUrlPut(object string, expiredInSec int64) (string, error) // SignedUrlGet generates a pre-signed URL for GET operations SignedUrlGet(object string, expiredInSec int64) (string, error) } ``` ``` -------------------------------- ### Define AliStorageConfig structure Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt Configuration model and helper function to load settings from a JSON reader. ```go package config import ( "encoding/json" "io" ) // AliStorageConfig holds the configuration for Ali OSS connection type AliStorageConfig struct { AccessKeyID string `json:"access_key_id"` // Alibaba Cloud Access Key ID AccessKeySecret string `json:"access_key_secret"` // Alibaba Cloud Access Key Secret Endpoint string `json:"endpoint"` // OSS endpoint (e.g., oss-cn-hangzhou.aliyuncs.com) BucketName string `json:"bucket_name"` // Target bucket name } // NewFromReader creates a new configuration from a JSON reader func NewFromReader(reader io.Reader) (AliStorageConfig, error) { bytes, err := io.ReadAll(reader) if err != nil { return AliStorageConfig{}, err } config := AliStorageConfig{} err = json.Unmarshal(bytes, &config) if err != nil { return AliStorageConfig{}, err } return config, nil } ``` -------------------------------- ### Commit and Push Release Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/github.com/onsi/ginkgo/v2/RELEASING.md Commands to commit version changes, push to the repository, and create a GitHub release. ```bash git commit -m "vM.m.p" git push gh release create "vM.m.p" git fetch --tags origin master ``` -------------------------------- ### Run All Ginkgo Tests Locally Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/github.com/onsi/gomega/CONTRIBUTING.md Execute all tests using Ginkgo with parallelization enabled. Ensure all tests pass before submitting a Pull Request. ```bash ginkgo -r -p ``` -------------------------------- ### Upload Files with Put Command Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt Uploads a local file to the configured OSS bucket. The CLI automatically calculates the MD5 checksum for integrity verification. ```bash # Upload a local file to the blobstore ./bosh-ali-storage-cli -c config.json put /path/to/local/file.tar.gz remote-blob-name # Example: Upload a release tarball ./bosh-ali-storage-cli -c config.json put ./releases/my-release-1.0.0.tgz releases/my-release-1.0.0.tgz # Output on success: # 2024/01/15 10:30:45 Uploading my-bucket/releases/my-release-1.0.0.tgz # 2024/01/15 10:30:47 Successfully uploaded file # Exit code: 0 on success, 1 on failure ``` -------------------------------- ### Check CLI version Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt Display the current version of the CLI tool. ```bash # Check CLI version ./bosh-ali-storage-cli -v # Output: # version 1.0.0 ``` -------------------------------- ### Export Environment Variables for Integration Tests Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/README.md Set these environment variables with your Alibaba Cloud credentials and bucket details before running integration tests. ```bash export ACCESS_KEY_ID= export ACCESS_KEY_SECRET= export ENDPOINT= export BUCKET_NAME= ``` -------------------------------- ### Ali Storage CLI Configuration Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/README.md This JSON structure defines the required configuration parameters for the Ali Storage CLI. ```json { "access_key_id": " (required)", "access_key_secret": " (required)", "endpoint": " (required)", "bucket_name": " (required)" } ``` -------------------------------- ### Run Ginkgo Specs in Parallel Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/github.com/onsi/ginkgo/v2/README.md Execute Ginkgo tests in parallel using the -p flag. Ensure your specs follow established patterns for parallel integration tests to maintain clean execution and performance. ```bash ginkgo -p ``` -------------------------------- ### Call Slim-Sprig functions in templates Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/github.com/go-task/slim-sprig/README.md Use lowercase function names within Go templates to perform string manipulations. ```text {{ "hello!" | upper | repeat 5 }} ``` ```text HELLO!HELLO!HELLO!HELLO!HELLO! ``` -------------------------------- ### Handle format strings with Sprintf Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/github.com/go-logr/logr/README.md Use fmt.Sprintf for values when a format string is strictly necessary within a structured log. ```go log.Printf("unable to reflect over type %T") ``` ```go logger.Info("unable to reflect over type", "type", fmt.Sprintf("%T")) ``` -------------------------------- ### Load Slim-Sprig FuncMap Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/github.com/go-task/slim-sprig/README.md Register the Slim-Sprig function map with the Go template engine before parsing templates. ```go import ( "html/template" "github.com/go-task/slim-sprig" ) // This example illustrates that the FuncMap *must* be set before the // templates themselves are loaded. tpl := template.Must( template.New("base").Funcs(sprig.FuncMap()).ParseGlob("*.html") ) ``` -------------------------------- ### Update CHANGELOG.md Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/github.com/onsi/ginkgo/v2/RELEASING.md Generates a list of changes since the last tag and prepends them to the CHANGELOG.md file. ```bash LAST_VERSION=$(git tag --sort=version:refname | tail -n1) CHANGES=$(git log --pretty=format:'- %s [%h]' HEAD...$LAST_VERSION) echo -e "## NEXT\n\n$CHANGES\n\n### Features\n\n### Fixes\n\n### Maintenance\n\n$(cat CHANGELOG.md)" > CHANGELOG.md ``` -------------------------------- ### Define StorageClient interface Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt The interface contract for storage operations, useful for implementing mocks in tests. ```go package client // StorageClient defines the interface for Ali OSS storage operations type StorageClient interface { // Upload uploads a file to the blobstore with MD5 verification Upload(sourceFilePath string, sourceFileMD5 string, destinationObject string) error // Download downloads a blob to a local file Download(sourceObject string, destinationFilePath string) error // Delete removes a blob from the blobstore Delete(object string) error // Exists checks if a blob exists in the blobstore Exists(object string) (bool, error) // SignedUrlPut generates a pre-signed URL for PUT operations SignedUrlPut(object string, expiredInSec int64) (string, error) // SignedUrlGet generates a pre-signed URL for GET operations SignedUrlGet(object string, expiredInSec int64) (string, error) } ``` -------------------------------- ### Ali Storage CLI - Exists Command Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/README.md Check if a blob exists in the blobstore using the 'exists' command. ```bash ./bosh-ali-storage-cli -c config.json exists ``` -------------------------------- ### Check Blob Existence with Exists Command Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt Verifies if a blob exists in the bucket. Returns exit code 0 if found, or 3 if missing. ```bash # Check if a blob exists ./bosh-ali-storage-cli -c config.json exists remote-blob-name # Example: Check for a specific release ./bosh-ali-storage-cli -c config.json exists releases/my-release-1.0.0.tgz echo $? # 0 if exists, 3 if not exists # Output when blob exists: # 2024/01/15 10:45:00 Checking if blob: my-bucket/releases/my-release-1.0.0.tgz # 2024/01/15 10:45:01 File 'releases/my-release-1.0.0.tgz' exists in bucket 'my-bucket' # Output when blob does not exist: # 2024/01/15 10:45:00 Checking if blob: my-bucket/releases/my-release-1.0.0.tgz # 2024/01/15 10:45:01 File 'releases/my-release-1.0.0.tgz' does not exist in bucket 'my-bucket' # Exit codes: # 0 - blob exists # 3 - blob does not exist # 1 - error occurred ``` -------------------------------- ### Store slog.Handler in context Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/github.com/go-logr/logr/README.md Stores a slog.Handler in a context.Context by converting it to a logr.Logger. This method involves more allocations than directly using logr.Logger. ```go func ContextWithHandler(ctx context.Context, handler slog.Handler) context.Context { return logr.NewContext(ctx, slogr.NewLogr(handler)) } ``` -------------------------------- ### Ali Storage CLI - Delete Command Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/README.md Remove a blob from the blobstore using the 'delete' command. ```bash ./bosh-ali-storage-cli -c config.json delete ``` -------------------------------- ### Delete Blobs with Delete Command Source: https://context7.com/cloudfoundry/bosh-ali-storage-cli/llms.txt Permanently removes a blob from the OSS bucket. ```bash # Delete a blob from the blobstore ./bosh-ali-storage-cli -c config.json delete remote-blob-name # Example: Delete an old release ./bosh-ali-storage-cli -c config.json delete releases/my-release-0.9.0.tgz # Output on success: # 2024/01/15 10:40:00 Deleting my-bucket/releases/my-release-0.9.0.tgz # Exit code: 0 on success, 1 on failure ``` -------------------------------- ### Log within Application Code Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/github.com/go-logr/logr/README.md Use the received logr.Logger object within application code to emit log messages. The logger can be stored in structs. ```go type appObject struct { // ... other fields ... logger logr.Logger // ... other fields ... } func (app *appObject) Run() { app.logger.Info("starting up", "timestamp", time.Now()) // ... app code ... } ``` -------------------------------- ### Pass Logger to Other Objects Source: https://github.com/cloudfoundry/bosh-ali-storage-cli/blob/main/vendor/github.com/go-logr/logr/README.md Pass the logr.Logger object to other parts of the application, such as structs or other libraries. ```go app := createTheAppObject(logger) app.Run() ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.