@git.zone/tsdocker 1.2.43

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.
@@ -0,0 +1,6 @@
1
+ FROM hosttoday/ht-docker-node:npmci
2
+ RUN yarn global add @git.zone/tsdocker
3
+ COPY ./ /workspace
4
+ WORKDIR /workspace
5
+ ENV CI=true
6
+ CMD ["tsdocker","runinside"];
package/cli.js ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ process.env.CLI_CALL = 'true';
3
+ require('./dist/index');
package/npmextra.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "npmts": {
3
+ "mode": "default",
4
+ "cli": true
5
+ },
6
+ "npmci": {
7
+ "npmGlobalTools": [],
8
+ "npmAccessLevel": "public"
9
+ },
10
+ "gitzone": {
11
+ "projectType": "npm",
12
+ "module": {
13
+ "githost": "gitlab.com",
14
+ "gitscope": "gitzone",
15
+ "gitrepo": "tsdocker",
16
+ "description": "develop npm modules cross platform with docker",
17
+ "npmPackagename": "@git.zone/tsdocker",
18
+ "license": "MIT"
19
+ }
20
+ }
21
+ }
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@git.zone/tsdocker",
3
+ "version": "1.2.43",
4
+ "private": false,
5
+ "description": "develop npm modules cross platform with docker",
6
+ "main": "dist/index.js",
7
+ "typings": "dist/index.d.ts",
8
+ "bin": {
9
+ "tsdocker": "cli.js"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://gitlab.com/gitzone/tsdocker.git"
14
+ },
15
+ "keywords": [
16
+ "docker"
17
+ ],
18
+ "author": "Lossless GmbH",
19
+ "license": "MIT",
20
+ "bugs": {
21
+ "url": "https://gitlab.com/gitzone/tsdocker/issues"
22
+ },
23
+ "homepage": "https://gitlab.com/gitzone/tsdocker#readme",
24
+ "devDependencies": {
25
+ "@git.zone/tsbuild": "^3.1.0",
26
+ "@git.zone/tsrun": "^2.0.0",
27
+ "@git.zone/tstest": "^3.1.3",
28
+ "@types/node": "^22.10.2"
29
+ },
30
+ "dependencies": {
31
+ "@push.rocks/npmextra": "^5.3.3",
32
+ "@push.rocks/projectinfo": "^5.0.2",
33
+ "@push.rocks/qenv": "^6.1.3",
34
+ "@push.rocks/smartanalytics": "^2.0.15",
35
+ "@push.rocks/smartcli": "^4.0.19",
36
+ "@push.rocks/smartfs": "^1.1.0",
37
+ "@push.rocks/smartlog": "^3.1.10",
38
+ "@push.rocks/smartlog-destination-local": "^9.0.2",
39
+ "@push.rocks/smartlog-source-ora": "^1.0.9",
40
+ "@push.rocks/smartopen": "^2.0.0",
41
+ "@push.rocks/smartpromise": "^4.2.3",
42
+ "@push.rocks/smartshell": "^3.3.0",
43
+ "@push.rocks/smartstring": "^4.1.0"
44
+ },
45
+ "type": "module",
46
+ "files": [
47
+ "ts/**/*",
48
+ "ts_web/**/*",
49
+ "dist/**/*",
50
+ "dist_*/**/*",
51
+ "dist_ts/**/*",
52
+ "dist_ts_web/**/*",
53
+ "assets/**/*",
54
+ "cli.js",
55
+ "npmextra.json",
56
+ "readme.md"
57
+ ],
58
+ "scripts": {
59
+ "test": "(npm run clean && npm run setupCheck && npm run testStandard && npm run testSpeed)",
60
+ "build": "(tsbuild)",
61
+ "testStandard": "(cd test/ && node ../cli.ts.js)",
62
+ "testSpeed": "(cd test/ && node ../cli.ts.js speedtest)",
63
+ "testClean": "(cd test/ && node ../cli.ts.js clean --all)",
64
+ "testVscode": "(cd test/ && node ../cli.ts.js vscode)",
65
+ "clean": "(rm -rf test/)",
66
+ "compile": "(npmts --notest)",
67
+ "setupCheck": "(git clone https://gitlab.com/sandboxzone/sandbox-npmts.git test/)",
68
+ "buildDocs": "tsdoc"
69
+ }
70
+ }
@@ -0,0 +1,40 @@
1
+ # tsdocker Project Hints
2
+
3
+ ## Module Purpose
4
+
5
+ tsdocker is a tool for developing npm modules cross-platform using Docker. It allows testing in clean, reproducible Linux environments locally.
6
+
7
+ ## Recent Upgrades (2025-11-22)
8
+
9
+ - Updated all @git.zone/_ dependencies to @git.zone/_ scope (latest versions)
10
+ - Updated all @pushrocks/_ dependencies to @push.rocks/_ scope (latest versions)
11
+ - Migrated from smartfile v8 to smartfs v1.1.0
12
+ - All filesystem operations now use smartfs fluent API
13
+ - Operations are now async (smartfs is async-only)
14
+ - Updated dev dependencies:
15
+ - @git.zone/tsbuild: ^3.1.0
16
+ - @git.zone/tsrun: ^2.0.0
17
+ - @git.zone/tstest: ^3.1.3
18
+ - Removed @pushrocks/tapbundle (now use @git.zone/tstest/tapbundle)
19
+ - Updated @types/node to ^22.10.2
20
+ - Removed tslint and tslint-config-prettier (no longer needed)
21
+
22
+ ## SmartFS Migration Details
23
+
24
+ The following operations were converted:
25
+
26
+ - `smartfile.fs.fileExistsSync()` → Node.js `fs.existsSync()` (for sync needs)
27
+ - `smartfile.fs.ensureDirSync()` → Node.js `fs.mkdirSync(..., { recursive: true })`
28
+ - `smartfile.memory.toFsSync()` → `smartfs.file(path).write(content)` (async)
29
+ - `smartfile.fs.removeSync()` → `smartfs.file(path).delete()` (async)
30
+
31
+ ## Test Status
32
+
33
+ - Build: ✅ Passes
34
+ - The integration test requires cloning an external test repository (sandbox-npmts)
35
+ - The external test repo uses top-level await which requires ESM module handling
36
+ - This is not a tsdocker issue but rather the test repository's structure
37
+
38
+ ## Dependencies
39
+
40
+ All dependencies are now at their latest versions compatible with Node.js without introducing new Node.js-specific dependencies.
package/readme.md ADDED
@@ -0,0 +1,331 @@
1
+ # @git.zone/tsdocker
2
+
3
+ > 🐳 Cross-platform npm module development with Docker — test your packages in clean, reproducible Linux environments every time.
4
+
5
+ ## Issue Reporting and Security
6
+
7
+ For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
8
+
9
+ ## What is tsdocker?
10
+
11
+ **tsdocker** provides containerized testing environments for npm packages, ensuring your code works consistently across different systems. It's perfect for:
12
+
13
+ - 🧪 **Testing in clean environments** — Every test run starts fresh, just like CI
14
+ - 🔄 **Reproducing CI behavior locally** — No more "works on my machine" surprises
15
+ - 🐧 **Cross-platform development** — Develop on macOS/Windows, test on Linux
16
+ - 🚀 **Quick validation** — Spin up isolated containers for testing without polluting your system
17
+
18
+ ## Features
19
+
20
+ ✨ **Works Everywhere Docker Does**
21
+
22
+ - Docker Toolbox
23
+ - Native Docker Desktop
24
+ - Docker-in-Docker (DinD)
25
+ - Mounted docker.sock scenarios
26
+
27
+ 🔧 **Flexible Configuration**
28
+
29
+ - Custom base images
30
+ - Configurable test commands
31
+ - Environment variable injection via qenv
32
+ - Optional docker.sock mounting for nested container tests
33
+
34
+ 📦 **TypeScript-First**
35
+
36
+ - Full TypeScript support with excellent IntelliSense
37
+ - Type-safe configuration
38
+ - Modern async/await patterns throughout
39
+
40
+ ## Installation
41
+
42
+ ```bash
43
+ npm install --save-dev @git.zone/tsdocker
44
+ # or
45
+ pnpm install --save-dev @git.zone/tsdocker
46
+ ```
47
+
48
+ ## Quick Start
49
+
50
+ ### 1. Configure Your Project
51
+
52
+ Create an `npmextra.json` file in your project root:
53
+
54
+ ```json
55
+ {
56
+ "npmdocker": {
57
+ "baseImage": "hosttoday/ht-docker-node:npmts",
58
+ "command": "npmci test stable",
59
+ "dockerSock": false
60
+ }
61
+ }
62
+ ```
63
+
64
+ ### 2. Run Your Tests
65
+
66
+ ```bash
67
+ npx tsdocker
68
+ ```
69
+
70
+ That's it! tsdocker will:
71
+
72
+ 1. ✅ Verify Docker is available
73
+ 2. 🏗️ Build a test container with your specified base image
74
+ 3. 📂 Mount your project directory
75
+ 4. 🚀 Execute your test command
76
+ 5. 🧹 Clean up automatically
77
+
78
+ ## Configuration Options
79
+
80
+ | Option | Type | Description |
81
+ | ------------ | --------- | ---------------------------------------------------------------------- |
82
+ | `baseImage` | `string` | Docker image to use as the test environment base |
83
+ | `command` | `string` | CLI command to execute inside the container |
84
+ | `dockerSock` | `boolean` | Whether to mount `/var/run/docker.sock` for Docker-in-Docker scenarios |
85
+
86
+ ### Environment Variables
87
+
88
+ If you have a `qenv.yml` file in your project, tsdocker automatically loads and injects those environment variables into your test container.
89
+
90
+ Example `qenv.yml`:
91
+
92
+ ```yaml
93
+ demoKey: demoValue
94
+ API_KEY: your-key-here
95
+ ```
96
+
97
+ ## CLI Commands
98
+
99
+ ### Standard Test Run
100
+
101
+ ```bash
102
+ tsdocker
103
+ ```
104
+
105
+ Runs your configured test command in a fresh Docker container.
106
+
107
+ ### Clean Docker Environment
108
+
109
+ ```bash
110
+ tsdocker clean --all
111
+ ```
112
+
113
+ ⚠️ **WARNING**: This aggressively cleans your Docker environment by:
114
+
115
+ - Killing all running containers
116
+ - Removing all stopped containers
117
+ - Removing dangling images
118
+ - Removing all images
119
+ - Removing dangling volumes
120
+
121
+ Use with caution!
122
+
123
+ ### VSCode in Docker
124
+
125
+ ```bash
126
+ tsdocker vscode
127
+ ```
128
+
129
+ Launches a containerized VS Code instance accessible via browser at `testing-vscode.git.zone:8443`.
130
+
131
+ ### Speed Test
132
+
133
+ ```bash
134
+ tsdocker speedtest
135
+ ```
136
+
137
+ Runs a network speed test inside a Docker container.
138
+
139
+ ## Advanced Usage
140
+
141
+ ### Docker-in-Docker Testing
142
+
143
+ If you need to run Docker commands inside your test container (e.g., testing Docker-related tools):
144
+
145
+ ```json
146
+ {
147
+ "npmdocker": {
148
+ "baseImage": "docker:latest",
149
+ "command": "docker run hello-world",
150
+ "dockerSock": true
151
+ }
152
+ }
153
+ ```
154
+
155
+ Setting `"dockerSock": true` mounts the host's Docker socket into the container.
156
+
157
+ ### Custom Base Images
158
+
159
+ You can use any Docker image as your base:
160
+
161
+ ```json
162
+ {
163
+ "npmdocker": {
164
+ "baseImage": "node:20-alpine",
165
+ "command": "npm test"
166
+ }
167
+ }
168
+ ```
169
+
170
+ Popular choices:
171
+
172
+ - `node:20` — Official Node.js images
173
+ - `node:20-alpine` — Lightweight Alpine-based images
174
+ - `hosttoday/ht-docker-node:npmts` — Pre-configured with npmts tooling
175
+
176
+ ### CI Integration
177
+
178
+ tsdocker automatically detects CI environments (via `CI=true` env var) and adjusts behavior:
179
+
180
+ - Skips mounting project directory in CI (assumes code is already in container)
181
+ - Optimizes for CI execution patterns
182
+
183
+ ## Why tsdocker?
184
+
185
+ ### The Problem
186
+
187
+ Local development environments drift over time. You might have:
188
+
189
+ - Stale global packages
190
+ - Modified system configurations
191
+ - Cached dependencies
192
+ - Different Node.js versions
193
+
194
+ Your tests pass locally but fail in CI — or vice versa.
195
+
196
+ ### The Solution
197
+
198
+ tsdocker ensures every test run happens in a **clean, reproducible environment**, just like your CI pipeline. This means:
199
+
200
+ ✅ Consistent behavior between local and CI
201
+ ✅ No dependency pollution between test runs
202
+ ✅ Easy cross-platform testing
203
+ ✅ Reproducible bug investigations
204
+
205
+ ## TypeScript Usage
206
+
207
+ tsdocker is built with TypeScript and provides full type definitions:
208
+
209
+ ```typescript
210
+ import { IConfig } from '@git.zone/tsdocker/dist/tsdocker.config';
211
+
212
+ const config: IConfig = {
213
+ baseImage: 'node:20',
214
+ command: 'npm test',
215
+ dockerSock: false,
216
+ keyValueObject: {
217
+ NODE_ENV: 'test',
218
+ },
219
+ };
220
+ ```
221
+
222
+ ## Requirements
223
+
224
+ - **Docker**: Docker must be installed and accessible via CLI
225
+ - **Node.js**: Version 14 or higher recommended
226
+
227
+ ## How It Works
228
+
229
+ Under the hood, tsdocker:
230
+
231
+ 1. 📋 Reads your `npmextra.json` configuration
232
+ 2. 🔍 Optionally loads environment variables from `qenv.yml`
233
+ 3. 🐳 Generates a temporary Dockerfile
234
+ 4. 🏗️ Builds a Docker image with your base image
235
+ 5. 📦 Mounts your project directory (unless in CI)
236
+ 6. ▶️ Runs your test command inside the container
237
+ 7. 📊 Captures the exit code
238
+ 8. 🧹 Cleans up containers and images
239
+ 9. ✅ Exits with the same code as your tests
240
+
241
+ ## Troubleshooting
242
+
243
+ ### "docker not found on this machine"
244
+
245
+ Make sure Docker is installed and the `docker` command is in your PATH:
246
+
247
+ ```bash
248
+ docker --version
249
+ ```
250
+
251
+ ### Tests fail in container but work locally
252
+
253
+ This often indicates environment-specific issues. Check:
254
+
255
+ - Are all dependencies in `package.json`? (not relying on global packages)
256
+ - Does your code have hardcoded paths?
257
+ - Are environment variables set correctly?
258
+
259
+ ### Permission errors with docker.sock
260
+
261
+ If using `dockerSock: true`, ensure your user has permissions to access `/var/run/docker.sock`:
262
+
263
+ ```bash
264
+ sudo usermod -aG docker $USER
265
+ # Then log out and back in
266
+ ```
267
+
268
+ ## Examples
269
+
270
+ ### Basic npm test
271
+
272
+ ```json
273
+ {
274
+ "npmdocker": {
275
+ "baseImage": "node:20",
276
+ "command": "npm test"
277
+ }
278
+ }
279
+ ```
280
+
281
+ ### Using npmci for multiple Node versions
282
+
283
+ ```json
284
+ {
285
+ "npmdocker": {
286
+ "baseImage": "hosttoday/ht-docker-node:npmts",
287
+ "command": "npmci test stable"
288
+ }
289
+ }
290
+ ```
291
+
292
+ ### Testing Docker-based tools
293
+
294
+ ```json
295
+ {
296
+ "npmdocker": {
297
+ "baseImage": "docker:latest",
298
+ "command": "sh -c 'docker version && docker ps'",
299
+ "dockerSock": true
300
+ }
301
+ }
302
+ ```
303
+
304
+ ## Performance Tips
305
+
306
+ 🚀 **Use specific base images**: `node:20-alpine` is much faster to pull than `node:latest`
307
+ 🚀 **Layer caching**: Docker caches image layers — your base image only downloads once
308
+ 🚀 **Prune regularly**: Run `docker system prune` periodically to reclaim disk space
309
+
310
+ ## Migration from legacy npmdocker scope
311
+
312
+ This package was previously published under the `npmdocker` name in the old scope. It is now available as `@git.zone/tsdocker` for better naming consistency. Functionality remains the same.
313
+
314
+ ## License and Legal Information
315
+
316
+ This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
317
+
318
+ **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
319
+
320
+ ### Trademarks
321
+
322
+ This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
323
+
324
+ ### Company Information
325
+
326
+ Task Venture Capital GmbH
327
+ Registered at District court Bremen HRB 35230 HB, Germany
328
+
329
+ For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
330
+
331
+ By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
@@ -0,0 +1,8 @@
1
+ /**
2
+ * autocreated commitinfo by @push.rocks/commitinfo
3
+ */
4
+ export const commitinfo = {
5
+ name: '@git.zone/tsdocker',
6
+ version: '1.2.43',
7
+ description: 'develop npm modules cross platform with docker'
8
+ }
package/ts/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ import * as plugins from './tsdocker.plugins';
2
+ import * as cli from './tsdocker.cli';
3
+
4
+ cli.run();
@@ -0,0 +1,90 @@
1
+ import * as plugins from './tsdocker.plugins';
2
+ import * as paths from './tsdocker.paths';
3
+
4
+ // modules
5
+ import * as ConfigModule from './tsdocker.config';
6
+ import * as DockerModule from './tsdocker.docker';
7
+
8
+ import { logger, ora } from './tsdocker.logging';
9
+
10
+ const tsdockerCli = new plugins.smartcli.Smartcli();
11
+
12
+ export let run = () => {
13
+ tsdockerCli.standardTask().subscribe(async argvArg => {
14
+ const configArg = await ConfigModule.run().then(DockerModule.run);
15
+ if (configArg.exitCode === 0) {
16
+ logger.log('success', 'container ended all right!');
17
+ } else {
18
+ logger.log('error', `container ended with error! Exit Code is ${configArg.exitCode}`);
19
+ process.exit(1);
20
+ }
21
+ });
22
+
23
+ /**
24
+ * this command is executed inside docker and meant for use from outside docker
25
+ */
26
+ tsdockerCli.addCommand('runinside').subscribe(async argvArg => {
27
+ logger.log('ok', 'Allright. We are now in Docker!');
28
+ ora.text('now trying to run your specified command');
29
+ const configArg = await ConfigModule.run();
30
+ const smartshellInstance = new plugins.smartshell.Smartshell({
31
+ executor: 'bash'
32
+ });
33
+ ora.stop();
34
+ await smartshellInstance.exec(configArg.command).then(response => {
35
+ if (response.exitCode !== 0) {
36
+ process.exit(1);
37
+ }
38
+ });
39
+ });
40
+
41
+ tsdockerCli.addCommand('clean').subscribe(async argvArg => {
42
+ ora.text('cleaning up docker env...');
43
+ if (argvArg.all) {
44
+ const smartshellInstance = new plugins.smartshell.Smartshell({
45
+ executor: 'bash'
46
+ });
47
+ ora.text('killing any running docker containers...');
48
+ await smartshellInstance.exec(`docker kill $(docker ps -q)`);
49
+
50
+ ora.text('removing stopped containers...');
51
+ await smartshellInstance.exec(`docker rm $(docker ps -a -q)`);
52
+
53
+ ora.text('removing images...');
54
+ await smartshellInstance.exec(`docker rmi -f $(docker images -q -f dangling=true)`);
55
+
56
+ ora.text('removing all other images...');
57
+ await smartshellInstance.exec(`docker rmi $(docker images -a -q)`);
58
+
59
+ ora.text('removing all volumes...');
60
+ await smartshellInstance.exec(`docker volume rm $(docker volume ls -f dangling=true -q)`);
61
+ }
62
+ ora.finishSuccess('docker environment now is clean!');
63
+ });
64
+
65
+ tsdockerCli.addCommand('speedtest').subscribe(async argvArg => {
66
+ const smartshellInstance = new plugins.smartshell.Smartshell({
67
+ executor: 'bash'
68
+ });
69
+ logger.log('ok', 'Starting speedtest');
70
+ await smartshellInstance.exec(
71
+ `docker pull tianon/speedtest && docker run --rm tianon/speedtest --accept-license --accept-gdpr`
72
+ );
73
+ });
74
+
75
+ tsdockerCli.addCommand('vscode').subscribe(async argvArg => {
76
+ const smartshellInstance = new plugins.smartshell.Smartshell({
77
+ executor: 'bash'
78
+ });
79
+ logger.log('ok', `Starting vscode in cwd ${paths.cwd}`);
80
+ await smartshellInstance.execAndWaitForLine(
81
+ `docker run -p 127.0.0.1:8443:8443 -v "${
82
+ paths.cwd
83
+ }:/home/coder/project" registry.gitlab.com/hosttoday/ht-docker-vscode --allow-http --no-auth`,
84
+ /Connected to shared process/
85
+ );
86
+ await plugins.smartopen.openUrl('testing-vscode.git.zone:8443');
87
+ });
88
+
89
+ tsdockerCli.startParse();
90
+ };
@@ -0,0 +1,38 @@
1
+ import * as plugins from './tsdocker.plugins';
2
+ import * as paths from './tsdocker.paths';
3
+ import * as fs from 'fs';
4
+
5
+ export interface IConfig {
6
+ baseImage: string;
7
+ command: string;
8
+ dockerSock: boolean;
9
+ exitCode?: number;
10
+ keyValueObject: {[key: string]: any};
11
+ }
12
+
13
+ const getQenvKeyValueObject = async () => {
14
+ let qenvKeyValueObjectArray: { [key: string]: string | number };
15
+ if (fs.existsSync(plugins.path.join(paths.cwd, 'qenv.yml'))) {
16
+ qenvKeyValueObjectArray = new plugins.qenv.Qenv(paths.cwd, '.nogit/').keyValueObject;
17
+ } else {
18
+ qenvKeyValueObjectArray = {};
19
+ }
20
+ return qenvKeyValueObjectArray;
21
+ };
22
+
23
+ const buildConfig = async (qenvKeyValueObjectArg: { [key: string]: string | number }) => {
24
+ const npmextra = new plugins.npmextra.Npmextra(paths.cwd);
25
+ const config = npmextra.dataFor<IConfig>('npmdocker', {
26
+ baseImage: 'hosttoday/ht-docker-node:npmdocker',
27
+ init: 'rm -rf node_nodules/ && yarn install',
28
+ command: 'npmci npm test',
29
+ dockerSock: false,
30
+ keyValueObject: qenvKeyValueObjectArg
31
+ });
32
+ return config;
33
+ };
34
+
35
+ export let run = async (): Promise<IConfig> => {
36
+ const config = await getQenvKeyValueObject().then(buildConfig);
37
+ return config;
38
+ };
@@ -0,0 +1,169 @@
1
+ import * as plugins from './tsdocker.plugins';
2
+ import * as paths from './tsdocker.paths';
3
+ import * as snippets from './tsdocker.snippets';
4
+
5
+ import { logger, ora } from './tsdocker.logging';
6
+
7
+ const smartshellInstance = new plugins.smartshell.Smartshell({
8
+ executor: 'bash'
9
+ });
10
+
11
+ // interfaces
12
+ import { IConfig } from './tsdocker.config';
13
+
14
+ let config: IConfig;
15
+
16
+ /**
17
+ * the docker data used to build the internal testing container
18
+ */
19
+ const dockerData = {
20
+ imageTag: 'npmdocker-temp-image:latest',
21
+ containerName: 'npmdocker-temp-container',
22
+ dockerProjectMountString: '',
23
+ dockerSockString: '',
24
+ dockerEnvString: ''
25
+ };
26
+
27
+ /**
28
+ * check if docker is available
29
+ */
30
+ const checkDocker = () => {
31
+ const done = plugins.smartpromise.defer();
32
+ ora.text('checking docker...');
33
+
34
+ if (smartshellInstance.exec('which docker')) {
35
+ logger.log('ok', 'Docker found!');
36
+ done.resolve();
37
+ } else {
38
+ done.reject(new Error('docker not found on this machine'));
39
+ }
40
+ return done.promise;
41
+ };
42
+
43
+ /**
44
+ * builds the Dockerfile according to the config in the project
45
+ */
46
+ const buildDockerFile = async () => {
47
+ const done = plugins.smartpromise.defer();
48
+ ora.text('building Dockerfile...');
49
+ const dockerfile: string = snippets.dockerfileSnippet({
50
+ baseImage: config.baseImage,
51
+ command: config.command
52
+ });
53
+ logger.log('info', `Base image is: ${config.baseImage}`);
54
+ logger.log('info', `Command is: ${config.command}`);
55
+ await plugins.smartfs.file(plugins.path.join(paths.cwd, 'npmdocker')).write(dockerfile);
56
+ logger.log('ok', 'Dockerfile created!');
57
+ ora.stop();
58
+ done.resolve();
59
+ return done.promise;
60
+ };
61
+
62
+ /**
63
+ * builds the Dockerimage from the built Dockerfile
64
+ */
65
+ const buildDockerImage = async () => {
66
+ logger.log('info', 'pulling latest base image from registry...');
67
+ await smartshellInstance.exec(`docker pull ${config.baseImage}`);
68
+ ora.text('building Dockerimage...');
69
+ const execResult = await smartshellInstance.execSilent(
70
+ `docker build -f npmdocker -t ${dockerData.imageTag} ${paths.cwd}`
71
+ );
72
+ if (execResult.exitCode !== 0) {
73
+ console.log(execResult.stdout);
74
+ process.exit(1);
75
+ }
76
+ logger.log('ok', 'Dockerimage built!');
77
+ };
78
+
79
+ const buildDockerProjectMountString = async () => {
80
+ if (process.env.CI !== 'true') {
81
+ dockerData.dockerProjectMountString = `-v ${paths.cwd}:/workspace`;
82
+ }
83
+ };
84
+
85
+ /**
86
+ * builds an environment string that docker cli understands
87
+ */
88
+ const buildDockerEnvString = async () => {
89
+ for (const key of Object.keys(config.keyValueObject)) {
90
+ const envString = (dockerData.dockerEnvString =
91
+ dockerData.dockerEnvString + `-e ${key}=${config.keyValueObject[key]} `);
92
+ }
93
+ };
94
+
95
+ /**
96
+ * creates string to mount the docker.sock inside the testcontainer
97
+ */
98
+ const buildDockerSockString = async () => {
99
+ if (config.dockerSock) {
100
+ dockerData.dockerSockString = `-v /var/run/docker.sock:/var/run/docker.sock`;
101
+ }
102
+ };
103
+
104
+ /**
105
+ * creates a container by running the built Dockerimage
106
+ */
107
+ const runDockerImage = async () => {
108
+ const done = plugins.smartpromise.defer();
109
+ ora.text('starting Container...');
110
+ ora.stop();
111
+ logger.log('info', 'now running Dockerimage');
112
+ config.exitCode = (await smartshellInstance.exec(
113
+ `docker run ${dockerData.dockerProjectMountString} ${dockerData.dockerSockString} ${
114
+ dockerData.dockerEnvString
115
+ } --name ${dockerData.containerName} ${dockerData.imageTag}`
116
+ )).exitCode;
117
+ };
118
+
119
+ /**
120
+ * cleans up: deletes the test container
121
+ */
122
+ const deleteDockerContainer = async () => {
123
+ await smartshellInstance.execSilent(`docker rm -f ${dockerData.containerName}`);
124
+ };
125
+
126
+ /**
127
+ * cleans up deletes the test image
128
+ */
129
+ const deleteDockerImage = async () => {
130
+ await smartshellInstance.execSilent(`docker rmi ${dockerData.imageTag}`).then(async response => {
131
+ if (response.exitCode !== 0) {
132
+ console.log(response.stdout);
133
+ }
134
+ });
135
+ };
136
+
137
+ const preClean = async () => {
138
+ await deleteDockerImage()
139
+ .then(deleteDockerContainer)
140
+ .then(async () => {
141
+ logger.log('ok', 'ensured clean Docker environment!');
142
+ });
143
+ };
144
+
145
+ const postClean = async () => {
146
+ await deleteDockerContainer()
147
+ .then(deleteDockerImage)
148
+ .then(async () => {
149
+ logger.log('ok', 'cleaned up!');
150
+ });
151
+ await plugins.smartfs.file(paths.npmdockerFile).delete();
152
+ };
153
+
154
+ export let run = async (configArg: IConfig): Promise<IConfig> => {
155
+ config = configArg;
156
+ const resultConfig = await checkDocker()
157
+ .then(preClean)
158
+ .then(buildDockerFile)
159
+ .then(buildDockerImage)
160
+ .then(buildDockerProjectMountString)
161
+ .then(buildDockerEnvString)
162
+ .then(buildDockerSockString)
163
+ .then(runDockerImage)
164
+ .then(postClean)
165
+ .catch(err => {
166
+ console.log(err);
167
+ });
168
+ return config;
169
+ };
@@ -0,0 +1,17 @@
1
+ import * as plugins from './tsdocker.plugins';
2
+
3
+ export const logger = new plugins.smartlog.Smartlog({
4
+ logContext: {
5
+ company: 'Some Company',
6
+ companyunit: 'Some CompanyUnit',
7
+ containerName: 'Some Containername',
8
+ environment: 'local',
9
+ runtime: 'node',
10
+ zone: 'gitzone'
11
+ },
12
+ minimumLogLevel: 'silly'
13
+ });
14
+
15
+ logger.addLogDestination(new plugins.smartlogDestinationLocal.DestinationLocal());
16
+
17
+ export const ora = new plugins.smartlogSouceOra.SmartlogSourceOra();
@@ -0,0 +1,9 @@
1
+ import * as plugins from './tsdocker.plugins';
2
+ import * as fs from 'fs';
3
+
4
+ // directories
5
+ export let cwd = process.cwd();
6
+ export let packageBase = plugins.path.join(__dirname, '../');
7
+ export let assets = plugins.path.join(packageBase, 'assets/');
8
+ fs.mkdirSync(assets, { recursive: true });
9
+ export let npmdockerFile = plugins.path.join(cwd, 'npmdocker');
@@ -0,0 +1,32 @@
1
+ // push.rocks scope
2
+ import * as npmextra from '@push.rocks/npmextra';
3
+ import * as path from 'path';
4
+ import * as projectinfo from '@push.rocks/projectinfo';
5
+ import * as smartpromise from '@push.rocks/smartpromise';
6
+ import * as qenv from '@push.rocks/qenv';
7
+ import * as smartcli from '@push.rocks/smartcli';
8
+ import { SmartFs, SmartFsProviderNode } from '@push.rocks/smartfs';
9
+ import * as smartlog from '@push.rocks/smartlog';
10
+ import * as smartlogDestinationLocal from '@push.rocks/smartlog-destination-local';
11
+ import * as smartlogSouceOra from '@push.rocks/smartlog-source-ora';
12
+ import * as smartopen from '@push.rocks/smartopen';
13
+ import * as smartshell from '@push.rocks/smartshell';
14
+ import * as smartstring from '@push.rocks/smartstring';
15
+
16
+ // Create smartfs instance
17
+ export const smartfs = new SmartFs(new SmartFsProviderNode());
18
+
19
+ export {
20
+ npmextra,
21
+ path,
22
+ projectinfo,
23
+ smartpromise,
24
+ qenv,
25
+ smartcli,
26
+ smartlog,
27
+ smartlogDestinationLocal,
28
+ smartlogSouceOra,
29
+ smartopen,
30
+ smartshell,
31
+ smartstring
32
+ };
@@ -0,0 +1,37 @@
1
+ import * as plugins from './tsdocker.plugins';
2
+
3
+ export interface IDockerfileSnippet {
4
+ baseImage: string;
5
+ command: string;
6
+ }
7
+
8
+ let getMountSolutionString = (optionsArg: IDockerfileSnippet) => {
9
+ if (process.env.CI) {
10
+ return 'COPY ./ /workspace';
11
+ } else {
12
+ return '# not copying workspcae since not in CI';
13
+ }
14
+ };
15
+
16
+ let getGlobalPreparationString = (optionsArg: IDockerfileSnippet) => {
17
+ if (optionsArg.baseImage !== 'hosttoday/ht-docker-node:npmdocker') {
18
+ return 'RUN npm install -g npmdocker';
19
+ } else {
20
+ return '# not installing npmdocker since it is included in the base image';
21
+ }
22
+ };
23
+
24
+ export let dockerfileSnippet = (optionsArg: IDockerfileSnippet): string => {
25
+ return plugins.smartstring.indent.normalize(
26
+ `
27
+ FROM ${optionsArg.baseImage}
28
+ # For info about what npmdocker does read the docs at https://gitzone.github.io/npmdocker
29
+ ${getGlobalPreparationString(optionsArg)}
30
+ ${getMountSolutionString(optionsArg)}
31
+ WORKDIR /workspace
32
+ ENV CI=true
33
+ ENTRYPOINT ["npmdocker"]
34
+ CMD ["runinside"]
35
+ `
36
+ );
37
+ };