Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(CLI): cache CDK API data in disk #1529

Merged
merged 10 commits into from
Feb 14, 2024
91 changes: 58 additions & 33 deletions cli/cmd/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (

const (
componentTypeAnnotation string = "component"
componentsCacheKey string = "components"
)

var (
Expand Down Expand Up @@ -163,14 +164,12 @@ func (c *cliState) IsComponentInstalled(name string) bool {

// Load v1 components
func (c *cliState) LoadComponents() {
components, err := lwcomponent.LocalComponents()
components, err := lwcomponent.LoadLocalComponents()
if err != nil {
c.Log.Debugw("unable to load components", "error", err)
return
}

// @jon-stewart: TODO: load from cached API info

for _, component := range components {
exists := false

Expand All @@ -187,18 +186,8 @@ func (c *cliState) LoadComponents() {
}

version := component.InstalledVersion()
componentDir, err := component.Dir()
if err != nil {
c.Log.Debugw("unable to find component directory", "error", err)
return
}
if devInfo, _ := lwcomponent.NewDevInfo(componentDir); devInfo != nil {
PengyuanZhao marked this conversation as resolved.
Show resolved Hide resolved
if devVersion, _ := semver.NewVersion(devInfo.Version); devVersion != nil {
version = devVersion
}
}

if version != nil && component.Exec.Executable() {
if version != nil {
componentCmd := &cobra.Command{
Use: component.Name,
Short: component.Description,
Expand All @@ -208,7 +197,7 @@ func (c *cliState) LoadComponents() {
DisableFlagParsing: true,
DisableFlagsInUseLine: true,
RunE: func(cmd *cobra.Command, args []string) error {
return v1ComponentCommand(c, cmd, args)
return v1ComponentCommand(c, cmd)
},
}

Expand All @@ -224,7 +213,7 @@ func startGrpcServer(c *cliState) {
}
}

func v1ComponentCommand(c *cliState, cmd *cobra.Command, args []string) error {
func v1ComponentCommand(c *cliState, cmd *cobra.Command) error {
// Parse component -v/--version flag
versionVal, _ := cmd.Flags().GetBool("version")
if versionVal {
Expand All @@ -234,11 +223,7 @@ func v1ComponentCommand(c *cliState, cmd *cobra.Command, args []string) error {

go startGrpcServer(c)

c.Log.Debugw("running component", "component", cmd.Use,
"args", c.componentParser.componentArgs,
"cli_flags", c.componentParser.cliArgs)

catalog, err := lwcomponent.NewCatalog(cli.LwApi, lwcomponent.NewStageTarGz, false)
catalog, err := LoadCatalog()
if err != nil {
return errors.Wrap(err, "unable to load component Catalog")
}
Expand All @@ -248,6 +233,14 @@ func v1ComponentCommand(c *cliState, cmd *cobra.Command, args []string) error {
return err
}

if !component.Exec.Executable() {
return errors.New("component is not executable")
}

c.Log.Debugw("running component", "component", cmd.Use,
"args", c.componentParser.componentArgs,
"cli_flags", c.componentParser.cliArgs)

// @jon-stewart: TODO: v1 dailyComponentUpdateAvailable

envs := []string{
Expand Down Expand Up @@ -357,8 +350,7 @@ func runComponentsList(_ *cobra.Command, _ []string) (err error) {
func listComponents() error {
cli.StartProgress("Loading component Catalog...")

catalog, err := lwcomponent.NewCatalog(cli.LwApi, lwcomponent.NewStageTarGz, true)
defer catalog.Persist()
catalog, err := LoadCatalog()

cli.StopProgress()
if err != nil {
Expand All @@ -379,8 +371,6 @@ func listComponents() error {

printComponents(catalog.PrintComponents())

cli.OutputHuman("\nComponents version: %s\n", cli.LwComponents.Version)

return nil
}

Expand Down Expand Up @@ -425,8 +415,7 @@ func installComponent(cmd *cobra.Command, args []string) (err error) {

cli.StartProgress("Loading component Catalog...")

catalog, err := lwcomponent.NewCatalog(cli.LwApi, lwcomponent.NewStageTarGz, false)
defer catalog.Persist()
catalog, err := LoadCatalog()

cli.StopProgress()
if err != nil {
Expand Down Expand Up @@ -526,8 +515,7 @@ func showComponent(args []string) error {

cli.StartProgress("Loading components Catalog...")

catalog, err := lwcomponent.NewCatalog(cli.LwApi, lwcomponent.NewStageTarGz, false)
defer catalog.Persist()
catalog, err := LoadCatalog()

cli.StopProgress()
if err != nil {
Expand Down Expand Up @@ -600,8 +588,7 @@ func updateComponent(args []string) (err error) {

cli.StartProgress("Loading components Catalog...")

catalog, err := lwcomponent.NewCatalog(cli.LwApi, lwcomponent.NewStageTarGz, false)
defer catalog.Persist()
catalog, err := LoadCatalog()

cli.StopProgress()
if err != nil {
Expand Down Expand Up @@ -726,8 +713,7 @@ func deleteComponent(args []string) (err error) {

cli.StartProgress("Loading components Catalog...")

catalog, err := lwcomponent.NewCatalog(cli.LwApi, lwcomponent.NewStageTarGz, false)
defer catalog.Persist()
catalog, err := LoadCatalog()

cli.StopProgress()
if err != nil {
Expand Down Expand Up @@ -1215,3 +1201,42 @@ func downloadProgress(complete chan int8, path string, sizeB int64) {
time.Sleep(time.Second)
}
}

func LoadCatalog() (*lwcomponent.Catalog, error) {
cli.StartProgress("Loading component Catalog...")
PengyuanZhao marked this conversation as resolved.
Show resolved Hide resolved

PengyuanZhao marked this conversation as resolved.
Show resolved Hide resolved
var componentsApiInfo map[string]lwcomponent.ApiInfo

// try to load components Catalog from cache
if !cli.noCache {
expired := cli.ReadCachedAsset(componentsCacheKey, &componentsApiInfo)
if !expired {
cli.StopProgress()
cli.Log.Infow("loaded components from cache", "components", componentsApiInfo)
catalog, err := lwcomponent.NewCachedCatalog(cli.LwApi, lwcomponent.NewStageTarGz, componentsApiInfo)
if err != nil {
return nil, errors.Wrap(err, "unable to load component Catalog from cache")
}
return catalog, nil
}
}

// load components Catalog from API
catalog, err := lwcomponent.NewCatalog(cli.LwApi, lwcomponent.NewStageTarGz, true)
cli.StopProgress()
if err != nil {
return nil, errors.Wrap(err, "unable to load component Catalog")
}

componentsApiInfo = make(map[string]lwcomponent.ApiInfo, len(catalog.Components))

for _, c := range catalog.Components {
if c.ApiInfo != nil {
componentsApiInfo[c.Name] = *c.ApiInfo
}
}

cli.WriteAssetToCache(componentsCacheKey, time.Now().Add(time.Hour*12), componentsApiInfo)

return catalog, nil
}
3 changes: 1 addition & 2 deletions cli/cmd/component_dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@ func devModeComponent(args []string) error {

cli.StartProgress("Loading components Catalog...")

catalog, err := lwcomponent.NewCatalog(cli.LwApi, lwcomponent.NewStageTarGz, false)
defer catalog.Persist()
catalog, err := LoadCatalog()

cli.StopProgress()
if err != nil {
Expand Down
10 changes: 5 additions & 5 deletions cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ func componentPersistentPreRun(cmd *cobra.Command, args []string) error {
cli.Event.Args = cli.componentParser.componentArgs
err := cmd.Flags().Parse(cli.componentParser.cliArgs)

// We call initConfig() again after global flags have been parsed.
initConfig()
// We call InitConfig() again after global flags have been parsed.
InitConfig()

if err != nil {
cli.Event.Error = err.Error()
Expand Down Expand Up @@ -200,7 +200,7 @@ func setupRootHelpCommand() {

func init() {
// initialize cobra
cobra.OnInitialize(initConfig)
cobra.OnInitialize(InitConfig)

// Note - do not add new global flags without considering the consequences
// on components. These global flags will be consumed by the CLI and
Expand Down Expand Up @@ -292,8 +292,8 @@ Use "{{.CommandPath}} [command] --help" for more information about a command.{{e
`
}

// initConfig reads in config file and ENV variables if set
func initConfig() {
// InitConfig reads in config file and ENV variables if set
func InitConfig() {
PengyuanZhao marked this conversation as resolved.
Show resolved Hide resolved
// Find home directory
home, err := homedir.Dir()
errcheckEXIT(err)
Expand Down
74 changes: 19 additions & 55 deletions lwcomponent/api_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,15 @@ import (
"github.com/Masterminds/semver"
)

type ApiInfo interface {
Id() int32

LatestVersion() *semver.Version

AllVersions() []*semver.Version

Deprecated() bool

Size() int64
}

type apiInfo struct {
id int32
name string
version semver.Version
allVersions []*semver.Version
desc string
sizeKB int64
deprecated bool
componentType Type
type ApiInfo struct {
Id int32 `json:"id"`
Name string `json:"name"`
Version *semver.Version `json:"version"`
AllVersions []*semver.Version `json:"allVersions"`
Desc string `json:"desc"`
SizeKB int64 `json:"sizeKB"`
Deprecated bool `json:"deprecated"`
ComponentType Type `json:"componentType"`
}

func NewAPIInfo(
Expand All @@ -36,39 +24,15 @@ func NewAPIInfo(
size int64,
deprecated bool,
componentType Type,
) ApiInfo {
return &apiInfo{
id: id,
name: name,
version: *version,
allVersions: allVersions,
desc: desc,
sizeKB: size,
deprecated: deprecated,
componentType: componentType,
) *ApiInfo {
return &ApiInfo{
Id: id,
Name: name,
Version: version,
AllVersions: allVersions,
Desc: desc,
SizeKB: size,
Deprecated: deprecated,
ComponentType: componentType,
}
}

func (a *apiInfo) Id() int32 {
return a.id
}

// AllVersions implements ApiInfo.
func (a *apiInfo) AllVersions() []*semver.Version {
return a.allVersions
}

// LatestVersion implements ApiInfo.
func (a *apiInfo) LatestVersion() *semver.Version {
return &a.version
}

// Deprecated implements ApiInfo.
func (a *apiInfo) Deprecated() bool {
return a.deprecated
}

// Size implements ApiInfo.
func (a *apiInfo) Size() int64 {
return a.sizeKB
}
4 changes: 2 additions & 2 deletions lwcomponent/api_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func TestApiInfoId(t *testing.T) {

info := lwcomponent.NewAPIInfo(id, "test", version, allVersions, "", 0, false, lwcomponent.BinaryType)

result := info.Id()
result := info.Id
assert.Equal(t, id, result)
}

Expand All @@ -34,6 +34,6 @@ func TestApiInfoLatestVersion(t *testing.T) {

info := lwcomponent.NewAPIInfo(1, "test", version, allVersions, "", 0, false, lwcomponent.BinaryType)

result := info.LatestVersion()
result := info.Version
assert.Equal(t, expectedVer, result.String())
}
Loading
Loading