Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
3 changes: 2 additions & 1 deletion cmd/llpkgstore/internal/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/goplus/llpkgstore/config"
"github.com/goplus/llpkgstore/internal/actions/generator/llcppg"
"github.com/goplus/llpkgstore/internal/actions/llpkg"
"github.com/goplus/llpkgstore/internal/file"
"github.com/goplus/llpkgstore/internal/pc"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -65,7 +66,7 @@ func runLLCppgGenerateWithDir(dir string) error {
}
}

generator := llcppg.New(dir, cfg.Upstream.Package.Name, tempDir)
generator := llcppg.New(dir, tempDir, llpkg.PackageName(filepath.Base(dir)))

return generator.Generate(dir)
}
Expand Down
11 changes: 5 additions & 6 deletions cmd/llpkgstore/internal/verification.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ package internal

import (
"encoding/json"
"fmt"
"os"
"os/exec"
"path/filepath"

"github.com/goplus/llpkgstore/config"
"github.com/goplus/llpkgstore/internal/actions"
"github.com/goplus/llpkgstore/internal/actions/env"
"github.com/goplus/llpkgstore/internal/actions/generator/llcppg"
"github.com/goplus/llpkgstore/internal/actions/llpkg"
"github.com/spf13/cobra"
)

Expand All @@ -24,19 +23,19 @@ var verificationCmd = &cobra.Command{
}

func runLLCppgVerificationWithDir(dir string) error {
cfg, err := config.ParseLLPkgConfig(filepath.Join(dir, LLGOModuleIdentifyFile))
pkg, err := llpkg.NewLLPkg(dir)
if err != nil {
return fmt.Errorf("parse config error: %v", err)
return err
}
uc, err := config.NewUpstreamFromConfig(cfg.Upstream)
uc, err := pkg.Upstream()
if err != nil {
return err
}
_, err = uc.Installer.Install(uc.Pkg, dir)
if err != nil {
return err
}
generator := llcppg.New(dir, cfg.Upstream.Package.Name, dir)
generator := llcppg.New(dir, dir, pkg.Name())

generated := filepath.Join(dir, ".generated")
os.Mkdir(generated, 0777)
Expand Down
58 changes: 46 additions & 12 deletions internal/actions/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package actions

import (
"encoding/json"
"errors"
"fmt"
"log"
"os"
Expand All @@ -13,8 +14,9 @@ import (
"strings"
"sync"

"github.com/goplus/llpkgstore/config"
"github.com/goplus/llpkgstore/internal/actions/env"
"github.com/goplus/llpkgstore/internal/actions/llpkg"
"github.com/goplus/llpkgstore/internal/actions/mappingtable"
"github.com/goplus/llpkgstore/internal/actions/versions"
"github.com/goplus/llpkgstore/internal/file"
"github.com/goplus/llpkgstore/internal/pc"
Expand Down Expand Up @@ -96,16 +98,24 @@ func shaFromTag(tag string) string {
return strings.TrimSpace(string(ret))
}

func headSHA() (string, error) {
ret, err := exec.Command("git", "rev-list", "--max-parents", "0", "--abbrev-commit", "HEAD").CombinedOutput()
if err != nil {
return "", errors.New(string(ret))
}
return strings.TrimSpace(string(ret)), nil
}

// parseMappedVersion splits the mapped version string into library name and version.
// Input format: "clib/semver" where semver starts with 'v'
// Panics if input format is invalid or version isn't valid semantic version
func parseMappedVersion(version string) (clib, mappedVersion string, err error) {
func parseMappedVersion(version string) (packageName llpkg.PackageName, mappedVersion string, err error) {
arr := strings.Split(version, "/")
if len(arr) != 2 {
err = fmt.Errorf("actions: invalid mapped version format")
return
}
clib, mappedVersion = arr[0], arr[1]
packageName, mappedVersion = llpkg.PackageName(arr[0]), arr[1]

if !semver.IsValid(mappedVersion) {
err = fmt.Errorf("actions: invalid mapped version format: mappedVersion is not a semver")
Expand All @@ -114,25 +124,35 @@ func parseMappedVersion(version string) (clib, mappedVersion string, err error)
}

// isValidLLPkg checks if directory contains both llpkg.cfg and llcppg.cfg
func isValidLLPkg(files []os.DirEntry) bool {
func isLLPkgRoot(path string) bool {
// don't retrieve files from pr changes, consider about maintenance case
files, err := os.ReadDir(path)
if err != nil {
return false
}
fileMap := make(map[string]struct{}, len(files))

for _, file := range files {
fileMap[filepath.Base(file.Name())] = struct{}{}
}

_, hasLLPkg := fileMap["llpkg.cfg"]
_, hasLLCppg := fileMap["llcppg.cfg"]
return hasLLCppg && hasLLPkg
_, hasGoMod := fileMap["go.mod"]
return hasLLCppg && hasLLPkg && hasGoMod
}

// checkLegacyVersion validates versioning strategy for legacy package submissions
// Ensures semantic versioning compliance and proper branch maintenance strategy
func checkLegacyVersion(ver *versions.Versions, cfg config.LLPkgConfig, mappedVersion string, isLegacy bool) error {
if slices.Contains(ver.GoVersions(cfg.Upstream.Package.Name), mappedVersion) {
func checkLegacyVersion(ver *mappingtable.Versions, pkg *llpkg.LLPkg, mappedVersion string, isLegacy bool) error {
clibName := pkg.ClibName()
clibVersion := pkg.ClibVersion()

if slices.Contains(ver.GoVersions(clibName), mappedVersion) {
return fmt.Errorf("actions: repeat semver %s", mappedVersion)
}
vers := ver.CVersions(cfg.Upstream.Package.Name)
currentVersion := versions.ToSemVer(cfg.Upstream.Package.Version)
vers := ver.CVersions(clibName)
currentVersion := clibVersion.ToSemVer()

// skip when we're the only latest version or C version doesn't follow semver.
if len(vers) == 0 || !semver.IsValid(currentVersion) {
Expand All @@ -148,7 +168,7 @@ func checkLegacyVersion(ver *versions.Versions, cfg config.LLPkgConfig, mappedVe
if isLatest {
// case1: we're the latest version, but mapped version is not latest, invalid.
// example: all version: 1.8.1 => v1.2.0 1.7.1 => v1.1.0 current: 1.9.1 => v1.0.0
if semver.Compare(ver.LatestGoVersion(cfg.Upstream.Package.Name), mappedVersion) > 0 {
if semver.Compare(ver.LatestGoVersion(clibName), mappedVersion) > 0 {
return fmt.Errorf("actions: mapped version should not less than the legacy one")
}
return nil
Expand Down Expand Up @@ -186,11 +206,11 @@ func checkLegacyVersion(ver *versions.Versions, cfg config.LLPkgConfig, mappedVe
// case5: we're the latest patch version for current major and minor, check the mapped version
// our mapped version should be larger than the closest one.
// example: current submit: 1.5.2 => v1.1.1, closest minor: 1.4.1 => v1.1.0, valid.
originalVersion := ver.SearchBySemVer(cfg.Upstream.Package.Name, vers[i])
originalVersion := ver.SearchBySemVer(clibName, vers[i])
if originalVersion == "" {
return fmt.Errorf("actions: cannot find original C version from semver")
}
closestMappedVersion := ver.LatestGoVersionForCVersion(cfg.Upstream.Package.Name, originalVersion)
closestMappedVersion := ver.LatestGoVersionForCVersion(clibName, originalVersion)
if closestMappedVersion == "" {
return fmt.Errorf("cannot find latest Go version from C version")
}
Expand All @@ -201,6 +221,20 @@ func checkLegacyVersion(ver *versions.Versions, cfg config.LLPkgConfig, mappedVe
return nil
}

func readMappingTableCompatible() (*mappingtable.Versions, error) {
ver, created, err := mappingtable.FromRelease()
if err != nil {
return nil, err
}
// if specified release that stores `llpkgstore.json` has created, read llpkgstore.json from release.
// otherwise, read it from github pages for compatibility
if created {
return ver, nil
}
// fallback to legacy gh-pages
return mappingtable.Read("llpkgstore.json"), nil
}

func BuildBinaryZip(uc *upstream.Upstream) (zipFileName, zipFilePath string, err error) {
tempDir, err := os.MkdirTemp("", "llpkg-tool")
if err != nil {
Expand Down
15 changes: 12 additions & 3 deletions internal/actions/actions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,25 @@ import (
"github.com/goplus/llpkgstore/config"
)

func demoDir() (dir string, err error) {
dir, err = os.Getwd()
if err != nil {
return
}
// ../../_demo

dir = filepath.Join("..", "..", "_demo")
return
}

func TestBuildBinaryZip(t *testing.T) {
dir, err := os.Getwd()
demoDir, err := demoDir()
if err != nil {
t.Error(err)
return
}
// ../../_demo

demoDir := filepath.Join(filepath.Dir(filepath.Dir(dir)), "_demo")

cfg, err := config.ParseLLPkgConfig(filepath.Join(demoDir, "llpkg.cfg"))
if err != nil {
t.Error(err)
Expand Down
Loading
Loading