### Install Azure Blob Storage Go Package Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/README.md Install the Azure Blob Storage client module for Go using go get. ```bash go get github.com/Azure/azure-sdk-for-go/sdk/storage/azblob ``` -------------------------------- ### Install YAML package Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/go.yaml.in/yaml/v3/README.md Command to install the package via go get. ```bash go get go.yaml.in/yaml/v3 ``` -------------------------------- ### Install Azure Identity Go Package Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/README.md Install the azidentity module for authenticating with Azure Active Directory. This is recommended for authenticating Azure SDK clients. ```bash go get github.com/Azure/azure-sdk-for-go/sdk/azidentity ``` -------------------------------- ### YAML Example Output Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/go.yaml.in/yaml/v3/README.md Expected output from the provided Go example code. ```text --- t: {Easy! {2 [3 4]}} --- t dump: a: Easy! b: c: 2 d: [3, 4] --- m: map[a:Easy! b:map[c:2 d:[3 4]]] --- m dump: a: Easy! b: c: 2 d: - 3 - 4 ``` -------------------------------- ### Install counterfeiter to GOPATH Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Install the binary globally to allow usage outside of Go modules. ```shell $ go install github.com/maxbrunsfeld/counterfeiter/v6 $ ~/go/bin/counterfeiter USAGE counterfeiter [-generate>] [-o ] [-p] [--fake-name ] [-header ] [] [-] ``` -------------------------------- ### Run Integration Tests Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/README.md Environment setup and execution commands for integration tests. ```bash export ACCOUNT_NAME= export ACCOUNT_KEY= export CONTAINER_NAME= ``` ```bash go test ./integration/... ``` -------------------------------- ### Running CLI Tests Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Instructions for installing the Ginkgo test framework and running unit and integration tests for the CLI. Integration tests require Azure credentials to be set as environment variables. ```bash # Install ginkgo test framework go install github.com/onsi/ginkgo/v2/ginkgo # Run unit tests with coverage ginkgo --skip-package=integration --randomize-all --cover -v -r # Or use standard go test go test $(go list ./... | grep -v integration) # Run integration tests (requires Azure credentials) export ACCOUNT_NAME=your-azure-account-name export ACCOUNT_KEY=your-azure-account-key export CONTAINER_NAME=your-test-container go test ./integration/... ``` -------------------------------- ### Using Signed URLs with curl Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Examples demonstrating how to use generated signed URLs with `curl` for downloading and uploading blobs. ```bash # Download using a signed GET URL SIGNED_URL=$(./bosh-azure-storage-cli -c config.json sign releases/my-release.tar.gz get 1h) curl -X GET "$SIGNED_URL" -o downloaded-file.tar.gz ``` ```bash # Upload using a signed PUT URL (requires x-ms-blob-type header) SIGNED_URL=$(./bosh-azure-storage-cli -c config.json sign uploads/new-file.tar.gz put 30m) curl -X PUT -H "x-ms-blob-type: BlockBlob" --data-binary @/path/to/local/file.tar.gz "$SIGNED_URL" ``` -------------------------------- ### Install azcore dependency Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/README.md Use this command to add the latest version of the azcore module to your project's go.mod file. ```bash go get github.com/Azure/azure-sdk-for-go/sdk/azcore ``` -------------------------------- ### Define a Ginkgo test suite Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/onsi/ginkgo/v2/README.md Uses Describe, Context, and It blocks to structure test scenarios with setup and teardown via BeforeEach. ```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)) }) }) ``` -------------------------------- ### Convert Infof with Format String to Structured Log Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/go-logr/logr/README.md Example of converting a Kubernetes klog format string to a structured log message with key-value pairs. Use this when migrating from format string logging to structured logging. ```go logger.Error(err, "client returned an error", "code", responseCode) ``` -------------------------------- ### Convert Infof with Format String and Verbosity to Structured Log Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/go-logr/logr/README.md Example of converting a Kubernetes klog format string with verbosity level to a structured log message. This demonstrates how to retain verbosity information in structured logs. ```go logger.V(4).Info("got a retry-after response when requesting url", "attempt", retries, "after seconds", seconds, "url", url) ``` -------------------------------- ### Authenticate Azure Blob Storage Client with Azure AD Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/README.md Create an azblob.Client instance for interacting with Azure Blob Storage. This example uses NewDefaultAzureCredential for authentication with Azure Active Directory. ```go // create a credential for authenticating with Azure Active Directory cred, err := azidentity.NewDefaultAzureCredential(nil) // TODO: handle err // create an azblob.Client for the specified storage account that uses the above credential client, err := azblob.NewClient("https://MYSTORAGEACCOUNT.blob.core.windows.net/", cred, nil) // TODO: handle err ``` -------------------------------- ### Generate Signed URL for Blob Access Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Create a self-signed URL for temporary GET (download) or PUT (upload) access to a blob. Expiration can be specified in hours (h), minutes (m), or seconds (s). ```bash # Generate a signed URL for downloading (valid for 1 hour) ./bosh-azure-storage-cli -c config.json sign releases/my-release-1.0.tar.gz get 1h ``` ```bash # Generate a signed URL for uploading (valid for 30 minutes) ./bosh-azure-storage-cli -c config.json sign uploads/new-file.tar.gz put 30m ``` ```bash # Generate a signed URL with seconds-based expiration (3600 seconds = 1 hour) ./bosh-azure-storage-cli -c config.json sign releases/my-release.tar.gz get 3600s ``` -------------------------------- ### Get Blob Properties Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Retrieves metadata properties (ETag, last modified time, content length) for a specified blob. Returns an empty JSON object if the blob does not exist. ```bash ./bosh-azure-storage-cli -c config.json properties releases/my-release-1.0.tar.gz ``` -------------------------------- ### Initialize azblob Client Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/migrationguide.md Construct a new client using a storage account URL and credentials. Pass nil for default options. ```go // new code client, err := azblob.NewClient("", cred, nil) ``` ```go // new code. cred is an AAD token credential created from the azidentity module client, err := azblob.NewClient("", cred, nil) ``` -------------------------------- ### Get Blob Properties Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Retrieves metadata properties for a specific blob. ```APIDOC ## CLI properties ### Description Retrieves metadata properties for a blob including ETag, last modified time, and content length. ### Endpoint ./bosh-azure-storage-cli -c config.json properties [blob_path] ### Response #### Success Response (200) - **etag** (string) - The ETag of the blob. - **last_modified** (string) - The last modified timestamp. - **content_length** (integer) - The size of the blob in bytes. ``` -------------------------------- ### Go Library: Upload, Check Exists, Sign URL, List, Download, Delete Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Demonstrates programmatic Azure Blob Storage operations using the BOSH Azure Storage CLI as a Go library. Includes loading configuration, creating clients, and performing various blob operations. ```go package main import ( "log" "os" "time" "github.com/cloudfoundry/bosh-azure-storage-cli/client" "github.com/cloudfoundry/bosh-azure-storage-cli/config" ) func main() { // Load configuration from file configFile, err := os.Open("config.json") if err != nil { log.Fatal(err) } defer configFile.Close() azConfig, err := config.NewFromReader(configFile) if err != nil { log.Fatal(err) } // Create storage client storageClient, err := client.NewStorageClient(azConfig) if err != nil { log.Fatal(err) } // Create blobstore client blobstore, err := client.New(storageClient) if err != nil { log.Fatal(err) } // Upload a file err = blobstore.Put("/path/to/local/file.tar.gz", "releases/my-release.tar.gz") if err != nil { log.Fatal(err) } // Check if blob exists exists, err := blobstore.Exists("releases/my-release.tar.gz") if err != nil { log.Fatal(err) } log.Printf("Blob exists: %v", exists) // Generate signed URL signedURL, err := blobstore.Sign("releases/my-release.tar.gz", "get", 1*time.Hour) if err != nil { log.Fatal(err) } log.Printf("Signed URL: %s", signedURL) // List blobs blobs, err := blobstore.List("releases/") if err != nil { log.Fatal(err) } for _, blob := range blobs { log.Println(blob) } // Download a file destFile, err := os.Create("/tmp/downloaded.tar.gz") if err != nil { log.Fatal(err) } defer destFile.Close() err = blobstore.Get("releases/my-release.tar.gz", destFile) if err != nil { log.Fatal(err) } // Delete a blob err = blobstore.Delete("releases/old-release.tar.gz") if err != nil { log.Fatal(err) } } ``` -------------------------------- ### Configure HTTP Pipeline Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/migrationguide.md Configure the HTTP pipeline by passing azcore.ClientOptions within the azblob.ClientOptions during client initialization. ```go // new code client, err := azblob.NewClient(account, cred, &azblob.ClientOptions{ ClientOptions: azcore.ClientOptions{ // configure HTTP pipeline options here }, }) ``` -------------------------------- ### Initialize the root logger Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/go-logr/logr/README.md Create a root logger instance using a specific implementation early in the application lifecycle. ```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 ... ``` -------------------------------- ### Fix 304 Not Modified response Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated/autorest.md Adds a specific response definition for the '304 Not Modified' status code to the GET operation for blob retrieval, including error code headers. ```yaml directive: - from: swagger-document where: $["x-ms-paths"]["/{containerName}/{blob}"] transform: > $.get.responses["304"] = { "description": "The condition specified using HTTP conditional header(s) is not met.", "x-az-response-name": "ConditionNotMetError", "headers": { "x-ms-error-code": { "x-ms-client-name": "ErrorCode", "type": "string" } } }; ``` -------------------------------- ### Run Unit Tests Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/README.md Commands to execute unit tests using Ginkgo or standard Go test tools. ```bash go install github.com/onsi/ginkgo/v2/ginkgo ginkgo --skip-package=integration --randomize-all --cover -v -r ``` ```bash go test $(go list ./... | grep -v integration) ``` -------------------------------- ### Run go generate Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Execute the generation process for the current directory or the entire module. ```shell $ go generate ./... ``` -------------------------------- ### Add tool dependency Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Establish a tool dependency on counterfeiter within your Go module. ```shell go get -tool github.com/maxbrunsfeld/counterfeiter/v6 ``` -------------------------------- ### Run Go Linter Locally Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/onsi/gomega/CONTRIBUTING.md Check for potential issues and warnings in the Go code using the `go vet` command. Ensure no warnings are reported before submitting changes. ```shell go vet ./... ``` -------------------------------- ### View Original Interface File Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md This command displays the content of the Go file containing the interface definition. ```shell $ cat path/to/foo/file.go ``` -------------------------------- ### Create and Check Version Constraints Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Masterminds/semver/v3/README.md Use `semver.NewConstraint` to create a constraint object and `semver.NewVersion` to parse a version string. The `Check` method then determines if the version satisfies the constraint. Handle potential errors during parsing. ```go c, err := semver.NewConstraint(">= 1.2.3") if err != nil { // Handle constraint not being parsable. } v, err := semver.NewVersion("1.3") if err != nil { // Handle version not being parsable. } // Check if the version meets the constraints. The variable a will be true. a := c.Check(v) ``` -------------------------------- ### Create Azure Storage Account CLI Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/README.md Use this Azure CLI command to create a new storage account. Ensure you replace placeholder values with your desired names and location. ```bash az storage account create --name MyStorageAccount --resource-group MyResourceGroup --location westus --sku Standard_LRS ``` -------------------------------- ### Display CLI Version Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Displays the current version of the BOSH Azure Storage CLI. ```bash ./bosh-azure-storage-cli -v ``` -------------------------------- ### Initialize Anonymous Client Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/migrationguide.md Use NewClientWithNoCredential for public blobs or URLs containing SAS tokens. ```go // new code client, err := azblob.NewClientWithNoCredential("", nil) ``` -------------------------------- ### Configure BOSH Azure Storage CLI Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Create a JSON configuration file with Azure storage credentials and settings like upload timeout. ```json { "account_name": "mystorageaccount", "account_key": "base64encodedaccountkey==", "container_name": "my-container", "environment": "AzureCloud", "put_timeout_in_seconds": "300" } ``` -------------------------------- ### Instantiate a Fake in Tests Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Import the generated fakes package and instantiate the fake object for use in your tests. ```go import "my-repo/path/to/foo/foofakes" var fake = &foofakes.FakeMySpecialInterface{} ``` -------------------------------- ### Define an Interface Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md This Go code defines a sample interface that can be used with counterfeiter. ```go package foo type MySpecialInterface interface { DoThings(string, uint64) (int, error) } ``` -------------------------------- ### Use the logger in application code Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/go-logr/logr/README.md Store the logger in a struct and use it to emit logs without knowing the underlying implementation. ```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 ... ``` -------------------------------- ### List Blobs with Prefix Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Lists blobs in the configured container that match a specific prefix. Ensure your config.json is set up correctly. ```bash ./bosh-azure-storage-cli -c config.json list releases/ ``` -------------------------------- ### Commit and Create Release Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/onsi/ginkgo/v2/RELEASING.md Commits the version changes, pushes to the repository, and triggers a GitHub release. ```bash git commit -m "vM.m.p" git push gh release create "vM.m.p" git fetch --tags origin master ``` -------------------------------- ### Configure Azure Storage CLI Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/README.md Required JSON configuration structure for the CLI. ```json { "account_name": " (required)", "account_key": " (required)", "container_name": " (required)", "environment": " (optional, default: 'AzureCloud')", } ``` -------------------------------- ### Configure Code Generation Settings Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated/autorest.md Sets up the code generation process for the Azure Blob SDK, specifying the Go language, input OpenAPI file, output folder, and security settings. ```yaml go: true clear-output-folder: false version: "^3.0.0" license-header: MICROSOFT_MIT_NO_VERSION input-file: "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/b6472ffd34d5d4a155101b41b4eb1f356abff600/specification/storage/data-plane/Microsoft.BlobStorage/stable/2026-02-06/blob.json" credential-scope: "https://storage.azure.com/.default" output-folder: ../generated file-prefix: "zz_" openapi-type: "data-plane" verbose: true security: AzureKey modelerfour: group-parameters: false seal-single-value-enum-by-default: true lenient-model-deduplication: true export-clients: true use: "@autorest/go@4.0.0-preview.65" ``` -------------------------------- ### Download a blob using Go Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/README.md Downloads a public blob to a local file without requiring authentication credentials. ```go // this example accesses a public blob via anonymous access, so no credentials are required client, err := azblob.NewClientWithNoCredential("https://azurestoragesamples.blob.core.windows.net/", nil) // TODO: handle error // create or open a local file where we can download the blob file, err := os.Create("cloud.jpg") // TODO: handle error defer file.Close() // download the blob _, err = client.DownloadFile(context.TODO(), "samples", "cloud.jpg", file, nil) // TODO: handle error ``` -------------------------------- ### Run Counterfeiter Tests Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Execute the `scripts/ci.sh` script to run the test suite for the counterfeiter tool itself. ```shell scripts/ci.sh ``` -------------------------------- ### Generate a Test Double (Fake) Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Use the `go tool counterfeiter` command to generate a fake implementation of a Go interface. The output file path is indicated in the command's output. ```shell $ go tool counterfeiter path/to/foo MySpecialInterface Wrote `FakeMySpecialInterface` to `path/to/foo/foofakes/fake_my_special_interface.go` ``` -------------------------------- ### Define system call entry points Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/golang.org/x/sys/unix/README.md These assembly functions implement system call dispatch for specific GOOS/GOARCH pairs. ```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) ``` -------------------------------- ### Execute Azure Storage CLI Commands Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/README.md Standard commands for blob manipulation using the CLI. ```bash # Command: "put" # Upload a blob to the blobstore. ./bosh-azure-storage-cli -c config.json put # Command: "get" # Fetch a blob from the blobstore. # Destination file will be overwritten if exists. ./bosh-azure-storage-cli -c config.json get # Command: "delete" # Remove a blob from the blobstore. ./bosh-azure-storage-cli -c config.json delete # Command: "exists" # Checks if blob exists in the blobstore. ./bosh-azure-storage-cli -c config.json exists # Command: "sign" # Create a self-signed url for a blob in the blobstore. ./bosh-azure-storage-cli -c config.json sign ``` -------------------------------- ### Download Blob from Azure Storage Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Fetch a blob from Azure Blob Storage and save it to a local file. Overwrites the destination file if it already exists. ```bash # Download a blob to a local file ./bosh-azure-storage-cli -c config.json get releases/my-release-1.0.tar.gz /tmp/downloaded-release.tar.gz ``` ```bash # Download to current directory ./bosh-azure-storage-cli -c config.json get packages/v1/package.zip ./package.zip ``` -------------------------------- ### Enumerate blobs using Go Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/README.md Lists blobs within a container using a pager to iterate through multiple pages of results. ```go const ( account = "https://MYSTORAGEACCOUNT.blob.core.windows.net/" containerName = "sample-container" ) // authenticate with Azure Active Directory cred, err := azidentity.NewDefaultAzureCredential(nil) // TODO: handle error // create a client for the specified storage account client, err := azblob.NewClient(account, cred, nil) // TODO: handle error // blob listings are returned across multiple pages pager := client.NewListBlobsFlatPager(containerName, nil) // continue fetching pages until no more remain for pager.More() { // advance to the next page page, err := pager.NextPage(context.TODO()) // TODO: handle error // print the blob names for this page for _, blob := range page.Segment.BlobItems { fmt.Println(*blob.Name) } } ``` -------------------------------- ### List Blobs with Pager Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/migrationguide.md Iterate through paginated results using the runtime.Pager returned by the client. ```go // new code pager := client.NewListBlobsFlatPager("my-container", nil) for pager.More() { page, err := pager.NextPage(context.TODO()) // process results } ``` -------------------------------- ### Run All Gomega Tests Locally Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/onsi/gomega/CONTRIBUTING.md Execute all tests in the Gomega project locally to ensure they pass before submitting a Pull Request. This command should be run from the project's root directory. ```shell ginkgo -r -p ``` -------------------------------- ### Generate Double for Third-Party Interface Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Use the alternative syntax `.` to generate test doubles for interfaces defined in external packages. ```shell $ go tool counterfeiter github.com/go-redis/redis.Pipeliner ``` -------------------------------- ### Export createRequest/HandleResponse methods Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated/autorest.md Transforms method names in Go source files to standardize naming conventions for createRequest and HandleResponse functions, specifically for container and page blob clients. ```yaml directive: - from: zz_container_client.go where: $ transform: >- return $.replace(/listBlobHierarchySegmentCreateRequest/g, function(_, s) { return `ListBlobHierarchySegmentCreateRequest` }). replace(/listBlobHierarchySegmentHandleResponse/g, function(_, s) { return `ListBlobHierarchySegmentHandleResponse` }); - from: zz_pageblob_client.go where: $ transform: >- return $.replace(/getPageRanges(Diff)?CreateRequest/g, function(_, s) { if (s === undefined) { s = '' }; return `GetPageRanges${s}CreateRequest` }). replace(/getPageRanges(Diff)?HandleResponse/g, function(_, s) { if (s === undefined) { s = '' }; return `GetPageRanges${s}HandleResponse` }); ``` -------------------------------- ### Use Sprintf for Complex Values in Structured Logs Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/go-logr/logr/README.md Demonstrates how to use fmt.Sprintf within a key's value in a structured log message when a format string is absolutely necessary for a specific value. This should be used sparingly. ```go logger.Info("unable to reflect over type", "type", fmt.Sprintf("%T")) ``` -------------------------------- ### Record and Assert Method Calls Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Fakes record arguments they are called with. Use `CallCount` and `ArgsForCall` methods to assert interactions. ```go fake.DoThings("stuff", 5) Expect(fake.DoThingsCallCount()).To(Equal(1)) str, num := fake.DoThingsArgsForCall(0) Expect(str).To(Equal("stuff")) Expect(num).To(Equal(uint64(5))) ``` -------------------------------- ### Generate multiple test doubles in a package Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Use the counterfeiter:generate directive to efficiently generate multiple fakes within a single package. ```shell $ cat myinterface.go ``` ```go package foo // You only need **one** of these per package! //go:generate go tool counterfeiter -generate // You will add lots of directives like these in the same package... //counterfeiter:generate . MySpecialInterface type MySpecialInterface interface { DoThings(string, uint64) (int, error) } // Like this... //counterfeiter:generate . MyOtherInterface type MyOtherInterface interface { DoOtherThings(string, uint64) (int, error) } ``` ```shell $ go generate ./... Writing `FakeMySpecialInterface` to `foofakes/fake_my_special_interface.go`... Done Writing `FakeMyOtherInterface` to `foofakes/fake_my_other_interface.go`... Done ``` -------------------------------- ### Stub Return Values Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Configure fakes to return specific values or errors when their methods are called. ```go fake.DoThingsReturns(3, errors.New("the-error")) num, err := fake.DoThings("stuff", 5) Expect(num).To(Equal(3)) Expect(err).To(Equal(errors.New("the-error"))) ``` -------------------------------- ### Upload a blob using Go Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/README.md Uploads a local file to a specified Azure Blob Storage container using Azure Active Directory authentication. ```go const ( account = "https://MYSTORAGEACCOUNT.blob.core.windows.net/" containerName = "sample-container" blobName = "sample-blob" sampleFile = "path/to/sample/file" ) // authenticate with Azure Active Directory cred, err := azidentity.NewDefaultAzureCredential(nil) // TODO: handle error // create a client for the specified storage account client, err := azblob.NewClient(account, cred, nil) // TODO: handle error // open the file for reading file, err := os.OpenFile(sampleFile, os.O_RDONLY, 0) // TODO: handle error defer file.Close() // upload the file to the specified container with the specified blob name _, err = client.UploadFile(context.TODO(), containerName, blobName, file, nil) // TODO: handle error ``` -------------------------------- ### Invoke counterfeiter from shell Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Display usage information for the counterfeiter tool within a Go module. ```shell $ go tool counterfeiter USAGE counterfeiter [-generate>] [-o ] [-p] [--fake-name ] [-header ] [] [-] ``` -------------------------------- ### Load Slim-Sprig FuncMap in Go Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/go-task/slim-sprig/v3/README.md Load the Slim-Sprig FuncMap before parsing templates. This ensures all available template functions are accessible within your Go application. ```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") ) ``` -------------------------------- ### Unmarshal and Marshal YAML data Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/go.yaml.in/yaml/v3/README.md Demonstrates unmarshaling YAML into a struct or map, and marshaling data back into YAML format. Struct fields must be exported for successful unmarshaling. ```go package main import ( "fmt" "log" "go.yaml.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)) } ``` -------------------------------- ### Run Ginkgo Specs in Parallel Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/onsi/ginkgo/v2/README.md Execute Ginkgo tests in parallel using the -p flag. This is useful for speeding up test execution in larger suites. ```bash ginkgo -p ``` -------------------------------- ### Supported Azure Environments Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Specify the Azure cloud environment for storage endpoint configuration. ```json { "environment": "AzureCloud" } ``` ```json { "environment": "AzureChinaCloud" } ``` ```json { "environment": "AzureUSGovernment" } ``` -------------------------------- ### Validate Version Against Constraint in Go Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Masterminds/semver/v3/README.md Use the Validate method to check if a version meets a constraint and retrieve specific error messages if it fails. ```go c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") if err != nil { // Handle constraint not being parseable. } v, err := semver.NewVersion("1.3") if err != nil { // Handle version not being parseable. } // Validate a version against a constraint. a, msgs := c.Validate(v) // a is false for _, m := range msgs { fmt.Println(m) // Loops over the errors which would read // "1.3 is greater than 1.2.3" // "1.3 is less than 1.4" } ``` -------------------------------- ### Sort Semantic Versions Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Masterminds/semver/v3/README.md Sort a slice of semantic versions using the standard library's `sort` package. Ensure all versions are parsed successfully before sorting. ```go raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} vs := make([]*semver.Version, len(raw)) for i, r := range raw { v, err := semver.NewVersion(r) if err != nil { t.Errorf("Error parsing version: %s", err) } vs[i] = v } sort.Sort(semver.Collection(vs)) ``` -------------------------------- ### Parse Semantic Version Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Masterminds/semver/v3/README.md Use `NewVersion` to parse a semantic version string. It attempts to coerce non-compliant versions into a valid semantic version. An error is returned if parsing fails. ```go v, err := semver.NewVersion("1.2.3-beta.1+build345") ``` -------------------------------- ### Update Service Version in Client Files Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated/autorest.md Replaces the hardcoded service version '2025-11-05' with a variable 'ServiceVersion' across multiple client Go files. ```yaml directive: - from: - zz_appendblob_client.go - zz_blob_client.go - zz_blockblob_client.go - zz_container_client.go - zz_pageblob_client.go - zz_service_client.go where: $ transform: >- return $.replaceAll(`[]string{"2025-11-05"}`, `[]string{ServiceVersion}`); ``` -------------------------------- ### List Blobs Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Lists blobs within the configured container that match a specific prefix. ```APIDOC ## CLI list ### Description Lists blobs with a specific prefix in the configured Azure container. ### Endpoint ./bosh-azure-storage-cli -c config.json list [prefix] ### Parameters #### Path Parameters - **prefix** (string) - Required - The prefix to filter blobs by. ``` -------------------------------- ### Export Methods in Container Client Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated/autorest.md Modifies 'zz_container_client.go' to remove pager methods and export various generated methods, improving usability. ```yaml directive: - from: zz_container_client.go where: $ transform: >- return $.replace(/func \(client \*ContainerClient\) NewListBlobFlatSegmentPager\(.+\/\/ listBlobFlatSegmentCreateRequest creates the ListBlobFlatSegment request/s, `//\n// listBlobFlatSegmentCreateRequest creates the ListBlobFlatSegment request`). replace(/\(client \*ContainerClient\) listBlobFlatSegmentCreateRequest\(/, `(client *ContainerClient) ListBlobFlatSegmentCreateRequest(`). replace(/\(client \*ContainerClient\) listBlobFlatSegmentHandleResponse\(/, `(client *ContainerClient) ListBlobFlatSegmentHandleResponse(`); ``` -------------------------------- ### Ensure Container Exists Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Ensures the configured container exists, creating it if necessary. ```APIDOC ## CLI ensure-bucket-exists ### Description Creates the configured container if it does not already exist. This operation is idempotent. ### Endpoint ./bosh-azure-storage-cli -c config.json ensure-bucket-exists ``` -------------------------------- ### Ensure Container Exists Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Creates the configured container if it does not already exist. This operation is idempotent and safe to call multiple times. ```bash ./bosh-azure-storage-cli -c config.json ensure-bucket-exists ``` -------------------------------- ### Pass the logger to application components Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/go-logr/logr/README.md Inject the logger instance into application objects to be used throughout the program. ```go app := createTheAppObject(logger) app.Run() ``` -------------------------------- ### Update CHANGELOG.md Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/onsi/ginkgo/v2/RELEASING.md Generates a list of commits 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 ``` -------------------------------- ### Generate test double for a single interface Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Use the go:generate directive to create a fake implementation for a specific interface. ```shell $ cat myinterface.go ``` ```go package foo //go:generate go tool counterfeiter . MySpecialInterface type MySpecialInterface interface { DoThings(string, uint64) (int, error) } ``` ```shell $ go generate ./... Writing `FakeMySpecialInterface` to `foofakes/fake_my_special_interface.go`... Done ``` -------------------------------- ### List Blobs in Azure Storage Container Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt List all blobs within the configured Azure storage container. Supports filtering by a prefix. ```bash # List all blobs in the container ./bosh-azure-storage-cli -c config.json list ``` -------------------------------- ### Export Methods in Service Client Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated/autorest.md Modifies 'zz_service_client.go' to remove pager methods and export various generated methods, enhancing client functionality. ```yaml directive: - from: zz_service_client.go where: $ transform: >- return $.replace(/func \(client \*ServiceClient\) NewListContainersSegmentPager\(.+\/\/ listContainersSegmentCreateRequest creates the ListContainersSegment request/s, `//\n// listContainersSegmentCreateRequest creates the ListContainersSegment request`). replace(/\(client \*ServiceClient\) listContainersSegmentCreateRequest\(/, `(client *ServiceClient) ListContainersSegmentCreateRequest(`). replace(/\(client \*ServiceClient\) listContainersSegmentHandleResponse\(/, `(client *ServiceClient) ListContainersSegmentHandleResponse(`); ``` -------------------------------- ### Check Blob Existence Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Verify if a blob exists in the blobstore. Returns exit code 0 if the blob exists, and exit code 3 if it does not. ```bash # Check if a blob exists ./bosh-azure-storage-cli -c config.json exists releases/my-release-1.0.tar.gz ``` ```bash # Use in scripts with exit code checking if ./bosh-azure-storage-cli -c config.json exists releases/my-release-1.0.tar.gz; then echo "Blob exists" else echo "Blob does not exist (exit code: $?)" fi ``` -------------------------------- ### Upload Blob to Azure Storage Source: https://context7.com/cloudfoundry/bosh-azure-storage-cli/llms.txt Upload a local file to Azure Blob Storage. Includes automatic MD5 checksum verification for data integrity. The blob is deleted on MD5 mismatch. ```bash # Upload a file to a blob ./bosh-azure-storage-cli -c config.json put /path/to/local/file.tar.gz releases/my-release-1.0.tar.gz ``` ```bash # Example with specific paths ./bosh-azure-storage-cli -c config.json put ./build/package.zip packages/v1/package.zip ``` -------------------------------- ### Update URL encoding Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated/autorest.md Replaces '+' with '%20' in URL query strings to ensure compatibility with the Azure service. ```yaml directive: - from: - zz_service_client.go - zz_container_client.go where: $ transform: >- return $. replace(/req.Raw\(\).URL.RawQuery \= reqQP.Encode\(\)/g, `req.Raw().URL.RawQuery = strings.Replace(reqQP.Encode(), "+", "%20", -1)`); ``` -------------------------------- ### Use Slim-Sprig Functions in Templates Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/go-task/slim-sprig/v3/README.md Call Slim-Sprig functions within templates using lowercase names. Functions are chained using the pipe operator, allowing for sequential operations like string manipulation. ```go {{ "hello!" | upper | repeat 5 }} ``` -------------------------------- ### Use azcore.ETag in generated models Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated/autorest.md Replaces string-based ETag fields with azcore.ETag types across models, options, and client files. ```yaml directive: - from: - zz_models.go - zz_options.go where: $ transform: >- return $. replace(/import "time"/, `import ( "time" "github.com/Azure/azure-sdk-for-go/sdk/azcore" )`). replace(/Etag\s+\*string/g, `ETag *azcore.ETag`). replace(/IfMatch\s+\*string/g, `IfMatch *azcore.ETag`). replace(/IfNoneMatch\s+\*string/g, `IfNoneMatch *azcore.ETag`). replace(/SourceIfMatch\s+\*string/g, `SourceIfMatch *azcore.ETag`). replace(/SourceIfNoneMatch\s+\*string/g, `SourceIfNoneMatch *azcore.ETag`); - from: zz_responses.go where: $ transform: >- return $. replace(/"time"/, `"time" "github.com/Azure/azure-sdk-for-go/sdk/azcore"`). replace(/ETag\s+\*string/g, `ETag *azcore.ETag`); - from: - zz_appendblob_client.go - zz_blob_client.go - zz_blockblob_client.go - zz_container_client.go - zz_pageblob_client.go where: $ transform: >- return $. replace(/"github\.com\/Azure\/azure\-sdk\-for\-go\/sdk\/azcore\/policy"/, `"github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"`). replace(/result\.ETag\s+=\s+&val/g, `result.ETag = (*azcore.ETag)(&val)`). replace(/\*modifiedAccessConditions.IfMatch/g, `string(*modifiedAccessConditions.IfMatch)`). replace(/\*modifiedAccessConditions.IfNoneMatch/g, `string(*modifiedAccessConditions.IfNoneMatch)`). replace(/\*blobModifiedAccessConditions.IfMatch/g, `string(*blobModifiedAccessConditions.IfMatch)`). replace(/\*blobModifiedAccessConditions.IfNoneMatch/g, `string(*blobModifiedAccessConditions.IfNoneMatch)`). replace(/\*sourceModifiedAccessConditions.SourceIfMatch/g, `string(*sourceModifiedAccessConditions.SourceIfMatch)`). replace(/\*sourceModifiedAccessConditions.SourceIfNoneMatch/g, `string(*sourceModifiedAccessConditions.SourceIfNoneMatch)`); ``` -------------------------------- ### Set parameters as required Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated/autorest.md Forces specific Swagger parameters to be marked as required. ```yaml directive: - from: swagger-document where: $.parameters.FilterBlobsWhere transform: > $.required = true; directive: - from: swagger-document where: $.parameters.LeaseDuration transform: > $.required = true; ``` -------------------------------- ### Add Owner, Group, Permissions, Acl, ResourceType to BlobPropertiesInternal Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated/autorest.md Extends the BlobPropertiesInternal definition in the OpenAPI schema by adding Owner, Group, Permissions, Acl, and ResourceType properties. ```yaml directive: - from: swagger-document where: $.definitions transform: > $.BlobPropertiesInternal.properties["Owner"] = { "type" : "string", }; $.BlobPropertiesInternal.properties["Group"] = { "type" : "string", }; $.BlobPropertiesInternal.properties["Permissions"] = { "type" : "string", }; $.BlobPropertiesInternal.properties["Acl"] = { "type" : "string", }; $.BlobPropertiesInternal.properties["ResourceType"] = { "type" : "string", }; ``` -------------------------------- ### Interact with Signed URLs via Curl Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/README.md Perform operations on blobs using generated signed URLs. ```bash # Uploading a blob: curl -X PUT -H "x-ms-blob-type: blockblob" -F 'fileX=' # Downloading a blob: curl -X GET ``` -------------------------------- ### Normalize acronym casing Source: https://github.com/cloudfoundry/bosh-azure-storage-cli/blob/main/vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/internal/generated/autorest.md Ensures CPK and CORS acronyms are consistently capitalized in the generated code. ```yaml directive: - from: source-file-go where: $ transform: >- return $. replace(/Cpk/g, "CPK"); directive: - from: source-file-go where: $ transform: >- return $. replace(/Cors/g, "CORS"); ```