Skip to content

Commit 5f665ff

Browse files
authored
Merge pull request #3730 from ActiveState/mitchell/cp-1029
Initial ecosystem implementation for R.
2 parents 18170e2 + 0cf8b0d commit 5f665ff

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

pkg/runtime/ecosystem.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ func init() {
2222
func() ecosystem { return &ecosys.Rust{} },
2323
func() ecosystem { return &ecosys.DotNet{} },
2424
func() ecosystem { return &ecosys.Golang{} },
25+
func() ecosystem { return &ecosys.R{} },
2526
}
2627
}
2728

pkg/runtime/ecosystem/javascript.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type JavaScript struct {
2424
func (e *JavaScript) Init(runtimePath string, buildplan *buildplan.BuildPlan) error {
2525
e.runtimePath = runtimePath
2626
e.installPackages = []string{}
27+
e.uninstallPackages = []string{}
2728
return nil
2829
}
2930

@@ -46,7 +47,7 @@ func (e *JavaScript) Add(artifact *buildplan.Artifact, artifactSrcPath string) (
4647
continue
4748
}
4849
ext := filepath.Ext(file.Name())
49-
if ext != ".tar.gz" && ext != ".tgz" {
50+
if ext != ".gz" && ext != ".tgz" {
5051
continue
5152
}
5253
if !strings.HasPrefix(file.Name(), packageName) {

pkg/runtime/ecosystem/r.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package ecosystem
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"path/filepath"
7+
"strings"
8+
9+
"github.com/ActiveState/cli/internal/errs"
10+
"github.com/ActiveState/cli/internal/fileutils"
11+
"github.com/ActiveState/cli/internal/osutils"
12+
13+
"github.com/ActiveState/cli/pkg/buildplan"
14+
)
15+
16+
const rLibraryDir = "usr/lib/R/library"
17+
18+
type R struct {
19+
runtimePath string
20+
installPackages []string
21+
}
22+
23+
func (e *R) Init(runtimePath string, buildplan *buildplan.BuildPlan) error {
24+
e.runtimePath = runtimePath
25+
e.installPackages = []string{}
26+
return nil
27+
}
28+
29+
func (e *R) Namespaces() []string {
30+
return []string{"language/R"}
31+
}
32+
33+
func (e *R) Add(artifact *buildplan.Artifact, artifactSrcPath string) ([]string, error) {
34+
files, err := fileutils.ListDir(artifactSrcPath, false)
35+
if err != nil {
36+
return nil, errs.Wrap(err, "Unable to read artifact source directory")
37+
}
38+
packageName := artifact.Name()
39+
for _, file := range files {
40+
ext := filepath.Ext(file.Name())
41+
if ext != ".gz" && ext != ".tgz" && ext != ".zip" {
42+
continue
43+
}
44+
e.installPackages = append(e.installPackages, file.AbsolutePath())
45+
}
46+
installedDir := filepath.Join(rLibraryDir, packageName) // Apply() will install here
47+
return []string{installedDir}, nil
48+
}
49+
50+
func (e *R) Remove(name, version string, installedFiles []string) (rerr error) {
51+
for _, dir := range installedFiles {
52+
if !fileutils.DirExists(dir) {
53+
continue
54+
}
55+
err := os.RemoveAll(dir)
56+
if err != nil {
57+
rerr = errs.Pack(rerr, errs.Wrap(err, "Unable to remove directory for '%s': %s", name, dir))
58+
}
59+
}
60+
return rerr
61+
}
62+
63+
func (e *R) Apply() error {
64+
if len(e.installPackages) == 0 {
65+
return nil // nothing to do
66+
}
67+
68+
binDir := filepath.Join(e.runtimePath, "usr", "bin")
69+
tgzs := []string{}
70+
for _, tgz := range e.installPackages {
71+
tgzs = append(tgzs, fmt.Sprintf(`"%s"`, tgz))
72+
}
73+
args := []string{
74+
"-e",
75+
fmt.Sprintf("install.packages(c(%s), lib='%s', repos=NULL)",
76+
strings.Join(tgzs, ","), filepath.Join(e.runtimePath, rLibraryDir)),
77+
}
78+
env := []string{}
79+
80+
_, stderr, err := osutils.ExecSimple(filepath.Join(binDir, "R"), args, env)
81+
if err != nil {
82+
return errs.Wrap(err, "Error running R: %s", stderr)
83+
}
84+
85+
return nil
86+
}

0 commit comments

Comments
 (0)