@kapeta/local-cluster-service 0.19.1 → 0.19.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/src/RepositoryWatcher.d.ts +3 -1
- package/dist/cjs/src/RepositoryWatcher.js +11 -3
- package/dist/cjs/src/codeGeneratorManager.d.ts +2 -0
- package/dist/cjs/src/codeGeneratorManager.js +46 -11
- package/dist/cjs/src/repositoryManager.d.ts +3 -1
- package/dist/cjs/src/repositoryManager.js +6 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/src/RepositoryWatcher.d.ts +3 -1
- package/dist/esm/src/RepositoryWatcher.js +11 -3
- package/dist/esm/src/codeGeneratorManager.d.ts +2 -0
- package/dist/esm/src/codeGeneratorManager.js +46 -11
- package/dist/esm/src/repositoryManager.d.ts +3 -1
- package/dist/esm/src/repositoryManager.js +6 -1
- package/index.ts +2 -0
- package/package.json +1 -1
- package/src/RepositoryWatcher.ts +11 -3
- package/src/codeGeneratorManager.ts +55 -11
- package/src/repositoryManager.ts +7 -1
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## [0.19.2](https://github.com/kapetacom/local-cluster-service/compare/v0.19.1...v0.19.2) (2023-09-05)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* Control boot order and reload code gen targets when repo changes ([#68](https://github.com/kapetacom/local-cluster-service/issues/68)) ([5557259](https://github.com/kapetacom/local-cluster-service/commit/5557259dda10f509a2b8cc45c0b4a4631e1d975a))
|
7
|
+
|
1
8
|
## [0.19.1](https://github.com/kapetacom/local-cluster-service/compare/v0.19.0...v0.19.1) (2023-09-03)
|
2
9
|
|
3
10
|
|
package/dist/cjs/index.js
CHANGED
@@ -28,6 +28,7 @@ const repositoryManager_1 = require("./src/repositoryManager");
|
|
28
28
|
const commandLineUtils_1 = require("./src/utils/commandLineUtils");
|
29
29
|
const DefaultProviderInstaller_1 = require("./src/utils/DefaultProviderInstaller");
|
30
30
|
const authManager_1 = require("./src/authManager");
|
31
|
+
const codeGeneratorManager_1 = require("./src/codeGeneratorManager");
|
31
32
|
let currentServer = null;
|
32
33
|
function createServer() {
|
33
34
|
const app = (0, express_1.default)();
|
@@ -109,6 +110,7 @@ exports.default = {
|
|
109
110
|
console.error('Could not ping docker runtime: ' + e.toString() + '. Make sure docker is running and working.');
|
110
111
|
}
|
111
112
|
await DefaultProviderInstaller_1.defaultProviderInstaller.checkForDefault();
|
113
|
+
await codeGeneratorManager_1.codeGeneratorManager.initialize();
|
112
114
|
const clusterPort = storageService_1.storageService.get('cluster', 'port');
|
113
115
|
if (clusterPort) {
|
114
116
|
clusterService_1.clusterService.setClusterServicePort(clusterPort);
|
@@ -1,5 +1,7 @@
|
|
1
|
+
/// <reference types="node" />
|
1
2
|
import { SourceOfChange } from './types';
|
2
|
-
|
3
|
+
import { EventEmitter } from 'node:events';
|
4
|
+
export declare class RepositoryWatcher extends EventEmitter {
|
3
5
|
private watcher?;
|
4
6
|
private disabled;
|
5
7
|
private readonly baseDir;
|
@@ -13,8 +13,9 @@ const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
|
13
13
|
const lodash_1 = __importDefault(require("lodash"));
|
14
14
|
const socketManager_1 = require("./socketManager");
|
15
15
|
const cacheManager_1 = require("./cacheManager");
|
16
|
+
const node_events_1 = require("node:events");
|
16
17
|
const KAPETA_YML_RX = /^kapeta.ya?ml$/;
|
17
|
-
class RepositoryWatcher {
|
18
|
+
class RepositoryWatcher extends node_events_1.EventEmitter {
|
18
19
|
watcher;
|
19
20
|
disabled = false;
|
20
21
|
baseDir;
|
@@ -22,6 +23,7 @@ class RepositoryWatcher {
|
|
22
23
|
symbolicLinks = {};
|
23
24
|
sourceOfChange = new Map();
|
24
25
|
constructor() {
|
26
|
+
super();
|
25
27
|
this.baseDir = local_cluster_config_1.default.getRepositoryBasedir();
|
26
28
|
}
|
27
29
|
setDisabled(disabled) {
|
@@ -204,6 +206,7 @@ class RepositoryWatcher {
|
|
204
206
|
this.allDefinitions = newDefinitions;
|
205
207
|
//console.log('Asset changed', payload);
|
206
208
|
socketManager_1.socketManager.emitGlobal('asset-change', payload);
|
209
|
+
this.emit('change', payload);
|
207
210
|
cacheManager_1.cacheManager.flush();
|
208
211
|
}
|
209
212
|
async exists(path) {
|
@@ -234,8 +237,13 @@ class RepositoryWatcher {
|
|
234
237
|
try {
|
235
238
|
// Make sure we're not watching the symlink target
|
236
239
|
await this.removeSymlinkTarget(path);
|
237
|
-
|
238
|
-
|
240
|
+
let symbolicLink = false;
|
241
|
+
try {
|
242
|
+
const stat = await fs_extra_1.default.lstat(path);
|
243
|
+
symbolicLink = stat.isSymbolicLink();
|
244
|
+
}
|
245
|
+
catch (e) { }
|
246
|
+
if (symbolicLink) {
|
239
247
|
const realPath = `${await fs_extra_1.default.realpath(path)}/kapeta.yml`;
|
240
248
|
if (await this.exists(realPath)) {
|
241
249
|
//console.log('Watching symlink target %s => %s', path, realPath);
|
@@ -1,6 +1,8 @@
|
|
1
1
|
import { BlockDefinition } from '@kapeta/schemas';
|
2
2
|
declare class CodeGeneratorManager {
|
3
|
+
private ensureLanguageTargetInRegistry;
|
3
4
|
reload(): Promise<void>;
|
5
|
+
initialize(): Promise<void>;
|
4
6
|
canGenerateCode(yamlContent: BlockDefinition): Promise<boolean>;
|
5
7
|
generate(yamlFile: string, yamlContent: BlockDefinition): Promise<void>;
|
6
8
|
}
|
@@ -7,27 +7,51 @@ exports.codeGeneratorManager = void 0;
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
8
8
|
const codegen_1 = require("@kapeta/codegen");
|
9
9
|
const definitionsManager_1 = require("./definitionsManager");
|
10
|
+
const assetManager_1 = require("./assetManager");
|
11
|
+
const utils_1 = require("./utils/utils");
|
12
|
+
const repositoryManager_1 = require("./repositoryManager");
|
10
13
|
const TARGET_KIND = 'core/language-target';
|
11
14
|
const BLOCK_TYPE_KIND = 'core/block-type';
|
12
15
|
class CodeGeneratorManager {
|
16
|
+
async ensureLanguageTargetInRegistry(path, version, definition) {
|
17
|
+
const key = `${definition.metadata.name}:${version}`;
|
18
|
+
try {
|
19
|
+
if (await codegen_1.registry.get(key)) {
|
20
|
+
return;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
catch (e) { }
|
24
|
+
try {
|
25
|
+
const target = require(path);
|
26
|
+
if (target.default) {
|
27
|
+
codegen_1.registry.register(key, target.default);
|
28
|
+
}
|
29
|
+
else {
|
30
|
+
codegen_1.registry.register(key, target);
|
31
|
+
}
|
32
|
+
}
|
33
|
+
catch (e) {
|
34
|
+
console.error('Failed to load target: %s', key, e);
|
35
|
+
}
|
36
|
+
}
|
13
37
|
async reload() {
|
14
38
|
codegen_1.registry.reset();
|
15
39
|
const languageTargets = await definitionsManager_1.definitionsManager.getDefinitions(TARGET_KIND);
|
16
40
|
for (const languageTarget of languageTargets) {
|
17
|
-
|
41
|
+
await this.ensureLanguageTargetInRegistry(languageTarget.path, languageTarget.version, languageTarget.definition);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
async initialize() {
|
45
|
+
await this.reload();
|
46
|
+
repositoryManager_1.repositoryManager.on('change', async () => {
|
47
|
+
// Reload code generators when the repository changes
|
18
48
|
try {
|
19
|
-
|
20
|
-
if (target.default) {
|
21
|
-
codegen_1.registry.register(key, target.default);
|
22
|
-
}
|
23
|
-
else {
|
24
|
-
codegen_1.registry.register(key, target);
|
25
|
-
}
|
49
|
+
await this.reload();
|
26
50
|
}
|
27
51
|
catch (e) {
|
28
|
-
console.error('Failed to
|
52
|
+
console.error('Failed to reload code generators', e);
|
29
53
|
}
|
30
|
-
}
|
54
|
+
});
|
31
55
|
}
|
32
56
|
async canGenerateCode(yamlContent) {
|
33
57
|
if (!yamlContent.spec.target?.kind) {
|
@@ -39,6 +63,18 @@ class CodeGeneratorManager {
|
|
39
63
|
return !!(yamlContent && yamlContent.kind && blockTypeKinds.indexOf(yamlContent.kind.toLowerCase()) > -1);
|
40
64
|
}
|
41
65
|
async generate(yamlFile, yamlContent) {
|
66
|
+
if (!yamlContent.spec.target?.kind) {
|
67
|
+
//Not all block types have targets
|
68
|
+
return;
|
69
|
+
}
|
70
|
+
const targetRef = (0, utils_1.normalizeKapetaUri)(yamlContent.spec.target?.kind);
|
71
|
+
// Automatically downloads target if not available
|
72
|
+
const targetAsset = await assetManager_1.assetManager.getAsset(targetRef);
|
73
|
+
if (!targetAsset) {
|
74
|
+
console.error('Language target not found: %s', yamlContent.spec.target?.kind);
|
75
|
+
return;
|
76
|
+
}
|
77
|
+
await this.ensureLanguageTargetInRegistry(targetAsset?.path, targetAsset?.version, targetAsset?.data);
|
42
78
|
const baseDir = path_1.default.dirname(yamlFile);
|
43
79
|
console.log('Generating code for path: %s', baseDir);
|
44
80
|
const codeGenerator = new codegen_1.BlockCodeGenerator(yamlContent);
|
@@ -50,4 +86,3 @@ class CodeGeneratorManager {
|
|
50
86
|
}
|
51
87
|
}
|
52
88
|
exports.codeGeneratorManager = new CodeGeneratorManager();
|
53
|
-
exports.codeGeneratorManager.reload();
|
@@ -1,6 +1,8 @@
|
|
1
|
+
/// <reference types="node" />
|
1
2
|
import { Task } from './taskManager';
|
2
3
|
import { SourceOfChange } from './types';
|
3
|
-
|
4
|
+
import { EventEmitter } from 'node:events';
|
5
|
+
declare class RepositoryManager extends EventEmitter {
|
4
6
|
private _registryService;
|
5
7
|
private watcher;
|
6
8
|
constructor();
|
@@ -13,6 +13,7 @@ const utils_1 = require("./utils/utils");
|
|
13
13
|
const progressListener_1 = require("./progressListener");
|
14
14
|
const RepositoryWatcher_1 = require("./RepositoryWatcher");
|
15
15
|
const cacheManager_1 = require("./cacheManager");
|
16
|
+
const node_events_1 = require("node:events");
|
16
17
|
const EVENT_DEFAULT_PROVIDERS_START = 'default-providers-start';
|
17
18
|
const EVENT_DEFAULT_PROVIDERS_END = 'default-providers-end';
|
18
19
|
const DEFAULT_PROVIDERS = [
|
@@ -29,13 +30,17 @@ const DEFAULT_PROVIDERS = [
|
|
29
30
|
'kapeta/language-target-nodejs',
|
30
31
|
'kapeta/language-target-java-spring-boot',
|
31
32
|
];
|
32
|
-
class RepositoryManager {
|
33
|
+
class RepositoryManager extends node_events_1.EventEmitter {
|
33
34
|
_registryService;
|
34
35
|
watcher;
|
35
36
|
constructor() {
|
37
|
+
super();
|
36
38
|
this._registryService = new nodejs_registry_utils_1.RegistryService(nodejs_registry_utils_1.Config.data.registry.url);
|
37
39
|
this.watcher = new RepositoryWatcher_1.RepositoryWatcher();
|
38
40
|
this.listenForChanges();
|
41
|
+
this.watcher.on('change', (file, source) => {
|
42
|
+
this.emit('change', file, source);
|
43
|
+
});
|
39
44
|
}
|
40
45
|
listenForChanges() {
|
41
46
|
this.watcher.watch();
|
package/dist/esm/index.js
CHANGED
@@ -28,6 +28,7 @@ const repositoryManager_1 = require("./src/repositoryManager");
|
|
28
28
|
const commandLineUtils_1 = require("./src/utils/commandLineUtils");
|
29
29
|
const DefaultProviderInstaller_1 = require("./src/utils/DefaultProviderInstaller");
|
30
30
|
const authManager_1 = require("./src/authManager");
|
31
|
+
const codeGeneratorManager_1 = require("./src/codeGeneratorManager");
|
31
32
|
let currentServer = null;
|
32
33
|
function createServer() {
|
33
34
|
const app = (0, express_1.default)();
|
@@ -109,6 +110,7 @@ exports.default = {
|
|
109
110
|
console.error('Could not ping docker runtime: ' + e.toString() + '. Make sure docker is running and working.');
|
110
111
|
}
|
111
112
|
await DefaultProviderInstaller_1.defaultProviderInstaller.checkForDefault();
|
113
|
+
await codeGeneratorManager_1.codeGeneratorManager.initialize();
|
112
114
|
const clusterPort = storageService_1.storageService.get('cluster', 'port');
|
113
115
|
if (clusterPort) {
|
114
116
|
clusterService_1.clusterService.setClusterServicePort(clusterPort);
|
@@ -1,5 +1,7 @@
|
|
1
|
+
/// <reference types="node" />
|
1
2
|
import { SourceOfChange } from './types';
|
2
|
-
|
3
|
+
import { EventEmitter } from 'node:events';
|
4
|
+
export declare class RepositoryWatcher extends EventEmitter {
|
3
5
|
private watcher?;
|
4
6
|
private disabled;
|
5
7
|
private readonly baseDir;
|
@@ -13,8 +13,9 @@ const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
|
13
13
|
const lodash_1 = __importDefault(require("lodash"));
|
14
14
|
const socketManager_1 = require("./socketManager");
|
15
15
|
const cacheManager_1 = require("./cacheManager");
|
16
|
+
const node_events_1 = require("node:events");
|
16
17
|
const KAPETA_YML_RX = /^kapeta.ya?ml$/;
|
17
|
-
class RepositoryWatcher {
|
18
|
+
class RepositoryWatcher extends node_events_1.EventEmitter {
|
18
19
|
watcher;
|
19
20
|
disabled = false;
|
20
21
|
baseDir;
|
@@ -22,6 +23,7 @@ class RepositoryWatcher {
|
|
22
23
|
symbolicLinks = {};
|
23
24
|
sourceOfChange = new Map();
|
24
25
|
constructor() {
|
26
|
+
super();
|
25
27
|
this.baseDir = local_cluster_config_1.default.getRepositoryBasedir();
|
26
28
|
}
|
27
29
|
setDisabled(disabled) {
|
@@ -204,6 +206,7 @@ class RepositoryWatcher {
|
|
204
206
|
this.allDefinitions = newDefinitions;
|
205
207
|
//console.log('Asset changed', payload);
|
206
208
|
socketManager_1.socketManager.emitGlobal('asset-change', payload);
|
209
|
+
this.emit('change', payload);
|
207
210
|
cacheManager_1.cacheManager.flush();
|
208
211
|
}
|
209
212
|
async exists(path) {
|
@@ -234,8 +237,13 @@ class RepositoryWatcher {
|
|
234
237
|
try {
|
235
238
|
// Make sure we're not watching the symlink target
|
236
239
|
await this.removeSymlinkTarget(path);
|
237
|
-
|
238
|
-
|
240
|
+
let symbolicLink = false;
|
241
|
+
try {
|
242
|
+
const stat = await fs_extra_1.default.lstat(path);
|
243
|
+
symbolicLink = stat.isSymbolicLink();
|
244
|
+
}
|
245
|
+
catch (e) { }
|
246
|
+
if (symbolicLink) {
|
239
247
|
const realPath = `${await fs_extra_1.default.realpath(path)}/kapeta.yml`;
|
240
248
|
if (await this.exists(realPath)) {
|
241
249
|
//console.log('Watching symlink target %s => %s', path, realPath);
|
@@ -1,6 +1,8 @@
|
|
1
1
|
import { BlockDefinition } from '@kapeta/schemas';
|
2
2
|
declare class CodeGeneratorManager {
|
3
|
+
private ensureLanguageTargetInRegistry;
|
3
4
|
reload(): Promise<void>;
|
5
|
+
initialize(): Promise<void>;
|
4
6
|
canGenerateCode(yamlContent: BlockDefinition): Promise<boolean>;
|
5
7
|
generate(yamlFile: string, yamlContent: BlockDefinition): Promise<void>;
|
6
8
|
}
|
@@ -7,27 +7,51 @@ exports.codeGeneratorManager = void 0;
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
8
8
|
const codegen_1 = require("@kapeta/codegen");
|
9
9
|
const definitionsManager_1 = require("./definitionsManager");
|
10
|
+
const assetManager_1 = require("./assetManager");
|
11
|
+
const utils_1 = require("./utils/utils");
|
12
|
+
const repositoryManager_1 = require("./repositoryManager");
|
10
13
|
const TARGET_KIND = 'core/language-target';
|
11
14
|
const BLOCK_TYPE_KIND = 'core/block-type';
|
12
15
|
class CodeGeneratorManager {
|
16
|
+
async ensureLanguageTargetInRegistry(path, version, definition) {
|
17
|
+
const key = `${definition.metadata.name}:${version}`;
|
18
|
+
try {
|
19
|
+
if (await codegen_1.registry.get(key)) {
|
20
|
+
return;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
catch (e) { }
|
24
|
+
try {
|
25
|
+
const target = require(path);
|
26
|
+
if (target.default) {
|
27
|
+
codegen_1.registry.register(key, target.default);
|
28
|
+
}
|
29
|
+
else {
|
30
|
+
codegen_1.registry.register(key, target);
|
31
|
+
}
|
32
|
+
}
|
33
|
+
catch (e) {
|
34
|
+
console.error('Failed to load target: %s', key, e);
|
35
|
+
}
|
36
|
+
}
|
13
37
|
async reload() {
|
14
38
|
codegen_1.registry.reset();
|
15
39
|
const languageTargets = await definitionsManager_1.definitionsManager.getDefinitions(TARGET_KIND);
|
16
40
|
for (const languageTarget of languageTargets) {
|
17
|
-
|
41
|
+
await this.ensureLanguageTargetInRegistry(languageTarget.path, languageTarget.version, languageTarget.definition);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
async initialize() {
|
45
|
+
await this.reload();
|
46
|
+
repositoryManager_1.repositoryManager.on('change', async () => {
|
47
|
+
// Reload code generators when the repository changes
|
18
48
|
try {
|
19
|
-
|
20
|
-
if (target.default) {
|
21
|
-
codegen_1.registry.register(key, target.default);
|
22
|
-
}
|
23
|
-
else {
|
24
|
-
codegen_1.registry.register(key, target);
|
25
|
-
}
|
49
|
+
await this.reload();
|
26
50
|
}
|
27
51
|
catch (e) {
|
28
|
-
console.error('Failed to
|
52
|
+
console.error('Failed to reload code generators', e);
|
29
53
|
}
|
30
|
-
}
|
54
|
+
});
|
31
55
|
}
|
32
56
|
async canGenerateCode(yamlContent) {
|
33
57
|
if (!yamlContent.spec.target?.kind) {
|
@@ -39,6 +63,18 @@ class CodeGeneratorManager {
|
|
39
63
|
return !!(yamlContent && yamlContent.kind && blockTypeKinds.indexOf(yamlContent.kind.toLowerCase()) > -1);
|
40
64
|
}
|
41
65
|
async generate(yamlFile, yamlContent) {
|
66
|
+
if (!yamlContent.spec.target?.kind) {
|
67
|
+
//Not all block types have targets
|
68
|
+
return;
|
69
|
+
}
|
70
|
+
const targetRef = (0, utils_1.normalizeKapetaUri)(yamlContent.spec.target?.kind);
|
71
|
+
// Automatically downloads target if not available
|
72
|
+
const targetAsset = await assetManager_1.assetManager.getAsset(targetRef);
|
73
|
+
if (!targetAsset) {
|
74
|
+
console.error('Language target not found: %s', yamlContent.spec.target?.kind);
|
75
|
+
return;
|
76
|
+
}
|
77
|
+
await this.ensureLanguageTargetInRegistry(targetAsset?.path, targetAsset?.version, targetAsset?.data);
|
42
78
|
const baseDir = path_1.default.dirname(yamlFile);
|
43
79
|
console.log('Generating code for path: %s', baseDir);
|
44
80
|
const codeGenerator = new codegen_1.BlockCodeGenerator(yamlContent);
|
@@ -50,4 +86,3 @@ class CodeGeneratorManager {
|
|
50
86
|
}
|
51
87
|
}
|
52
88
|
exports.codeGeneratorManager = new CodeGeneratorManager();
|
53
|
-
exports.codeGeneratorManager.reload();
|
@@ -1,6 +1,8 @@
|
|
1
|
+
/// <reference types="node" />
|
1
2
|
import { Task } from './taskManager';
|
2
3
|
import { SourceOfChange } from './types';
|
3
|
-
|
4
|
+
import { EventEmitter } from 'node:events';
|
5
|
+
declare class RepositoryManager extends EventEmitter {
|
4
6
|
private _registryService;
|
5
7
|
private watcher;
|
6
8
|
constructor();
|
@@ -13,6 +13,7 @@ const utils_1 = require("./utils/utils");
|
|
13
13
|
const progressListener_1 = require("./progressListener");
|
14
14
|
const RepositoryWatcher_1 = require("./RepositoryWatcher");
|
15
15
|
const cacheManager_1 = require("./cacheManager");
|
16
|
+
const node_events_1 = require("node:events");
|
16
17
|
const EVENT_DEFAULT_PROVIDERS_START = 'default-providers-start';
|
17
18
|
const EVENT_DEFAULT_PROVIDERS_END = 'default-providers-end';
|
18
19
|
const DEFAULT_PROVIDERS = [
|
@@ -29,13 +30,17 @@ const DEFAULT_PROVIDERS = [
|
|
29
30
|
'kapeta/language-target-nodejs',
|
30
31
|
'kapeta/language-target-java-spring-boot',
|
31
32
|
];
|
32
|
-
class RepositoryManager {
|
33
|
+
class RepositoryManager extends node_events_1.EventEmitter {
|
33
34
|
_registryService;
|
34
35
|
watcher;
|
35
36
|
constructor() {
|
37
|
+
super();
|
36
38
|
this._registryService = new nodejs_registry_utils_1.RegistryService(nodejs_registry_utils_1.Config.data.registry.url);
|
37
39
|
this.watcher = new RepositoryWatcher_1.RepositoryWatcher();
|
38
40
|
this.listenForChanges();
|
41
|
+
this.watcher.on('change', (file, source) => {
|
42
|
+
this.emit('change', file, source);
|
43
|
+
});
|
39
44
|
}
|
40
45
|
listenForChanges() {
|
41
46
|
this.watcher.watch();
|
package/index.ts
CHANGED
@@ -24,6 +24,7 @@ import { repositoryManager } from './src/repositoryManager';
|
|
24
24
|
import { ensureCLI } from './src/utils/commandLineUtils';
|
25
25
|
import { defaultProviderInstaller } from './src/utils/DefaultProviderInstaller';
|
26
26
|
import { authManager } from './src/authManager';
|
27
|
+
import { codeGeneratorManager } from './src/codeGeneratorManager';
|
27
28
|
|
28
29
|
export type LocalClusterService = HTTP.Server & { host?: string; port?: number };
|
29
30
|
|
@@ -125,6 +126,7 @@ export default {
|
|
125
126
|
}
|
126
127
|
|
127
128
|
await defaultProviderInstaller.checkForDefault();
|
129
|
+
await codeGeneratorManager.initialize();
|
128
130
|
|
129
131
|
const clusterPort = storageService.get('cluster', 'port');
|
130
132
|
if (clusterPort) {
|
package/package.json
CHANGED
package/src/RepositoryWatcher.ts
CHANGED
@@ -8,6 +8,7 @@ import _ from 'lodash';
|
|
8
8
|
import { socketManager } from './socketManager';
|
9
9
|
import { SourceOfChange, WatchEventName } from './types';
|
10
10
|
import { cacheManager } from './cacheManager';
|
11
|
+
import { EventEmitter } from 'node:events';
|
11
12
|
|
12
13
|
interface AssetIdentity {
|
13
14
|
handle: string;
|
@@ -15,7 +16,7 @@ interface AssetIdentity {
|
|
15
16
|
version: string;
|
16
17
|
}
|
17
18
|
const KAPETA_YML_RX = /^kapeta.ya?ml$/;
|
18
|
-
export class RepositoryWatcher {
|
19
|
+
export class RepositoryWatcher extends EventEmitter {
|
19
20
|
private watcher?: FSWatcher;
|
20
21
|
private disabled: boolean = false;
|
21
22
|
private readonly baseDir: string;
|
@@ -23,6 +24,7 @@ export class RepositoryWatcher {
|
|
23
24
|
private symbolicLinks: { [link: string]: string } = {};
|
24
25
|
private sourceOfChange: Map<string, SourceOfChange> = new Map();
|
25
26
|
constructor() {
|
27
|
+
super();
|
26
28
|
this.baseDir = ClusterConfiguration.getRepositoryBasedir();
|
27
29
|
}
|
28
30
|
|
@@ -228,6 +230,7 @@ export class RepositoryWatcher {
|
|
228
230
|
|
229
231
|
//console.log('Asset changed', payload);
|
230
232
|
socketManager.emitGlobal('asset-change', payload);
|
233
|
+
this.emit('change', payload);
|
231
234
|
|
232
235
|
cacheManager.flush();
|
233
236
|
}
|
@@ -261,8 +264,13 @@ export class RepositoryWatcher {
|
|
261
264
|
try {
|
262
265
|
// Make sure we're not watching the symlink target
|
263
266
|
await this.removeSymlinkTarget(path);
|
264
|
-
|
265
|
-
|
267
|
+
let symbolicLink = false;
|
268
|
+
try {
|
269
|
+
const stat = await FS.lstat(path);
|
270
|
+
symbolicLink = stat.isSymbolicLink();
|
271
|
+
} catch (e) {}
|
272
|
+
|
273
|
+
if (symbolicLink) {
|
266
274
|
const realPath = `${await FS.realpath(path)}/kapeta.yml`;
|
267
275
|
if (await this.exists(realPath)) {
|
268
276
|
//console.log('Watching symlink target %s => %s', path, realPath);
|
@@ -1,29 +1,58 @@
|
|
1
1
|
import Path from 'path';
|
2
2
|
import { registry as Targets, BlockCodeGenerator, CodeWriter } from '@kapeta/codegen';
|
3
|
-
import ClusterConfiguration from '@kapeta/local-cluster-config';
|
4
3
|
import { BlockDefinition } from '@kapeta/schemas';
|
5
4
|
import { definitionsManager } from './definitionsManager';
|
5
|
+
import { Definition } from '@kapeta/local-cluster-config';
|
6
|
+
import { assetManager } from './assetManager';
|
7
|
+
import { normalizeKapetaUri } from './utils/utils';
|
8
|
+
import { repositoryManager } from './repositoryManager';
|
6
9
|
|
7
10
|
const TARGET_KIND = 'core/language-target';
|
8
11
|
const BLOCK_TYPE_KIND = 'core/block-type';
|
9
12
|
|
10
13
|
class CodeGeneratorManager {
|
14
|
+
private async ensureLanguageTargetInRegistry(path: string, version: string, definition: Definition) {
|
15
|
+
const key = `${definition.metadata.name}:${version}`;
|
16
|
+
|
17
|
+
try {
|
18
|
+
if (await Targets.get(key)) {
|
19
|
+
return;
|
20
|
+
}
|
21
|
+
} catch (e) {}
|
22
|
+
|
23
|
+
try {
|
24
|
+
const target = require(path);
|
25
|
+
if (target.default) {
|
26
|
+
Targets.register(key, target.default);
|
27
|
+
} else {
|
28
|
+
Targets.register(key, target);
|
29
|
+
}
|
30
|
+
} catch (e) {
|
31
|
+
console.error('Failed to load target: %s', key, e);
|
32
|
+
}
|
33
|
+
}
|
11
34
|
async reload() {
|
12
35
|
Targets.reset();
|
13
36
|
const languageTargets = await definitionsManager.getDefinitions(TARGET_KIND);
|
14
37
|
for (const languageTarget of languageTargets) {
|
15
|
-
|
38
|
+
await this.ensureLanguageTargetInRegistry(
|
39
|
+
languageTarget.path,
|
40
|
+
languageTarget.version,
|
41
|
+
languageTarget.definition
|
42
|
+
);
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
async initialize() {
|
47
|
+
await this.reload();
|
48
|
+
repositoryManager.on('change', async () => {
|
49
|
+
// Reload code generators when the repository changes
|
16
50
|
try {
|
17
|
-
|
18
|
-
if (target.default) {
|
19
|
-
Targets.register(key, target.default);
|
20
|
-
} else {
|
21
|
-
Targets.register(key, target);
|
22
|
-
}
|
51
|
+
await this.reload();
|
23
52
|
} catch (e) {
|
24
|
-
console.error('Failed to
|
53
|
+
console.error('Failed to reload code generators', e);
|
25
54
|
}
|
26
|
-
}
|
55
|
+
});
|
27
56
|
}
|
28
57
|
|
29
58
|
async canGenerateCode(yamlContent: BlockDefinition): Promise<boolean> {
|
@@ -40,6 +69,22 @@ class CodeGeneratorManager {
|
|
40
69
|
}
|
41
70
|
|
42
71
|
async generate(yamlFile: string, yamlContent: BlockDefinition) {
|
72
|
+
if (!yamlContent.spec.target?.kind) {
|
73
|
+
//Not all block types have targets
|
74
|
+
return;
|
75
|
+
}
|
76
|
+
|
77
|
+
const targetRef = normalizeKapetaUri(yamlContent.spec.target?.kind);
|
78
|
+
|
79
|
+
// Automatically downloads target if not available
|
80
|
+
const targetAsset = await assetManager.getAsset(targetRef);
|
81
|
+
|
82
|
+
if (!targetAsset) {
|
83
|
+
console.error('Language target not found: %s', yamlContent.spec.target?.kind);
|
84
|
+
return;
|
85
|
+
}
|
86
|
+
|
87
|
+
await this.ensureLanguageTargetInRegistry(targetAsset?.path, targetAsset?.version, targetAsset?.data);
|
43
88
|
const baseDir = Path.dirname(yamlFile);
|
44
89
|
console.log('Generating code for path: %s', baseDir);
|
45
90
|
const codeGenerator = new BlockCodeGenerator(yamlContent);
|
@@ -55,4 +100,3 @@ class CodeGeneratorManager {
|
|
55
100
|
}
|
56
101
|
|
57
102
|
export const codeGeneratorManager = new CodeGeneratorManager();
|
58
|
-
codeGeneratorManager.reload();
|
package/src/repositoryManager.ts
CHANGED
@@ -9,6 +9,7 @@ import { ProgressListener } from './progressListener';
|
|
9
9
|
import { RepositoryWatcher } from './RepositoryWatcher';
|
10
10
|
import { SourceOfChange } from './types';
|
11
11
|
import { cacheManager } from './cacheManager';
|
12
|
+
import { EventEmitter } from 'node:events';
|
12
13
|
|
13
14
|
const EVENT_DEFAULT_PROVIDERS_START = 'default-providers-start';
|
14
15
|
const EVENT_DEFAULT_PROVIDERS_END = 'default-providers-end';
|
@@ -28,14 +29,19 @@ const DEFAULT_PROVIDERS = [
|
|
28
29
|
'kapeta/language-target-java-spring-boot',
|
29
30
|
];
|
30
31
|
|
31
|
-
class RepositoryManager {
|
32
|
+
class RepositoryManager extends EventEmitter {
|
32
33
|
private _registryService: RegistryService;
|
33
34
|
private watcher: RepositoryWatcher;
|
34
35
|
|
35
36
|
constructor() {
|
37
|
+
super();
|
36
38
|
this._registryService = new RegistryService(Config.data.registry.url);
|
37
39
|
this.watcher = new RepositoryWatcher();
|
38
40
|
this.listenForChanges();
|
41
|
+
|
42
|
+
this.watcher.on('change', (file: string, source: SourceOfChange) => {
|
43
|
+
this.emit('change', file, source);
|
44
|
+
});
|
39
45
|
}
|
40
46
|
|
41
47
|
listenForChanges() {
|