Skip to content
Open
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
31 changes: 30 additions & 1 deletion cmd/aem/osgi.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/wttech/aemc/pkg/common/httpx"
"github.com/wttech/aemc/pkg/common/mapsx"
"github.com/wttech/aemc/pkg/common/pathx"
"github.com/wttech/aemc/pkg/osgi"
"strings"
)

Expand Down Expand Up @@ -204,6 +205,17 @@ func (c *CLI) osgiBundleReadCmd() *cobra.Command {
Short: "Read OSGi bundle details",
Aliases: []string{"get", "find"},
Run: func(cmd *cobra.Command, args []string) {
offline, _ := cmd.Flags().GetBool("offline")
if offline {
manifest, err := osgiBundleManifestByFlags(cmd)
if err != nil {
c.Error(err)
return
}
c.SetOutput("bundle", manifest)
c.Ok("bundle read")
return
}
instance, err := c.aem.InstanceManager().One()
if err != nil {
c.Error(err)
Expand All @@ -219,6 +231,7 @@ func (c *CLI) osgiBundleReadCmd() *cobra.Command {
},
}
osgiBundleDefineFlags(cmd)
cmd.Flags().Bool("offline", false, "Read bundle manifest from local file without connecting to AEM instance")
return cmd
}

Expand Down Expand Up @@ -369,6 +382,18 @@ func osgiBundleDefineFlags(cmd *cobra.Command) {
cmd.MarkFlagsMutuallyExclusive("symbolic-name", "file")
}

func osgiBundleManifestByFlags(cmd *cobra.Command) (*osgi.BundleManifest, error) {
file, _ := cmd.Flags().GetString("file")
if len(file) == 0 {
return nil, fmt.Errorf("flag 'file' is required when using 'offline' mode")
}
fileGlobbed, err := pathx.GlobSome(file)
if err != nil {
return nil, err
}
return osgi.ReadBundleManifest(fileGlobbed)
}

func osgiBundleByFlags(cmd *cobra.Command, i pkg.Instance) (*pkg.OSGiBundle, error) {
symbolicName, _ := cmd.Flags().GetString("symbolic-name")
if len(symbolicName) > 0 {
Expand All @@ -377,7 +402,11 @@ func osgiBundleByFlags(cmd *cobra.Command, i pkg.Instance) (*pkg.OSGiBundle, err
}
file, _ := cmd.Flags().GetString("file")
if len(file) > 0 {
bundle, err := i.OSGI().BundleManager().ByFile(file)
fileGlobbed, err := pathx.GlobSome(file)
if err != nil {
return nil, err
}
bundle, err := i.OSGI().BundleManager().ByFile(fileGlobbed)
return bundle, err
}
return nil, fmt.Errorf("flag 'symbolic-name' or 'file' are required")
Expand Down
10 changes: 7 additions & 3 deletions pkg/osgi/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ import (
func ReadBundleManifest(localPath string) (*BundleManifest, error) {
manifest, err := jar.ReadFile(localPath)
if err != nil {
return nil, fmt.Errorf("cannot read OSGi bundle manifest from file '%s'", localPath)
return nil, fmt.Errorf("cannot read OSGi bundle manifest from file '%s': %w", localPath, err)
}
return &BundleManifest{SymbolicName: manifest[AttributeSymbolicName], Version: manifest[AttributeVersion]}, nil
}

type BundleManifest struct {
SymbolicName string
Version string
SymbolicName string `yaml:"symbolic_name" json:"symbolicName"`
Version string `yaml:"version" json:"version"`
}

func (m BundleManifest) MarshalText() string {
return fmt.Sprintf("symbolic name '%s'\nversion '%s'\n", m.SymbolicName, m.Version)
}

const (
Expand Down
70 changes: 70 additions & 0 deletions pkg/osgi/manifest_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package osgi

import (
"archive/zip"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
)

func createTestJAR(t *testing.T, manifest string) string {
t.Helper()
path := filepath.Join(t.TempDir(), "test-bundle.jar")
f, err := os.Create(path)
assert.NoError(t, err)
defer f.Close()
w := zip.NewWriter(f)
defer w.Close()
entry, err := w.Create("META-INF/MANIFEST.MF")
assert.NoError(t, err)
_, err = entry.Write([]byte(manifest))
assert.NoError(t, err)
return path
}

func TestReadBundleManifest(t *testing.T) {
t.Parallel()

jar := createTestJAR(t, "Manifest-Version: 1.0\r\nBundle-SymbolicName: com.example.test\r\nBundle-Version: 1.2.3\r\n")

manifest, err := ReadBundleManifest(jar)

assert.NoError(t, err)
assert.Equal(t, "com.example.test", manifest.SymbolicName)
assert.Equal(t, "1.2.3", manifest.Version)
}

func TestReadBundleManifestMissingFile(t *testing.T) {
t.Parallel()

_, err := ReadBundleManifest("/nonexistent/bundle.jar")

assert.Error(t, err)
assert.Contains(t, err.Error(), "cannot read OSGi bundle manifest from file")
}

func TestReadBundleManifestInvalidJAR(t *testing.T) {
t.Parallel()

path := filepath.Join(t.TempDir(), "not-a-jar.jar")
err := os.WriteFile(path, []byte("not a jar file"), 0644)
assert.NoError(t, err)

_, err = ReadBundleManifest(path)

assert.Error(t, err)
assert.Contains(t, err.Error(), "cannot read OSGi bundle manifest from file")
}

func TestBundleManifestMarshalText(t *testing.T) {
t.Parallel()

manifest := BundleManifest{SymbolicName: "com.example.test", Version: "1.0.0"}

text := manifest.MarshalText()

assert.Contains(t, text, "com.example.test")
assert.Contains(t, text, "1.0.0")
}