1: <?php
2: declare(strict_types=1);
3: /**
4: * +------------------------------------------------------------+
5: * | apnscp |
6: * +------------------------------------------------------------+
7: * | Copyright (c) Apis Networks |
8: * +------------------------------------------------------------+
9: * | Licensed under Artistic License 2.0 |
10: * +------------------------------------------------------------+
11: * | Author: Matt Saladna (msaladna@apisnetworks.com) |
12: * +------------------------------------------------------------+
13: */
14:
15: /**
16: * Ruby, RoR features formerly under Web_Module
17: *
18: * @package core
19: */
20: class Ruby_Module extends \Module\Support\Anyversion
21: {
22: const LTS = '2.7.6';
23:
24: public function __construct()
25: {
26: $this->exportedFunctions += [
27: 'update_remote' => PRIVILEGE_ADMIN
28: ];
29:
30: parent::__construct();
31: }
32:
33: /**
34: * Execute Ruby within the scope of a version
35: *
36: * @param null|string $version
37: * @param null|string $pwd pwd, defaults to ~
38: * @param string $command
39: * @param array $args optional command arguments
40: * @return array process output from pman_run
41: */
42: public function do(?string $version, ?string $pwd, string $command, ...$args): array
43: {
44: if ($version === 'lts') {
45: $version = $this->get_lts();
46: }
47:
48: return parent::do($version, $pwd, $command, ...$args);
49: }
50:
51: /**
52: * Get configured Ruby LTS
53: *
54: * @return string
55: */
56: protected function get_lts(): string
57: {
58: $prefs = \Preferences::factory($this->getAuthContext());
59:
60: return array_get($prefs, 'ruby.lts', static::LTS);
61: }
62:
63: /**
64: * Update known Ruby versions
65: *
66: * @return bool
67: */
68: public function update_remote(): bool
69: {
70: if (!IS_CLI) {
71: return $this->query('ruby_update_remote');
72: }
73: if (!$root = $this->environmentRoot()) {
74: return error("%(what)s is not available on this system", ['what' => 'rbenv']);
75: }
76:
77: // @TODO move to private repo lest we have an "event-stream" debacle
78: $builddir = $root. '/plugins/ruby-build';
79: $ret = \Util_Process_Safe::exec('cd %(builddir)s && git pull', ['builddir' => $builddir]);
80: if (!$ret['success']) {
81: return error(coalesce($ret['stderr'], $ret['stdout']));
82: }
83: (new \Opcenter\Service\ServiceLayer(null))->dropVirtualCache();
84:
85: return true;
86: }
87:
88: /**
89: * Remove an installed Ruby
90: *
91: * @param string $version
92: * @return bool
93: */
94: public function uninstall(string $version): bool
95: {
96: if ($version === 'lts') {
97: $version = $this->get_lts();
98: }
99:
100: return parent::uninstall($version);
101: }
102:
103: /**
104: * Assign Ruby version to directory
105: *
106: * @param string $version
107: * @param string $path
108: * @return bool
109: */
110: public function make_default(string $version, string $path = '~'): bool
111: {
112: if ($version === 'lts') {
113: $version = $this->get_lts();
114: }
115:
116: return parent::make_default($version, $path);
117: }
118:
119: /**
120: * Install Ruby
121: *
122: * @param string $version
123: * @return null|string version installed, null on failure
124: */
125: public function install(string $version): ?string
126: {
127: if ($version === 'lts') {
128: $version = $this->get_lts();
129: }
130:
131: return parent::install($version);
132: }
133:
134: /**
135: * Ruby version is installed
136: *
137: * @param string $version
138: * @return string|null installed ver
139: */
140: public function installed(string $version, string $comparator = '='): ?string
141: {
142: if ($version === 'lts') {
143: return $this->lts_installed() ? $this->get_lts() : null;
144: }
145:
146: return parent::installed($version, $comparator);
147: }
148:
149: /**
150: * Latest LTS is installed
151: *
152: * @return bool
153: */
154: public function lts_installed(): bool
155: {
156: $versions = $this->list();
157:
158: return \in_array($this->get_lts(), $versions, true);
159: }
160:
161: /**
162: * Set LTS for account
163: *
164: * @param string $version
165: */
166: protected function set_lts(string $version): void
167: {
168: $prefs = \Preferences::factory($this->getAuthContext());
169: $prefs->unlock($this->getApnscpFunctionInterceptor());
170: array_set($prefs, 'ruby.lts', $version);
171: }
172: }