Skip to content

Commit

Permalink
feat: package manager state support (#19)
Browse files Browse the repository at this point in the history
Fixes #18
  • Loading branch information
agaffney authored Feb 9, 2024
1 parent e1effa9 commit 5ba0a47
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 1 deletion.
5 changes: 5 additions & 0 deletions pkgmgr/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package pkgmgr

type Environment struct {
// TODO
}
24 changes: 23 additions & 1 deletion pkgmgr/pkgmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,30 @@

package pkgmgr

import (
"errors"
"fmt"
)

// ErrOperationFailed is a placeholder error for operations that directly log errors.
// It's used to signify when an operation has failed when the actual error message is
// sent through the provided logger
var ErrOperationFailed = errors.New("the operation has failed")

type PackageManager struct {
config Config
state *State
// TODO
}

func NewPackageManager(cfg Config) (*PackageManager, error) {
// Make sure that a logger was provided, since we use it for pretty much all feedback
if cfg.Logger == nil {
return nil, errors.New("you must provide a logger")
}
p := &PackageManager{
config: cfg,
state: NewState(cfg),
}
if err := p.init(); err != nil {
return nil, err
Expand All @@ -38,7 +54,13 @@ func NewDefaultPackageManager() (*PackageManager, error) {
}

func (p *PackageManager) init() error {
// TODO: create config/cache dirs
p.config.Logger.Debug("initializing package manager")
if err := p.state.Load(); err != nil {
return fmt.Errorf("failed to load state: %s", err)
}
// TODO: remove me
if err := p.state.Save(); err != nil {
return err
}
return nil
}
92 changes: 92 additions & 0 deletions pkgmgr/state.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package pkgmgr

import (
"encoding/json"
"os"
"path/filepath"
)

const (
environmentsFilename = "environments.json"
)

type State struct {
config Config
Environments []Environment
// TODO: installed packages
}

func NewState(cfg Config) *State {
return &State{
config: cfg,
Environments: make([]Environment, 0),
}
}

func (s *State) Load() error {
if err := s.loadEnvironments(); err != nil {
return err
}
return nil
}

func (s *State) Save() error {
if err := s.saveEnvironments(); err != nil {
return err
}
return nil
}

func (s *State) loadFile(filename string, dest any) error {
tmpPath := filepath.Join(
s.config.ConfigDir,
filename,
)
// Check if the file exists and we can access it
if _, err := os.Stat(tmpPath); err != nil {
// Treat no file like an empty file
if os.IsNotExist(err) {
return nil
}
return err
}
content, err := os.ReadFile(tmpPath)
if err != nil {
return err
}
if err := json.Unmarshal(content, dest); err != nil {
return err
}
return nil
}

func (s *State) saveFile(filename string, src any) error {
// Create parent directory if it doesn't exist
if _, err := os.Stat(s.config.ConfigDir); err != nil {
if os.IsNotExist(err) {
if err := os.MkdirAll(s.config.ConfigDir, os.ModePerm); err != nil {
return err
}
}
}
tmpPath := filepath.Join(
s.config.ConfigDir,
filename,
)
jsonContent, err := json.Marshal(src)
if err != nil {
return err
}
if err := os.WriteFile(tmpPath, jsonContent, os.ModePerm); err != nil {
return err
}
return nil
}

func (s *State) loadEnvironments() error {
return s.loadFile(environmentsFilename, &(s.Environments))
}

func (s *State) saveEnvironments() error {
return s.saveFile(environmentsFilename, &(s.Environments))
}

0 comments on commit 5ba0a47

Please sign in to comment.