Skip to content

api in pairs: main && test apis: action, state, specs: bulk specs #20

@AmitKumarDas

Description

@AmitKumarDas
  • golang module: relm
  • golang package: relm/pkg/carvel
  • golang file: relm/pkg/carvel/bundle.go
  • last updated date: 23/JUL/2024
package carvel

type AnySpecsValidate interface {
  // public; external clients can invoke
  ValidateSpecs() error
}

type AnyBundlePush interface {
  // AnySpecsValidate ensures the instance of AnyBundlePush can be validated
  AnySpecsValidate

  // private; avoid custom implementations by external client
  pushBundle() (BundleResult, error)
}
type AnyBundlePushAssert interface {
  AnyBundlePush

  assertBundlePush() (AssertResult, error)
}
var _ AnyBundleCreate = &NestedBundleCreateSpecs{}
var _ AnyBundlePush = &BundlePushSpecs{}
var _ AnyPackageCRResolve = &PackageCRResolveSpecs{}
var _ AnyFileCopy = &FileCopySpecs{}
// Copy Package Metadata CR yaml to output location
var myFile1 = FileCopySpecs {
  Source: "path/to/component/package-meta-cr.yaml",
  Destination: "nested/bundle/config/component-v1.0.0/package-meta-cr.yaml",
}
// Resolve Package CR yaml & copy the resolved yaml to output location
var myPkgCR2 = PackageCRResolveSpecs {
  Method: YttFileOut, // Low level operation; declarative
  Source: "path/to/component/package.yaml",
  Destination: "nested/bundle/config/component/package.yaml", 
  KeyValues: map[string]string {
    "version": "v1.0.0",
    "image": "address/component_bundle@sha256:digestxxxx",
  },
}
// Push a bundle file (that was created earlier) to registry, 
// Then resolve the corresponding Package CR yaml using above registry endpoint, 
// Finally copy the resolved Package CR yaml to declared output location
var myBundle1 = &BundlePushSpecs {
  Method: ImgpkgCopyTarToRepo, // Low level operation; declarative
  Source: BundleSourceSpecs {
    BundleFilePath: "${GOBUILD_RELM_PATH}/bundle.tar.gz",
  },
  Destination: BundleDestinationSpecs {
    Address: "localhost:5000",
    BundlePath: "bundles/relm_bun",
    BundleTag: "v1.0.0",    
  },
  PackageCR: &PackageCRResolveSpecs { // [optional];
    Method: YttFileOut,
    Source: "relm/package.yaml", // templated file
    Destination: "nested/bundle/config/relm/package.yaml", 
    KeyValues: map[string]string {
      "version": "v1.0.0",
      "image": "localhost:5000/bundles/relm_bun:v1.0.0",
    },
    KeyValueRefs: map[string]string { // Alternative to KeyValues
      "version": LookupBundleTag,
      "image": LookupBundleURLTag,
    },
    refValues: map[string]string { // Private/Internal; filled up by BundleSpecs
      LookupBundleTag: "v1.0.0",
      LookupBundleURLTag: "localhost:5000/bundles/relm_bun:v1.0.0",
      LookupBundleURLDigest: "localhost:5000/bundles/relm_bun@sha256:digestxxx",
    },
  },
}
  • Summary
- One interface per action i.e. API
- Interfaces determine the main behaviour i.e. API
- Use prefix `Any` for interface names
- Use suffix `Specs` for struct names
- One struct (i.e. specs) for multiple interfaces wherever possible
- Every API should have corresponding Assert API
- Read (i.e. Maintainability) over Write (i.e. Implementation)
  - Distinct, Non ambiguous, Easy to understand
- Use verbose field names in Specs struct
- Use verbose method / function names
  - E.g.: getXXX, runXXX, createXXX, newXXX, etc.
- Keywords:
  - `XXXState` # PackageCRState, etc.; Multiple States per Action
  - `PostOperation` # PreOperation, etc.
  - `Method` # ImgpkgCopy, Ytt, CranePull, etc.
    - Names the `Low Level Operations`
  - `Target` # w.r.t Assert i.e. TargetUnderTest

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions