Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions pkg/wpm/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ type Dist struct {
UnpackedSize int `json:"unpackedSize"`
}

// PackageConfig struct to define the package configuration
type PackageConfig struct {
BinDir string `json:"bin-dir,omitempty"`
ContentDir string `json:"content-dir,omitempty"`
PlatformStrict bool `json:"platform-strict,omitempty"` // If set to true, wpm will refuse to install the package if the platform requirements are not met.
}

// Config struct to define the wpm.json schema
type Config struct {
Name string `json:"name" validate:"required,min=3,max=164,package_name_regex"`
Expand All @@ -23,6 +30,7 @@ type Config struct {
Dependencies map[string]string `json:"dependencies,omitempty" validate:"omitempty,package_dependencies"`
DevDependencies map[string]string `json:"devDependencies,omitempty" validate:"omitempty,package_dependencies"`
Scripts map[string]string `json:"scripts,omitempty"`
Config PackageConfig `json:"config,omitempty" validate:"omitempty"`
}

// Meta struct to define the package metadata
Expand Down
110 changes: 110 additions & 0 deletions pkg/wpm/sumfile/sum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package sumfile

import (
"bufio"
"crypto/sha256"
"fmt"
"io"
"os"
"path/filepath"
"sort"
"strings"
"sync"

"github.com/pkg/errors"
)

const SumFile = "wpm.sum"

// Sum represents a single line in the wpm.sum file.
type Sum struct {
Name string
Version string
Hash string
}

// SumDB holds the parsed content of a wpm.sum file.
type SumDB struct {
mu sync.RWMutex
file string
sums map[string]map[string]string // map[name]map[version]hash
}

// NewSumDB creates a new SumDB and loads the sum file from the given path.
func NewSumDB(path string) (*SumDB, error) {
db := &SumDB{
file: filepath.Join(path, SumFile),
sums: make(map[string]map[string]string),
}

f, err := os.Open(db.file)
if err != nil {
if os.IsNotExist(err) {
return db, nil // File doesn't exist, which is fine.
}
return nil, errors.Wrapf(err, "failed to open %s", db.file)
}
defer f.Close()

scanner := bufio.NewScanner(f)
for scanner.Scan() {
parts := strings.Fields(scanner.Text())
if len(parts) != 3 {
continue // Ignore malformed lines
}
if db.sums[parts[0]] == nil {
db.sums[parts[0]] = make(map[string]string)
}
db.sums[parts[0]][parts[1]] = parts[2]
}

return db, scanner.Err()
}

// Add adds a new sum to the database.
func (db *SumDB) Add(name, version, hash string) {
db.mu.Lock()
defer db.mu.Unlock()

if db.sums[name] == nil {
db.sums[name] = make(map[string]string)
}
db.sums[name][version] = hash
}

// Get returns the hash for a given package and version.
func (db *SumDB) Get(name, version string) (string, bool) {
db.mu.RLock()
defer db.mu.RUnlock()

if v, ok := db.sums[name]; ok {
hash, ok := v[version]
return hash, ok
}
return "", false
}

// Save writes the current state of the database back to the wpm.sum file.
func (db *SumDB) Save() error {
db.mu.RLock()
defer db.mu.RUnlock()

var lines []string
for name, versions := range db.sums {
for version, hash := range versions {
lines = append(lines, fmt.Sprintf("%s %s %s", name, version, hash))
}
}
sort.Strings(lines) // For deterministic output

return os.WriteFile(db.file, []byte(strings.Join(lines, "\n")+"\n"), 0644)
}

// CalculateHash computes the SHA256 hash of a reader's content and returns it in "sha256:..." format.
func CalculateHash(r io.Reader) (string, error) {
hasher := sha256.New()
if _, err := io.Copy(hasher, r); err != nil {
return "", err
}
return fmt.Sprintf("sha256:%x", hasher.Sum(nil)), nil
}
Loading