### Install Match Library Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/match/README.md Use the go get command to download and install the package. ```bash go get -u github.com/tidwall/match ``` -------------------------------- ### Install Pretty package Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/pretty/README.md Use the go get command to retrieve the library. ```sh $ go get -u github.com/tidwall/pretty ``` -------------------------------- ### Run a local Go Doc site Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md Install and start a local documentation server to view Go package documentation. ```sh go install golang.org/x/pkgsite/cmd/pkgsite@latest pkgsite ``` -------------------------------- ### Install semver library Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/blang/semver/README.md Use the go get command to add the library to your project. ```bash $ go get github.com/blang/semver ``` -------------------------------- ### Install the YAML package Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/go.yaml.in/yaml/v3/README.md Use the go get command to add the package to your Go project. ```bash go get go.yaml.in/yaml/v3 ``` -------------------------------- ### Deploy Application with Start Command Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/cloudfoundry/switchblade/README.md Configures a custom start command for the application deployment. ```APIDOC ## WithStartCommand ### Description Sets a custom start command for the application, equivalent to the 'cf push -c' flag. ### Method Method chaining (Go) ### Parameters #### Request Body - **command** (string) - Required - The start command string to be executed by the application. ### Request Example platform.Deploy.WithStartCommand("start my-app").Execute("my-app", "/path/to/my/app/source") ``` -------------------------------- ### Install Go YAML Package Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/gopkg.in/yaml.v2/README.md Use 'go get' to install the yaml.v2 package for use in your Go projects. ```bash go get gopkg.in/yaml.v2 ``` -------------------------------- ### Install Mimetype Go Package Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/gabriel-vasile/mimetype/README.md Use 'go get' to install the mimetype package for your Go project. ```bash go get github.com/gabriel-vasile/mimetype ``` -------------------------------- ### Install Buildpack Packager Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/README.md Install the buildpack-packager tool using go install. This is required for building the buildpack. ```bash go install github.com/cloudfoundry/libbuildpack/packager/buildpack-packager ``` -------------------------------- ### Install GJSON package Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/README.md Use the go get command to add the GJSON library to your project. ```sh $ go get -u github.com/tidwall/gjson ``` -------------------------------- ### Install Mock Generation Tools Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/cloudfoundry/libbuildpack/README.md Install the necessary tools for generating mocks used in development. Run these commands in your terminal. ```bash go get github.com/golang/mock/gomock go get github.com/golang/mock/mockgen ``` -------------------------------- ### Deploy App with Custom Start Command Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/cloudfoundry/switchblade/README.md Deploy an application with a specific start command. This is equivalent to using the `cf push -c` command. ```go // Deploy an application called "my-app" with source code located at // /path/to/my/app/source. This is similar to running the following `cf` // commands: // cf push my-app -c "start my-app" deployment, logs, err := platform.Deploy. WithStartCommand("start my-app"). Execute("my-app", "/path/to/my/app/source") ``` -------------------------------- ### Preview documentation locally Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/onsi/ginkgo/v2/CONTRIBUTING.md Commands to install dependencies and serve the documentation site locally. ```bash bundle && bundle exec jekyll serve ``` -------------------------------- ### YAML Example Output Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/go.yaml.in/yaml/v3/README.md The expected console output after running the provided Go YAML example. ```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 ``` -------------------------------- ### Advanced request manipulation examples Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/elazarl/goproxy/README.md Examples demonstrating how to reject HTTPS requests and the correct way to filter by URL path. ```go // This rejects the HTTPS request to *.reddit.com during HTTP CONNECT phase. // Reddit URL check is case-insensitive because of (?i), so the block will work also if the user types something like rEdDit.com. proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile("(?i)reddit.*:443$"))).HandleConnect(goproxy.AlwaysReject) // Be careful about this example! It shows you a common error that you // need to avoid. // This will NOT reject the HTTPS request with URL ending with .gif because, // if the scheme is HTTPS, the proxy will receive only URL.Hostname // and URL.Port during the HTTP CONNECT phase. proxy.OnRequest(goproxy.UrlMatches(regexp.MustCompile(`.*gif$`))).HandleConnect(goproxy.AlwaysReject) // To fix the previous example, here there is the correct way to manipulate // an HTTP request using URL.Path (target path) as a condition. proxy.OnRequest(goproxy.UrlMatches(regexp.MustCompile(`.*gif$`))).Do(YourReqHandlerFunc()) ``` -------------------------------- ### JSON Path Result Examples Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/SYNTAX.md Examples showing the output of specific GJSON path queries. ```json [{"first": "Dale", "last": "Murphy", "age": 44},{"first": "Jane", "last": "Murphy", "age": 47}] ``` ```json ["Dale","Jane"] ``` ```json {"first": "Dale", "last": "Murphy", "age": 44} ``` -------------------------------- ### Install APT Buildpack Packager Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/cloudfoundry/libbuildpack/packager/README.md Installs the buildpack-packager tool. Ensure you are in the correct directory and have Go modules enabled. ```bash go get github.com/cloudfoundry/libbuildpack cd ~/go/src/github.com/cloudfoundry/libbuildpack && GO111MODULE=on go mod download cd packager/buildpack-packager && GO111MODULE=on go install ``` -------------------------------- ### Migrate Format Strings to Structured Logging Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/go-logr/logr/README.md Examples demonstrating the conversion of klog format-string logging to structured logr-style 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) ``` ```go log.Printf("unable to reflect over type %T") ``` ```go logger.Info("unable to reflect over type", "type", fmt.Sprintf("%T")) ``` -------------------------------- ### Run build and test commands Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/onsi/ginkgo/v2/CONTRIBUTING.md Commands to build the project, install the CLI, run tests, and vet the code. ```bash make ``` ```bash go install ./... ``` ```bash ginkgo -r -p ``` ```bash go vet ./... ``` -------------------------------- ### Fetch the project using go get Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md Downloads the project source using the Go toolchain. ```go go get -d go.opentelemetry.io/otel ``` -------------------------------- ### Install golangci-lint Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/elazarl/goproxy/README.md Install the golangci-lint tool to perform automatic lint checks on your code before submitting pull requests. ```sh go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest ``` -------------------------------- ### Create Root Logger Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/go-logr/logr/README.md Initialize the root logger early in the 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 ... } ``` -------------------------------- ### Path Chaining Examples Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/README.md Examples of using the pipe character to chain path modifiers. ```text "children|@reverse" >> ["Jack","Alex","Sara"] "children|@reverse|0" >> "Jack" ``` -------------------------------- ### Define JSON path syntax examples Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/README.md Examples of path syntax for accessing nested objects, arrays, and escaped keys. ```json { "name": {"first": "Tom", "last": "Anderson"}, "age":37, "children": ["Sara","Alex","Jack"], "fav.movie": "Deer Hunter", "friends": [ {"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]}, {"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]}, {"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]} ] } ``` -------------------------------- ### Configure Apt Packages Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/README.md Define packages to install using apt.yml. Supports package names and direct URLs to .deb files. ```yaml --- packages: - ascii - libxml - https://example.com/exciting.deb ``` -------------------------------- ### Pretty JSON Output Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/SYNTAX.md Example of formatted JSON output. ```json { "age":37, "children": ["Sara","Alex","Jack"], "fav.movie": "Deer Hunter", "friends": [ {"age": 44, "first": "Dale", "last": "Murphy"}, {"age": 68, "first": "Roger", "last": "Craig"}, {"age": 47, "first": "Jane", "last": "Murphy"} ], "name": {"first": "Tom", "last": "Anderson"} } ``` -------------------------------- ### Example generated IDs Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/teris-io/shortid/README.md Sample output showing ID length variations during high-throttle generation. ```text -NDveu-9Q iNove6iQ9J NVDve6-9Q VVDvc6i99J NVovc6-QQy VVoveui9QC ... tFmGc6iQQs KpTvcui99k KFTGcuiQ9p KFmGeu-Q9O tFTvcu-QQt tpTveu-99u ``` -------------------------------- ### Source .envrc File Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/README.md Source the .envrc file to set up the buildpack environment. Consider installing direnv for automatic sourcing. ```bash source .envrc ``` -------------------------------- ### Basic GJSON Path Examples Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/SYNTAX.md Retrieve values by object name or array index using basic GJSON Paths. ```json name.last "Anderson" name.first "Tom" age 37 children ["Sara","Alex","Jack"] children.0 "Sara" children.1 "Alex" friends.1 {"first": "Roger", "last": "Craig", "age": 68} friends.1.first "Roger" ``` -------------------------------- ### Define a Ginkgo test suite Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/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)) }) }) ``` -------------------------------- ### Define BDD tests with Spec Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/sclevine/spec/README.md Use spec.Run to define nested test cases with setup and teardown logic. ```go func TestObject(t *testing.T) { spec.Run(t, "object", func(t *testing.T, when spec.G, it spec.S) { var someObject *myapp.Object it.Before(func() { someObject = myapp.NewObject() }) it.After(func() { someObject.Close() }) it("should have some default", func() { if someObject.Default != "value" { t.Error("bad default") } }) when("something happens", func() { it.Before(func() { someObject.Connect() }) it("should do one thing", func() { if err := someObject.DoThing(); err != nil { t.Error(err) } }) it("should do another thing", func() { if result := someObject.DoOtherThing(); result != "good result" { t.Error("bad result") } }) }, spec.Random()) when("some slow things happen", func() { it("should do one thing in parallel", func() { if result := someObject.DoSlowThing(); result != "good result" { t.Error("bad result") } }) it("should do another thing in parallel", func() { if result := someObject.DoOtherSlowThing(); result != "good result" { t.Error("bad result") } }) }, spec.Parallel()) }, spec.Report(report.Terminal{})) } ``` -------------------------------- ### GJSON Path Wildcard Examples Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/SYNTAX.md Use wildcard characters '*' (zero or more characters) and '?' (exactly one character) in GJSON Paths to match keys. ```json child*.2 "Jack" c?ildren.0 "Sara" ``` -------------------------------- ### Unmarshal and Marshal YAML Data in Go Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/gopkg.in/yaml.v2/README.md This example demonstrates how to unmarshal YAML data into a Go struct and a map, and then marshal them back into YAML. Ensure struct fields are public for correct unmarshalling. ```Go package main import ( "fmt" "log" "gopkg.in/yaml.v2" ) 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)) } ``` -------------------------------- ### List all containers using Docker Engine API in Go Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/docker/docker/client/README.md Demonstrates how to initialize a Docker client and list all containers, equivalent to running 'docker ps --all'. Requires the github.com/docker/docker/client package. ```go package main import ( "context" "fmt" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" ) func main() { apiClient, err := client.NewClientWithOpts(client.FromEnv) if err != nil { panic(err) } defer apiClient.Close() containers, err := apiClient.ContainerList(context.Background(), container.ListOptions{All: true}) if err != nil { panic(err) } for _, ctr := range containers { fmt.Printf("%s %s (status: %s)\n", ctr.ID, ctr.Image, ctr.Status) } } ``` -------------------------------- ### Chained Get Operations Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/README.md Demonstrates multiple ways to chain `Get` operations for accessing nested JSON values. All provided examples achieve the same result. ```go gjson.Parse(json).Get("name").Get("last") ``` ```go gjson.Get(json, "name").Get("last") ``` ```go gjson.Get(json, "name.last") ``` -------------------------------- ### Get Nested Array Values Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/README.md Retrieve values from nested arrays using the '#' wildcard and specific paths. This example shows how to get all last names from a list of programmers. ```go result := gjson.Get(json, "programmers.#.lastName") for _, name := range result.Array() { println(name.String()) } ``` -------------------------------- ### Run Integration Tests with Docker Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/cloudfoundry/switchblade/README.md Initializes a Docker platform instance and deploys an application. Requires a GitHub API token. Asserts deployment logs and application serving. Cleans up by deleting the application. ```go package integration_test import ( "log" "testing" "github.com/cloudfoundry/switchblade" . "github.com/onsi/gomega" . "github.com/cloudfoundry/switchblade/matchers" ) func TestDocker(t *testing.T) { var ( Expect = NewWithT(t).Expect Eventually = NewWithT(t).Eventually ) // Create an instance of a Docker platform. A GitHub token is required to // make API requests to GitHub fetching buildpack details. platform, err := switchblade.NewPlatform(switchblade.Docker, "") Expect(err).NotTo(HaveOccurred()) // Deploy an application called "my-app" onto Docker with source code // located at /path/to/my/app/source. This is similar to the following `cf` // command, but running locally on your Docker daemon: // cf push my-app -p /path/to/my/app deployment, logs, err := platform.Deploy.Execute("my-app", "/path/to/my/app/source") Expect(err).NotTo(HaveOccurred()) // Assert that the deployment logs contain a line that contains the substring // "Installing dependency..." Expect(logs).To(ContainLines(ContainSubstring("Installing dependency..."))) // Assert that the deployment results in an application instance that serves // "Hello, world!" over HTTP. Eventually(deployment).Should(Serve(ContainSubstring("Hello, world!"))) // Delete the application from the platform. Expect(platform.Delete.Execute("my-app")).To(Succeed()) } ``` -------------------------------- ### GJSON Multipath Result Example Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/SYNTAX.md This is the resulting JSON structure when using the multipath example provided. ```json {"first":"Tom","age":37,"the_murphys":["Dale","Jane"]} ``` -------------------------------- ### JSON Literal Result Example Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/SYNTAX.md This is the resulting JSON structure when using the JSON literal and multipath example. ```json {"first":"Tom","age":37,"company":"Happysoft","employed":true} ``` -------------------------------- ### Deploy App with Service Bindings Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/cloudfoundry/switchblade/README.md Deploy an application with specified service bindings. This is analogous to using `cf create-user-provided-service` and `cf bind-service`. ```go // Deploy an application called "my-app" with source code located at // /path/to/my/app/source. This is similar to running the following `cf` // commands: // cf create-user-provided-service my-app-my-service -p '{"password": "its-a-secret!"}' // cf bind-service my-app my-app-my-service deployment, logs, err := platform.Deploy. WithService(map[string]switchblade.Service{ "my-service": { "password": "its-a-secret!", }, }). Execute("my-app", "/path/to/my/app/source") ``` -------------------------------- ### Implement a configuration constructor Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md Use an unexported 'newConfig' function to apply default values and iterate through provided options. ```go // newConfig returns an appropriately configured config. func newConfig(options ...Option) config { // Set default values for config. config := config{/* […] */} for _, option := range options { config = option.apply(config) } // Perform any validation here. return config } ``` -------------------------------- ### Custom Modifier Usage Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/README.md Examples of applying the custom 'case' modifier. ```text "children|@case:upper" >> ["SARA","ALEX","JACK"] "children|@case:lower|@reverse" >> ["jack","alex","sara"] ``` -------------------------------- ### Run Integration Tests with Cloud Foundry Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/cloudfoundry/switchblade/README.md Initializes a Cloud Foundry platform instance and deploys an application. Requires a GitHub API token. Asserts deployment logs and application serving. Cleans up by deleting the application. ```go package integration_test import ( "log" "testing" "github.com/cloudfoundry/switchblade" . "github.com/onsi/gomega" . "github.com/cloudfoundry/switchblade/matchers" ) func TestCloudFoundry(t *testing.T) { var ( Expect = NewWithT(t).Expect Eventually = NewWithT(t).Eventually ) // Create an instance of a Cloud Foundry platform. A GitHub token is required // to make API requests to GitHub fetching buildpack details. platform, err := switchblade.NewPlatform(switchblade.CloudFoundry, "") Expect(err).NotTo(HaveOccurred()) // Deploy an application called "my-app" onto Cloud Foundry with source code // located at /path/to/my/app/source. This is similar to the following `cf` // command: // cf push my-app -p /path/to/my/app deployment, logs, err := platform.Deploy.Execute("my-app", "/path/to/my/app/source") Expect(err).NotTo(HaveOccurred()) // Assert that the deployment logs contain a line that contains the substring // "Installing dependency..." Expect(logs).To(ContainLines(ContainSubstring("Installing dependency..."))) // Assert that the deployment results in an application instance that serves // "Hello, world!" over HTTP. Eventually(deployment).Should(Serve(ContainSubstring("Hello, world!"))) // Delete the application from the platform. Expect(platform.Delete.Execute("my-app")).To(Succeed()) } ``` -------------------------------- ### Retrieve Runtime Logs Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/cloudfoundry/switchblade/README.md Retrieves logs generated by the application after it has successfully started. ```APIDOC ## RuntimeLogs ### Description Retrieves runtime logs from the running application post-deployment. This is distinct from staging logs returned by the Execute method. ### Method GET (via deployment object) ### Response #### Success Response (200) - **logs** (string) - The output logs from the running application instance. ### Response Example "Application started\nConnected to Redis" ``` -------------------------------- ### Run golangci-lint locally Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/Microsoft/go-winio/README.md Execute this command from the repository root to run linting across all packages. ```shell # use . or specify a path to only lint a package # to show all lint errors, use flags "--max-issues-per-linter=0 --max-same-issues=0" > golangci-lint run ./... ``` -------------------------------- ### Pretty Modifier Argument Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/README.md Example of passing a JSON object as an argument to the @pretty modifier. ```text @pretty:{"sortKeys":true} ``` -------------------------------- ### Create and Check Version Constraint Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/Masterminds/semver/v3/README.md Use `semver.NewConstraint` to create a constraint and `semver.NewVersion` to create a version. Then, use the `Check` method to determine 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) ``` -------------------------------- ### Basic version comparison Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/blang/semver/README.md Create version objects and compare them using the Compare method. ```go import github.com/blang/semver v1, err := semver.Make("1.0.0-beta") v2, err := semver.Make("2.0.0-beta") v1.Compare(v2) ``` -------------------------------- ### Configure Pretty Modifier Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/SYNTAX.md Example of passing a JSON object as an argument to the @pretty modifier. ```text @pretty:{"sortKeys":true} ``` -------------------------------- ### Create and Deploy Buildpack Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/README.md Upload the built buildpack to Cloud Foundry and optionally specify it during application deployment. ```bash cf create-buildpack [BUILDPACK_NAME] [BUILDPACK_ZIP_FILE_PATH] 1 cf push my_app [-b BUILDPACK_NAME] ``` -------------------------------- ### Handling Overlapping Configurations with Interfaces in Go Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md Illustrates how to manage complex configurations with shared and distinct options using interfaces. This pattern helps avoid redundant configuration code. ```go // config holds options for all animals. type config struct { Weight float64 Color string MaxAltitude float64 } // DogOption apply Dog specific options. type DogOption interface { applyDog(config) config } // BirdOption apply Bird specific options. type BirdOption interface { applyBird(config) config } // Option apply options for all animals. type Option interface { BirdOption DogOption } type weightOption float64 func (o weightOption) applyDog(c config) config { c.Weight = float64(o) return c } func (o weightOption) applyBird(c config) config { c.Weight = float64(o) return c } func WithWeight(w float64) Option { return weightOption(w) } type furColorOption string func (o furColorOption) applyDog(c config) config { c.Color = string(o) return c } func WithFurColor(c string) DogOption { return furColorOption(c) } type maxAltitudeOption float64 func (o maxAltitudeOption) applyBird(c config) config { c.MaxAltitude = float64(o) return c } func WithMaxAltitude(a float64) BirdOption { return maxAltitudeOption(a) } func NewDog(name string, o ...DogOption) Dog {…} func NewBird(name string, o ...BirdOption) Bird {…} ``` -------------------------------- ### Instantiate a Lager Logger Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/code.cloudfoundry.org/lager/README.md Instantiate a logger with the name of your component. Import 'code.cloudfoundry.org/lager'. ```go import ( "code.cloudfoundry.org/lager" ) logger := lager.NewLogger("my-app") ``` -------------------------------- ### Customize JSON output with Options Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/pretty/README.md Define an Options struct to configure width, prefix, indentation, and key sorting. ```go type Options struct { // Width is an max column width for single line arrays // Default is 80 Width int // Prefix is a prefix for all lines // Default is an empty string Prefix string // Indent is the nested indentation // Default is two spaces Indent string // SortKeys will sort the keys alphabetically // Default is false SortKeys bool } ``` -------------------------------- ### Compress and Decompress Text using Go API Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/ulikunitz/xz/README.md Demonstrates how to use the xz.NewWriter and xz.NewReader to compress a string and then decompress it, writing the output to standard output. Ensure the 'bytes' and 'io' packages are imported. ```go package main import ( "bytes" "io" "log" "os" "github.com/ulikunitz/xz" ) func main() { const text = "The quick brown fox jumps over the lazy dog.\n" var buf bytes.Buffer // compress text w, err := xz.NewWriter(&buf) if err != nil { log.Fatalf("xz.NewWriter error %s", err) } if _, err := io.WriteString(w, text); err != nil { log.Fatalf("WriteString error %s", err) } if err := w.Close(); err != nil { log.Fatalf("w.Close error %s", err) } // decompress buffer and write output to stdout r, err := xz.NewReader(&buf) if err != nil { log.Fatalf("NewReader error %s", err) } if _, err = io.Copy(os.Stdout, r); err != nil { log.Fatalf("io.Copy error %s", err) } } ``` -------------------------------- ### Run APT Buildpack Tests Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/cloudfoundry/libbuildpack/packager/README.md Executes the tests for the APT buildpack using Ginkgo. The -r flag indicates recursive testing. ```bash ginkgo -r ``` -------------------------------- ### Specify Environment Variables for Deployment Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/cloudfoundry/switchblade/README.md Deploys an application with specified environment variables. This is similar to using `cf set-env`. ```go // Deploy an application called "my-app" with source code located at // /path/to/my/app/source. This is similar to running the following `cf` // command: // cf set-env my-app SOME_KEY some-value deployment, logs, err := platform.Deploy. WithEnv(map[string]string{ "SOME_KEY": "some-value", }). Execute("my-app", "/path/to/my/app/source") ``` -------------------------------- ### Validate Version Against Constraint in Go Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/Masterminds/semver/README.md Demonstrates how to parse a constraint and version string to validate compatibility, returning error messages if validation fails. ```go c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") if err != nil { // Handle constraint not being parseable. } v, _ := 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" } ``` -------------------------------- ### GJSON Path Array Length and Elements Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/SYNTAX.md Use the '#' character to get the length of a JSON array or to retrieve all elements within an array. ```json friends.# 3 friends.#.age [44,68,47] ``` -------------------------------- ### Build the Buildpack Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/README.md Build the buildpack using the buildpack-packager tool. This command generates the buildpack archive. ```bash buildpack-packager build ``` -------------------------------- ### Retrieve Runtime Logs After Deployment Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/cloudfoundry/switchblade/README.md Retrieve logs from a running application after successful deployment. Use staging logs for build-time output and runtime logs for application behavior testing. ```go // Deploy an application deployment, stagingLogs, err := platform.Deploy.Execute("my-app", "/path/to/my/app/source") Expect(err).NotTo(HaveOccurred()) // stagingLogs contains build-time output (buildpack detection, compilation, etc.) Expect(stagingLogs).To(ContainLines(ContainSubstring("Installing dependencies..."))) // Retrieve runtime logs (application startup, service connections, etc.) runtimeLogs, err := deployment.RuntimeLogs() Expect(err).NotTo(HaveOccurred()) Expect(runtimeLogs).To(ContainSubstring("Application started")) Expect(runtimeLogs).To(ContainSubstring("Connected to Redis")) ``` -------------------------------- ### Construct JSON with Literals and Multipaths Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/SYNTAX.md Utilize GJSON JSON literals, starting with '!', to construct static JSON blocks. This is useful when combining static values with dynamic data from multipaths. ```go {name.first,age,"company":!"Happysoft","employed":!true} ``` -------------------------------- ### Import Hash Implementations Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/opencontainers/go-digest/README.md Ensure necessary hash implementations (e.g., sha256, sha512) are imported into your application's main or entrypoint to prevent panics. This allows for flexibility in choosing hash algorithms. ```go import ( _ "crypto/sha256" _ "crypto/sha512" ) ``` -------------------------------- ### Query Object within Array Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/tidwall/gjson/README.md Access specific object properties within an array by filtering based on other properties. This example retrieves the first name of a programmer whose last name is 'Hunter'. ```go name := gjson.Get(json, `programmers.#(lastName="Hunter").firstName`) println(name.String()) // prints "Elliotte" ``` -------------------------------- ### Configure Custom Apt Repositories Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/README.md Configure custom apt repositories and GPG keys in apt.yml. `truncatesources` clears existing sources, and `cleancache` purges apt cache. ```yaml --- truncatesources: true cleancache: true keys: - https://example.com/public.key repos: - deb http://apt.example.com stable main packages: - ascii - libxml ``` -------------------------------- ### Go Instantiation with Functional Options Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md Demonstrates how to instantiate a type using functional options. The `NewT` function accepts a variadic slice of `Option`. ```go func NewT(options ...Option) T {…} ``` -------------------------------- ### Create a Contextual Logger Session Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/code.cloudfoundry.org/lager/README.md Create a new logger session with contextual data that will be repeated in subsequent log messages. This avoids repetition of contextual data. ```go contextualLogger := logger.Session("my-task", lager.Data{ "request-id": 5, }) contextualLogger.Info("my-action") ``` -------------------------------- ### Deploy Application with Service Bindings Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/cloudfoundry/switchblade/README.md Configures and deploys an application with specific user-provided service bindings. ```APIDOC ## WithService ### Description Configures the deployment to include user-provided service bindings before execution. ### Method Method chaining (Go) ### Parameters #### Request Body - **services** (map[string]switchblade.Service) - Required - A map where keys are service names and values are service configurations. ### Request Example platform.Deploy.WithService(map[string]switchblade.Service{"my-service": {"password": "its-a-secret!"}}).Execute("my-app", "/path/to/my/app/source") ``` -------------------------------- ### Run go generate Source: https://github.com/cloudfoundry/apt-buildpack/blob/master/vendor/github.com/Microsoft/go-winio/README.md Execute this command to ensure all auto-generated code in the repository is up to date. ```shell > go generate ./... ```