Skip to content
Merged
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
63 changes: 63 additions & 0 deletions docs/databases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Created databases

The cli is creating some databases for the tools it manages.
Currently [`@seald-io/nedb`](https://github.com/seald/nedb) is used.
It's planned to eventually switch to [`node:sqlite`](https://nodejs.org/api/sqlite.html) when it becomes stable.

## List of created databases

- `state`: Stores information about all the current linked version of installed tools.
- `versions`: Stores information about installed tool versions.
- `links`: Stores information about linked tool versions.

## `state`

Stores information about all the current linked version of installed tools.

**Meta:**

- `name`: tool name or alias
- `tool`: the tool and version
- `name`: tool name
- `version`: tool version

**Index:**

- `name` (`unique`): only one can exist

## `versions`

Stores the installed tool versions with an optional parent.

**Meta:**

- `name`: tool name
- `version`: tool version
- `tool`: the optional parent tool and version this tool depends on
- `name`: tool name
- `version`: tool version

**Index:**

- `name`: search all installed versions
- `name` and `version`: is a version installed
- `tool.name` and `tool.version` (`sparse`): find links by current tool version

## `links`

Stores information about linked tool versions.
It stores which tool and version a shell wrapper was created from.

⚠️ `links` database is currently unused. ⚠️

**Meta:**

- `name`: file name
- `tool`: the tool the file is linked to
- `name`: tool name
- `version`: tool version

**Index:**

- `name` (`unique`): only one can exist
- `tool.name` and `tool.version`: find links by current tool version
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
},
"dependencies": {
"@renovatebot/pep440": "4.2.0",
"@seald-io/nedb": "4.1.2",
"@sindresorhus/is": "7.0.2",
"clipanion": "3.2.1",
"common-tags": "1.8.2",
Expand Down
56 changes: 56 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions src/cli/install-tool/base-install.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,24 @@ export abstract class BaseInstallService {
@inject(CompressionService)
protected readonly compress!: CompressionService;

/**
* Optional tool alias used to refer to this tool as parent.
*/
get alias(): string {
return this.name;
}

/**
* Tool name
*/
abstract readonly name: string;

/**
* A tool can depend on another tool to work.
* Eg. composer depends on php.
*/
readonly parent?: string;

abstract install(version: string): Promise<void>;

async isInstalled(version: string): Promise<boolean> {
Expand All @@ -62,6 +78,11 @@ export abstract class BaseInstallService {
return !NoPrepareTools.includes(this.name);
}

/**
* Post-installation steps
* @param _version Version that was installed
* @deprecated Link check is now smart enough to not need this
*/
postInstall(_version: string): Promise<void> {
return Promise.resolve();
}
Expand Down
23 changes: 19 additions & 4 deletions src/cli/install-tool/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { beforeAll, describe, expect, test, vi } from 'vitest';
import { VersionService } from '../services';
import { VersionService, createContainer } from '../services';
import { NpmVersionResolver } from '../tools/node/resolver';
import { NpmBaseInstallService } from '../tools/node/utils';
import { PipVersionResolver } from '../tools/python/pip';
Expand All @@ -23,6 +23,21 @@ describe('cli/install-tool/index', () => {
'tmp/containerbase/tool.init.d',
'opt/containerbase/data',
]);

const verSvc = await createContainer().getAsync(VersionService);

await verSvc.setCurrent({
name: 'node',
tool: { name: 'node', version: '1.0.0' },
});
await verSvc.setCurrent({
name: 'python',
tool: { name: 'python', version: '1.0.0' },
});
await verSvc.setCurrent({
name: 'ruby',
tool: { name: 'ruby', version: '1.0.0' },
});
});

describe('installTool', () => {
Expand All @@ -47,12 +62,12 @@ describe('cli/install-tool/index', () => {
])('works: $type', async ({ type, svc }) => {
vi.spyOn(svc.prototype, 'install').mockResolvedValue();
vi.spyOn(svc.prototype, 'needsInitialize').mockReturnValue(false);
vi.spyOn(svc.prototype, 'isInstalled').mockResolvedValue(false);
vi.spyOn(svc.prototype, 'validate').mockResolvedValue(true);
vi.spyOn(svc.prototype, 'postInstall').mockResolvedValue();
vi.spyOn(svc.prototype, 'test').mockRejectedValue(new Error('test'));
vi.spyOn(VersionService.prototype, 'find').mockResolvedValue(null);
expect(await installTool('dummy', '1.0.0', false, type)).toBeUndefined();
expect(
await installTool(`dummy-${type}`, '1.0.0', false, type),
).toBeUndefined();
});
});

Expand Down
Loading