Skip to content

Commit 1556b21

Browse files
Automatic SootWrapper Installation (#281)
* fix spelling mistakes and upgrade embedded SootWrapper * Initial working solution * Refactoring and tests * Hide some defers and tests from linter * windows copy test fix * SootWrapper release archive changed to one file * use current version for soot-wrapper jar * Change name to DEBRICKED_VERSION * fixes after reviews
1 parent 1959b30 commit 1556b21

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+978
-204
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ jobs:
9292
distribution: 'temurin'
9393

9494
- name: Install Debricked CLI
95-
run: go install -ldflags "-X main.version=${GITHUB_REF#refs/heads/}" ./cmd/debricked
95+
run: |
96+
go install -ldflags "-X main.version=${{ secrets.DEBRICKED_VERSION }}" ./cmd/debricked
9697
9798
- name: Callgraph E2E
9899
run: ./scripts/test_e2e_callgraph_java_version.sh ${{matrix.java}}

internal/callgraph/cgexec/command.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,13 @@ func RunCommand(cmd ICommand, ctx IContext) error {
109109
go func() {
110110
err := cmd.Wait()
111111
if err != nil {
112-
err = fmt.Errorf("Command '%s' executed in folder '%s' gave the following error: \n%s\n%s", args, cmd.GetDir(), cmd.GetStdOut().String(), cmd.GetStdErr().String())
112+
err = fmt.Errorf(
113+
"Command '%s' executed in folder '%s' gave the following error: \n%s\n%s",
114+
args,
115+
cmd.GetDir(),
116+
cmd.GetStdOut().String(),
117+
cmd.GetStdErr().String(),
118+
)
113119
}
114120

115121
done <- err

internal/callgraph/config/config.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ type IConfig interface {
66
Kwargs() map[string]string
77
Build() bool
88
PackageManager() string
9+
Version() string
910
}
1011

1112
type Config struct {
@@ -14,15 +15,24 @@ type Config struct {
1415
kwargs map[string]string
1516
build bool
1617
packageManager string
18+
version string
1719
}
1820

19-
func NewConfig(language string, args []string, kwargs map[string]string, build bool, packageManager string) Config {
21+
func NewConfig(
22+
language string,
23+
args []string,
24+
kwargs map[string]string,
25+
build bool,
26+
packageManager string,
27+
version string,
28+
) Config {
2029
return Config{
2130
language,
2231
args,
2332
kwargs,
2433
build,
2534
packageManager,
35+
version,
2636
}
2737
}
2838

@@ -45,3 +55,7 @@ func (c Config) Build() bool {
4555
func (c Config) PackageManager() string {
4656
return c.packageManager
4757
}
58+
59+
func (c Config) Version() string {
60+
return c.version
61+
}

internal/callgraph/generator.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type DebrickedOptions struct {
1616
Inclusions []string
1717
Configs []config.IConfig
1818
Timeout int
19+
Version string
1920
}
2021

2122
type IGenerator interface {

internal/callgraph/generator_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func TestGenerate(t *testing.T) {
3030
)
3131

3232
configs := []config.IConfig{
33-
config.NewConfig("java", []string{}, map[string]string{"pm": "maven"}, true, "maven"),
33+
config.NewConfig("java", []string{}, map[string]string{"pm": "maven"}, true, "maven", ""),
3434
}
3535
ctx, _ := ctxTestdata.NewContextMock()
3636
err := g.Generate(
@@ -51,7 +51,7 @@ func TestGenerateWithTimer(t *testing.T) {
5151
)
5252

5353
configs := []config.IConfig{
54-
config.NewConfig("java", []string{}, map[string]string{"pm": "maven"}, true, "maven"),
54+
config.NewConfig("java", []string{}, map[string]string{"pm": "maven"}, true, "maven", ""),
5555
}
5656
err := g.GenerateWithTimer(
5757
DebrickedOptions{
@@ -73,7 +73,7 @@ func TestGenerateInvokeError(t *testing.T) {
7373
)
7474

7575
configs := []config.IConfig{
76-
config.NewConfig("java", []string{}, map[string]string{"pm": "maven"}, true, "maven"),
76+
config.NewConfig("java", []string{}, map[string]string{"pm": "maven"}, true, "maven", ""),
7777
}
7878
ctx, _ := ctxTestdata.NewContextMock()
7979
err := g.Generate(
@@ -94,7 +94,7 @@ func TestGenerateScheduleError(t *testing.T) {
9494
)
9595

9696
configs := []config.IConfig{
97-
config.NewConfig("java", []string{}, map[string]string{"pm": "maven"}, true, "maven"),
97+
config.NewConfig("java", []string{}, map[string]string{"pm": "maven"}, true, "maven", ""),
9898
}
9999
ctx, _ := ctxTestdata.NewContextMock()
100100
err := g.Generate(

internal/callgraph/language/golang/job_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func TestRun(t *testing.T) {
4747
}
4848
}()
4949

50-
config := conf.NewConfig("golang", nil, nil, true, "go")
50+
config := conf.NewConfig("golang", nil, nil, true, "go", "")
5151
ctx, _ := ctxTestdata.NewContextMock()
5252

5353
rootFileDir := filepath.Dir("testdata/fixture/app.go")
@@ -65,7 +65,7 @@ func TestRun(t *testing.T) {
6565

6666
func TestRunCallgraphMockError(t *testing.T) {
6767
fileWriterMock := &ioTestData.FileWriterMock{}
68-
config := conf.NewConfig("golang", nil, nil, true, "go")
68+
config := conf.NewConfig("golang", nil, nil, true, "go", "")
6969
ctx, _ := ctxTestdata.NewContextMock()
7070
callgraphMock := testdata.CallgraphMock{RunCallGraphError: fmt.Errorf("error")}
7171

@@ -83,7 +83,7 @@ func TestRunCallgraphMockError(t *testing.T) {
8383

8484
func TestRunPostProcessZipFileError(t *testing.T) {
8585
fileWriterMock := &ioTestData.FileWriterMock{}
86-
config := conf.NewConfig("golang", nil, nil, true, "go")
86+
config := conf.NewConfig("golang", nil, nil, true, "go", "")
8787
ctx, _ := ctxTestdata.NewContextMock()
8888
archiveMock := ioTestData.ArchiveMock{ZipFileError: fmt.Errorf("error")}
8989
fs := io.FileSystem{}
@@ -98,7 +98,7 @@ func TestRunPostProcessZipFileError(t *testing.T) {
9898

9999
func TestRunPostProcessB64Error(t *testing.T) {
100100
fileWriterMock := &ioTestData.FileWriterMock{}
101-
config := conf.NewConfig("golang", nil, nil, true, "go")
101+
config := conf.NewConfig("golang", nil, nil, true, "go", "")
102102
ctx, _ := ctxTestdata.NewContextMock()
103103
fs := io.FileSystem{}
104104

@@ -114,7 +114,7 @@ func TestRunPostProcessB64Error(t *testing.T) {
114114

115115
func TestRunPostProcessCleanupError(t *testing.T) {
116116
fileWriterMock := &ioTestData.FileWriterMock{}
117-
config := conf.NewConfig("golang", nil, nil, true, "go")
117+
config := conf.NewConfig("golang", nil, nil, true, "go", "")
118118
ctx, _ := ctxTestdata.NewContextMock()
119119
fs := io.FileSystem{}
120120

@@ -130,7 +130,7 @@ func TestRunPostProcessCleanupError(t *testing.T) {
130130

131131
func TestRunPostProcessCleanupNoFileExistError(t *testing.T) {
132132
fileWriterMock := &ioTestData.FileWriterMock{}
133-
config := conf.NewConfig("golang", nil, nil, true, "go")
133+
config := conf.NewConfig("golang", nil, nil, true, "go", "")
134134
ctx, _ := ctxTestdata.NewContextMock()
135135
fs := io.FileSystem{}
136136

@@ -148,7 +148,7 @@ func TestRunPostProcessCleanupNoFileExistError(t *testing.T) {
148148

149149
func TestRunWithErrorsIsNotExistFalse(t *testing.T) {
150150
fileWriterMock := &ioTestData.FileWriterMock{}
151-
config := conf.NewConfig("golang", nil, nil, true, "go")
151+
config := conf.NewConfig("golang", nil, nil, true, "go", "")
152152
ctx, _ := ctxTestdata.NewContextMock()
153153

154154
fs := ioTestData.FileSystemMock{}
@@ -170,7 +170,7 @@ func TestRunWithErrorsIsNotExistFalse(t *testing.T) {
170170

171171
func TestRunWithErrorsIsNotExistTrue(t *testing.T) {
172172
fileWriterMock := &ioTestData.FileWriterMock{}
173-
config := conf.NewConfig("golang", nil, nil, true, "go")
173+
config := conf.NewConfig("golang", nil, nil, true, "go", "")
174174
ctx, _ := ctxTestdata.NewContextMock()
175175

176176
fs := ioTestData.FileSystemMock{}

internal/callgraph/language/golang/strategy_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func TestNewStrategy(t *testing.T) {
2222
s = NewStrategy(nil, []string{"file-1", "file-2"}, []string{}, []string{}, nil, nil)
2323
assert.NotNil(t, s)
2424

25-
conf := config.NewConfig("golang", []string{"arg1"}, map[string]string{"kwarg": "val"}, true, "go")
25+
conf := config.NewConfig("golang", []string{"arg1"}, map[string]string{"kwarg": "val"}, true, "go", "")
2626
finder := testdata.NewEmptyFinderMock()
2727
testFiles := []string{"file-1"}
2828
finder.FindRootsNames = testFiles
@@ -39,7 +39,7 @@ func TestInvokeNoFiles(t *testing.T) {
3939
}
4040

4141
func TestInvokeOneFile(t *testing.T) {
42-
conf := config.NewConfig("golang", []string{"arg1"}, map[string]string{"kwarg": "val"}, true, "go")
42+
conf := config.NewConfig("golang", []string{"arg1"}, map[string]string{"kwarg": "val"}, true, "go", "")
4343
finder := testdata.NewEmptyFinderMock()
4444
testFiles := []string{"file-1"}
4545
finder.FindRootsNames = testFiles
@@ -51,7 +51,7 @@ func TestInvokeOneFile(t *testing.T) {
5151
}
5252

5353
func TestInvokeManyFiles(t *testing.T) {
54-
conf := config.NewConfig("golang", []string{"arg1"}, map[string]string{"kwarg": "val"}, true, "go")
54+
conf := config.NewConfig("golang", []string{"arg1"}, map[string]string{"kwarg": "val"}, true, "go", "")
5555
finder := testdata.NewEmptyFinderMock()
5656
testFiles := []string{"file-1", "file-2"}
5757
finder.FindRootsNames = testFiles
@@ -62,7 +62,7 @@ func TestInvokeManyFiles(t *testing.T) {
6262
}
6363

6464
func TestInvokeWithErrors(t *testing.T) {
65-
conf := config.NewConfig("golang", []string{"arg1"}, map[string]string{"kwarg": "val"}, true, "go")
65+
conf := config.NewConfig("golang", []string{"arg1"}, map[string]string{"kwarg": "val"}, true, "go", "")
6666
finder := testdata.NewEmptyFinderMock()
6767
testFiles := []string{"file-1", "file-2"}
6868
finder.FindRootsNames = testFiles
@@ -82,7 +82,7 @@ func TestInvokeWithErrors(t *testing.T) {
8282
}
8383

8484
func TestInvokeNoRoots(t *testing.T) {
85-
conf := config.NewConfig("golang", []string{"arg1"}, map[string]string{"kwarg": "val"}, true, "go")
85+
conf := config.NewConfig("golang", []string{"arg1"}, map[string]string{"kwarg": "val"}, true, "go", "")
8686
finder := testdata.NewEmptyFinderMock()
8787
testFiles := []string{}
8888
finder.FindRootsNames = testFiles
File renamed without changes.

internal/callgraph/language/java11/callgraph.go renamed to internal/callgraph/language/java/callgraph.go

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
package java
22

33
import (
4-
"embed"
5-
"path/filepath"
4+
"fmt"
5+
"regexp"
66

77
"github.com/debricked/cli/internal/callgraph/cgexec"
88
ioFs "github.com/debricked/cli/internal/io"
99
)
1010

11-
//go:embed embeded/SootWrapper.jar
12-
var jarCallGraph embed.FS
13-
1411
type ICallgraph interface {
1512
RunCallGraphWithSetup() error
1613
RunCallGraph(callgraphJarPath string) error
@@ -19,11 +16,13 @@ type ICallgraph interface {
1916
type Callgraph struct {
2017
cmdFactory ICmdFactory
2118
filesystem ioFs.IFileSystem
19+
archive ioFs.IArchive
2220
workingDirectory string
2321
targetClasses []string
2422
targetDir string
2523
outputName string
2624
ctx cgexec.IContext
25+
sootHandler ISootHandler
2726
}
2827

2928
func NewCallgraph(
@@ -33,7 +32,9 @@ func NewCallgraph(
3332
targetDir string,
3433
outputName string,
3534
filesystem ioFs.IFileSystem,
35+
archive ioFs.IArchive,
3636
ctx cgexec.IContext,
37+
sootHandler ISootHandler,
3738
) Callgraph {
3839
return Callgraph{
3940
cmdFactory: cmdFactory,
@@ -42,43 +43,59 @@ func NewCallgraph(
4243
targetDir: targetDir,
4344
outputName: outputName,
4445
filesystem: filesystem,
46+
archive: archive,
4547
ctx: ctx,
48+
sootHandler: sootHandler,
4649
}
4750
}
4851

4952
func (cg *Callgraph) RunCallGraphWithSetup() error {
50-
jarFile, err := cg.filesystem.FsOpenEmbed(jarCallGraph, "embeded/SootWrapper.jar")
53+
version, err := cg.javaVersion(".")
5154
if err != nil {
5255
return err
5356
}
54-
defer cg.filesystem.FsCloseFile(jarFile)
5557

56-
tempDir, err := cg.filesystem.MkdirTemp("jar")
58+
jarFile, err := cg.sootHandler.GetSootWrapper(version, cg.filesystem, cg.archive)
5759
if err != nil {
60+
5861
return err
5962
}
60-
defer cg.filesystem.RemoveAll(tempDir)
61-
tempJarFile := filepath.Join(tempDir, "SootWrapper.jar")
6263

63-
jarBytes, err := cg.filesystem.FsReadAll(jarFile)
64-
if err != nil {
64+
err = cg.RunCallGraph(jarFile)
6565

66-
return err
67-
}
66+
return err
67+
}
6868

69-
err = cg.filesystem.FsWriteFile(tempJarFile, jarBytes, 0600)
69+
func (cg *Callgraph) javaVersion(path string) (string, error) {
70+
osCmd, err := cg.cmdFactory.MakeJavaVersionCmd(path, cg.ctx)
7071
if err != nil {
7172

72-
return err
73+
return "", err
7374
}
7475

75-
err = cg.RunCallGraph(tempJarFile)
76-
77-
return err
76+
cmd := cgexec.NewCommand(osCmd)
77+
err = cgexec.RunCommand(*cmd, cg.ctx)
78+
if err != nil {
79+
return "", err
80+
}
81+
javaVersionRegex := regexp.MustCompile(`\b(\d+)\.\d+\.\d+\b`)
82+
match := javaVersionRegex.FindStringSubmatch(cmd.GetStdOut().String())
83+
if len(match) > 1 {
84+
return match[1], nil
85+
} else {
86+
return "", fmt.Errorf("no version found in 'java --version' output, are you using a non-numeric version?")
87+
}
7888
}
7989

8090
func (cg *Callgraph) RunCallGraph(callgraphJarPath string) error {
81-
osCmd, err := cg.cmdFactory.MakeCallGraphGenerationCmd(callgraphJarPath, cg.workingDirectory, cg.targetClasses, cg.targetDir, cg.outputName, cg.ctx)
91+
osCmd, err := cg.cmdFactory.MakeCallGraphGenerationCmd(
92+
callgraphJarPath,
93+
cg.workingDirectory,
94+
cg.targetClasses,
95+
cg.targetDir,
96+
cg.outputName,
97+
cg.ctx,
98+
)
8299
if err != nil {
83100

84101
return err

0 commit comments

Comments
 (0)