Skip to content

Commit

Permalink
feat: context support (#37)
Browse files Browse the repository at this point in the history
Fixes #7
  • Loading branch information
agaffney authored Feb 23, 2024
1 parent ff89806 commit 48fd211
Show file tree
Hide file tree
Showing 8 changed files with 323 additions and 18 deletions.
201 changes: 201 additions & 0 deletions cmd/cardano-up/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
// Copyright 2024 Blink Labs Software
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"errors"
"fmt"
"log/slog"
"os"
"sort"

"github.com/blinklabs-io/cardano-up/pkgmgr"
"github.com/spf13/cobra"
)

var contextFlags = struct {
description string
network string
}{}

func contextCommand() *cobra.Command {
contextCommand := &cobra.Command{
Use: "context",
Short: "Manage the current context",
}
contextCommand.AddCommand(
contextListCommand(),
contextSelectCommand(),
contextCreateCommand(),
contextDeleteCommand(),
)

return contextCommand
}

func contextListCommand() *cobra.Command {
return &cobra.Command{
Use: "list",
Short: "List available contexts",
Run: func(cmd *cobra.Command, args []string) {
pm, err := pkgmgr.NewDefaultPackageManager()
if err != nil {
slog.Error(fmt.Sprintf("failed to create package manager: %s", err))
os.Exit(1)
}
activeContext, _ := pm.ActiveContext()
contexts := pm.Contexts()
slog.Info("Contexts (* is active):\n")
slog.Info(
fmt.Sprintf(
" %-15s %-15s %s",
"Name",
"Network",
"Description",
),
)
var tmpContextNames []string
for contextName := range contexts {
tmpContextNames = append(tmpContextNames, contextName)
}
sort.Strings(tmpContextNames)
//for contextName, context := range contexts {
for _, contextName := range tmpContextNames {
context := contexts[contextName]
activeMarker := " "
if contextName == activeContext {
activeMarker = "*"
}
slog.Info(
fmt.Sprintf(
"%s %-15s %-15s %s",
activeMarker,
contextName,
context.Network,
context.Description,
),
)
}
},
}
}

func contextSelectCommand() *cobra.Command {
return &cobra.Command{
Use: "select <context name>",
Short: "Select the active context",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return errors.New("no context name provided")
}
if len(args) > 1 {
return errors.New("only one context name may be specified")
}
return nil
},
Run: func(cmd *cobra.Command, args []string) {
pm, err := pkgmgr.NewDefaultPackageManager()
if err != nil {
slog.Error(fmt.Sprintf("failed to create package manager: %s", err))
os.Exit(1)
}
if err := pm.SetActiveContext(args[0]); err != nil {
slog.Error(fmt.Sprintf("failed to set active context: %s", err))
os.Exit(1)
}
slog.Info(
fmt.Sprintf(
"Selected context %q",
args[0],
),
)
},
}
}

func contextCreateCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "create <context name>",
Short: "Create a new context",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return errors.New("no context name provided")
}
if len(args) > 1 {
return errors.New("only one context name may be specified")
}
return nil
},
Run: func(cmd *cobra.Command, args []string) {
pm, err := pkgmgr.NewDefaultPackageManager()
if err != nil {
slog.Error(fmt.Sprintf("failed to create package manager: %s", err))
os.Exit(1)
}
tmpContextName := args[0]
tmpContext := pkgmgr.Context{
Description: contextFlags.description,
Network: contextFlags.network,
}
if err := pm.AddContext(tmpContextName, tmpContext); err != nil {
slog.Error(fmt.Sprintf("failed to add context: %s", err))
os.Exit(1)
}
},
}
cmd.Flags().StringVarP(&contextFlags.description, "description", "d", "", "specifies description for context")
cmd.Flags().StringVarP(&contextFlags.network, "network", "n", "", "specifies network for context. if not specified, it's set automatically on the first package install")
return cmd
}

func contextDeleteCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "delete <context name>",
Short: "Delete a context",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return errors.New("no context name provided")
}
if len(args) > 1 {
return errors.New("only one context name may be specified")
}
return nil
},
Run: func(cmd *cobra.Command, args []string) {
pm, err := pkgmgr.NewDefaultPackageManager()
if err != nil {
slog.Error(fmt.Sprintf("failed to create package manager: %s", err))
os.Exit(1)
}
activeContext, _ := pm.ActiveContext()
if args[0] == activeContext {
slog.Error("cannot delete active context")
os.Exit(1)
}
if err := pm.DeleteContext(args[0]); err != nil {
slog.Error(fmt.Sprintf("failed to delete context: %s", err))
os.Exit(1)
}
slog.Info(
fmt.Sprintf(
"Deleted context %q",
args[0],
),
)
},
}
cmd.Flags().StringVarP(&contextFlags.description, "description", "d", "", "specifies description for context")
return cmd
}
1 change: 1 addition & 0 deletions cmd/cardano-up/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func main() {

// Add subcommands
rootCmd.AddCommand(
contextCommand(),
versionCommand(),
listAvailableCommand(),
installCommand(),
Expand Down
29 changes: 29 additions & 0 deletions pkgmgr/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2024 Blink Labs Software
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package pkgmgr

const (
defaultContextName = "default"
)

var defaultContext = Context{
Network: "preprod",
Description: "Default context",
}

type Context struct {
Description string `yaml:"description"`
Network string `yaml:"network"`
}
5 changes: 0 additions & 5 deletions pkgmgr/env.go

This file was deleted.

6 changes: 6 additions & 0 deletions pkgmgr/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,9 @@ var ErrMultipleInstallMethods = errors.New("only one install method may be speci
// ErrNoInstallMethods is returned when a package's install steps include an install step which has no
// recognized install method specified
var ErrNoInstallMethods = errors.New("no supported install method specified on install step")

// ErrContextNotExist is returned when trying to selecting/managing a context that does not exist
var ErrContextNotExist = errors.New("context does not exist")

// ErrContextAlreadyExists is returned when creating a context with a name that is already in use
var ErrContextAlreadyExists = errors.New("specified context already exists")
14 changes: 14 additions & 0 deletions pkgmgr/installed_package.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
// Copyright 2024 Blink Labs Software
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package pkgmgr

import (
Expand Down
41 changes: 41 additions & 0 deletions pkgmgr/pkgmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,44 @@ func (p *PackageManager) Uninstall(installedPkg InstalledPackage) error {
}
return nil
}

func (p *PackageManager) Contexts() map[string]Context {
return p.state.Contexts
}

func (p *PackageManager) ActiveContext() (string, Context) {
return p.state.ActiveContext, p.state.Contexts[p.state.ActiveContext]
}

func (p *PackageManager) AddContext(name string, context Context) error {
if _, ok := p.state.Contexts[name]; ok {
return ErrContextAlreadyExists
}
p.state.Contexts[name] = context
if err := p.state.Save(); err != nil {
return err
}
return nil
}

func (p *PackageManager) DeleteContext(name string) error {
if _, ok := p.state.Contexts[name]; !ok {
return ErrContextNotExist
}
delete(p.state.Contexts, name)
if err := p.state.Save(); err != nil {
return err
}
return nil
}

func (p *PackageManager) SetActiveContext(name string) error {
if _, ok := p.state.Contexts[name]; !ok {
return ErrContextNotExist
}
p.state.ActiveContext = name
if err := p.state.Save(); err != nil {
return err
}
return nil
}
Loading

0 comments on commit 48fd211

Please sign in to comment.