Compare commits
	
		
			16 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 572738e88f | |||
| 129ae93044 | |||
| e910892231 | |||
| 6d9cabf7ee | |||
| 7c7787e811 | |||
| bde26cc312 | |||
| 29e81f3ae7 | |||
| 6337b20d62 | |||
| 6dd537fe43 | |||
| 7191b172a4 | |||
| 9a4611b70f | |||
| 189dbc3654 | |||
| fc95fc96ed | |||
| 467eed57d7 | |||
| a5ca5444a0 | |||
| 17610cb834 | 
| @@ -38,17 +38,17 @@ snyk: | ||||
| # test stage | ||||
| # ==================== | ||||
|  | ||||
| testLTS: | ||||
| testStable: | ||||
|   stage: test | ||||
|   script: | ||||
|   - npmci npm prepare | ||||
|   - npmci node install lts | ||||
|   - npmci node install stable | ||||
|   - npmci npm install | ||||
|   - npmci npm test | ||||
|   coverage: /\d+.?\d+?\%\s*coverage/ | ||||
|   tags: | ||||
|   - docker | ||||
|   - notpriv | ||||
|   - priv | ||||
|  | ||||
| testBuild: | ||||
|   stage: test | ||||
| @@ -98,7 +98,9 @@ trigger: | ||||
|   - notpriv | ||||
|  | ||||
| pages: | ||||
|   image: hosttoday/ht-docker-node:npmci | ||||
|   image: hosttoday/ht-docker-dbase:npmci | ||||
|   services: | ||||
|    - docker:stable-dind | ||||
|   stage: metadata | ||||
|   script: | ||||
|     - npmci command npm install -g @gitzone/tsdoc | ||||
|   | ||||
| @@ -1,9 +1,4 @@ | ||||
| { | ||||
|   "npmts": { | ||||
|     "mode": "default", | ||||
|     "coverageTreshold": "70", | ||||
|     "cli": true | ||||
|   }, | ||||
|   "npmci": { | ||||
|     "npmGlobalTools": [], | ||||
|     "npmAccessLevel": "public", | ||||
|   | ||||
							
								
								
									
										236
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										236
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,9 +1,37 @@ | ||||
| { | ||||
|   "name": "@shipzone/npmci", | ||||
|   "version": "3.1.38", | ||||
|   "version": "3.1.46", | ||||
|   "lockfileVersion": 1, | ||||
|   "requires": true, | ||||
|   "dependencies": { | ||||
|     "@apiglobal/typedrequest": { | ||||
|       "version": "1.0.17", | ||||
|       "resolved": "https://verdaccio.lossless.one/@apiglobal%2ftypedrequest/-/typedrequest-1.0.17.tgz", | ||||
|       "integrity": "sha512-p19ZOROh7+dsA00N3QFHCuyeUWarxpSVZxVJBI59LPnh6JlGE3ixQYpAEi+HJbsGfIEhuOBIJ6upN+0lnjH+fg==", | ||||
|       "requires": { | ||||
|         "@apiglobal/typedrequest-interfaces": "^1.0.7", | ||||
|         "@pushrocks/lik": "^3.0.11", | ||||
|         "@pushrocks/smartjson": "^3.0.8", | ||||
|         "@pushrocks/smartrequest": "^1.1.23" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "@pushrocks/smartjson": { | ||||
|           "version": "3.0.8", | ||||
|           "resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartjson/-/smartjson-3.0.8.tgz", | ||||
|           "integrity": "sha512-EjC3611RSZaZmK+nXxXrYDBxdxYWtrxjOrZtQzbYn0yM33KSCH0sLIAG8B2wYZVAOj4A2pC8mVxFSJ1w3iRFHg==", | ||||
|           "requires": { | ||||
|             "@types/fast-json-stable-stringify": "^2.0.0", | ||||
|             "fast-json-stable-stringify": "^2.0.0", | ||||
|             "lodash.clonedeep": "^4.5.0" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "@apiglobal/typedrequest-interfaces": { | ||||
|       "version": "1.0.7", | ||||
|       "resolved": "https://verdaccio.lossless.one/@apiglobal%2ftypedrequest-interfaces/-/typedrequest-interfaces-1.0.7.tgz", | ||||
|       "integrity": "sha512-yPl0UcLFMwSQL7bK52wVjkgvadC+x2YS3+7T15V1A1dXNxa96yd4WX1fqcKqwnBrvYexq/8FaxWGi98tZ0oNwg==" | ||||
|     }, | ||||
|     "@babel/code-frame": { | ||||
|       "version": "7.5.5", | ||||
|       "resolved": "https://verdaccio.lossless.one/@babel%2fcode-frame/-/code-frame-7.5.5.tgz", | ||||
| @@ -25,9 +53,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "@gitzone/tsbuild": { | ||||
|       "version": "2.1.11", | ||||
|       "resolved": "https://verdaccio.lossless.one/@gitzone%2ftsbuild/-/tsbuild-2.1.11.tgz", | ||||
|       "integrity": "sha512-Sa90/S7rkfFaTa2yeASHVAWIl3hNh9DBqVcQbOCaNhqKUGdD+NzPw1MESuMOXqKG7oM5i4Cu6qfcJB0fmAjS8g==", | ||||
|       "version": "2.1.17", | ||||
|       "resolved": "https://registry.npmjs.org/@gitzone/tsbuild/-/tsbuild-2.1.17.tgz", | ||||
|       "integrity": "sha512-Mg2cu7cW3cC6L2tzatB8t6OMVgTGatobb8UkN+y3n7KAWRld4gXcVWmaehch/wSFrbmk6Oe8rPjdWPjhTSIF1Q==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@pushrocks/smartcli": "^3.0.7", | ||||
| @@ -35,7 +63,7 @@ | ||||
|         "@pushrocks/smartlog": "^2.0.19", | ||||
|         "@pushrocks/smartpath": "^4.0.1", | ||||
|         "@pushrocks/smartpromise": "^3.0.2", | ||||
|         "typescript": "^3.4.5" | ||||
|         "typescript": "^3.5.2" | ||||
|       } | ||||
|     }, | ||||
|     "@gitzone/tsrun": { | ||||
| @@ -92,9 +120,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "@pushrocks/lik": { | ||||
|       "version": "3.0.10", | ||||
|       "resolved": "https://verdaccio.lossless.one/@pushrocks%2flik/-/lik-3.0.10.tgz", | ||||
|       "integrity": "sha512-iWG06QsrL6AAnjPRWMVz4bRaRE0jJt/HgEK0YeLqaSBLY8ju4ps1j4lEN8VrUlXGZyPB6UGQfcreesO24buYhQ==", | ||||
|       "version": "3.0.11", | ||||
|       "resolved": "https://registry.npmjs.org/@pushrocks/lik/-/lik-3.0.11.tgz", | ||||
|       "integrity": "sha512-SDKRPj9+xBTqozlDPcA7O6BcccM1Tw/sXPVP+OnhNxCubDZ/L2kGNpPpqm43NJUoNxSSo5wdBw4N7MAFYCGdVg==", | ||||
|       "requires": { | ||||
|         "@pushrocks/smartdelay": "^2.0.3", | ||||
|         "@pushrocks/smartpromise": "^3.0.2", | ||||
| @@ -151,6 +179,15 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "@pushrocks/qenv": { | ||||
|       "version": "4.0.4", | ||||
|       "resolved": "https://verdaccio.lossless.one/@pushrocks%2fqenv/-/qenv-4.0.4.tgz", | ||||
|       "integrity": "sha512-nvgiY3u25mvi5wmVbEYfCDuBaz6pogwzKPxGaohMrIcNn/0MlXZ+JvkVHWK6CxExklSDbjSXsD7zfvme4GGA0g==", | ||||
|       "requires": { | ||||
|         "@pushrocks/smartfile": "^7.0.4", | ||||
|         "@pushrocks/smartlog": "^2.0.19" | ||||
|       } | ||||
|     }, | ||||
|     "@pushrocks/smartanalytics": { | ||||
|       "version": "2.0.15", | ||||
|       "resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartanalytics/-/smartanalytics-2.0.15.tgz", | ||||
| @@ -261,18 +298,18 @@ | ||||
|       } | ||||
|     }, | ||||
|     "@pushrocks/smartgit": { | ||||
|       "version": "1.0.11", | ||||
|       "resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartgit/-/smartgit-1.0.11.tgz", | ||||
|       "integrity": "sha512-h9F2zsHu2OdS8D905/amW3XnFqoRS7HTDfmPOrvgQ5SDb27zwBTlypJ8musSmJKBYti8vXuNzmMOZHZg+in2qQ==", | ||||
|       "version": "1.0.13", | ||||
|       "resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartgit/-/smartgit-1.0.13.tgz", | ||||
|       "integrity": "sha512-NHI9Umo5bzUVsrSb9RZSA+t9LFsXzeoFmTjIK/LtUd/4oyvbArPRs97tYe1ueufViW1HZh0vXZKigrHxlWvypA==", | ||||
|       "requires": { | ||||
|         "@pushrocks/smartfile": "^7.0.2", | ||||
|         "@pushrocks/smartfile": "^7.0.4", | ||||
|         "@pushrocks/smartpath": "^4.0.1", | ||||
|         "@pushrocks/smartpromise": "^3.0.2", | ||||
|         "@pushrocks/smartshell": "^2.0.23", | ||||
|         "@pushrocks/smartstring": "^3.0.10", | ||||
|         "@types/minimatch": "^3.0.3", | ||||
|         "@types/nodegit": "^0.24.8", | ||||
|         "nodegit": "^0.24.3" | ||||
|         "@types/nodegit": "^0.24.10", | ||||
|         "nodegit": "^0.25.1" | ||||
|       } | ||||
|     }, | ||||
|     "@pushrocks/smarthash": { | ||||
| @@ -396,9 +433,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "@pushrocks/smartshell": { | ||||
|       "version": "2.0.23", | ||||
|       "resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartshell/-/smartshell-2.0.23.tgz", | ||||
|       "integrity": "sha512-+YXacX/sp4f+iBYm4vAoxrq/c8WCHnFhMaW66l3R08stl0eezW3SytoSlnr6R+JT1xqnBzIItDfCyyRC3uEVnw==", | ||||
|       "version": "2.0.25", | ||||
|       "resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartshell/-/smartshell-2.0.25.tgz", | ||||
|       "integrity": "sha512-sYVHOhBRdr+CkjS+o1SDtB5058ZYxTPAYuexx2ydl2g+57KNdEcSRWN/2mOv5+NFH+tvvgtnUjC3AclC9CwJ4A==", | ||||
|       "requires": { | ||||
|         "@pushrocks/smartdelay": "^2.0.3", | ||||
|         "@pushrocks/smartexit": "^1.0.15", | ||||
| @@ -519,6 +556,11 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "@servezone/servezone-interfaces": { | ||||
|       "version": "2.0.29", | ||||
|       "resolved": "https://verdaccio.lossless.one/@servezone%2fservezone-interfaces/-/servezone-interfaces-2.0.29.tgz", | ||||
|       "integrity": "sha512-alXB2SFD+3tVxfC0Kd8NrHlr4WyB1hSg60ydHUvzJB30fUMKMX71UlWrITxORg8UXQQy1Kw9rhFhCXnq31xxSA==" | ||||
|     }, | ||||
|     "@types/body-parser": { | ||||
|       "version": "1.17.1", | ||||
|       "resolved": "https://verdaccio.lossless.one/@types%2fbody-parser/-/body-parser-1.17.1.tgz", | ||||
| @@ -665,14 +707,14 @@ | ||||
|       "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" | ||||
|     }, | ||||
|     "@types/node": { | ||||
|       "version": "12.7.2", | ||||
|       "resolved": "https://verdaccio.lossless.one/@types%2fnode/-/node-12.7.2.tgz", | ||||
|       "integrity": "sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg==" | ||||
|       "version": "12.7.3", | ||||
|       "resolved": "https://verdaccio.lossless.one/@types%2fnode/-/node-12.7.3.tgz", | ||||
|       "integrity": "sha512-3SiLAIBkDWDg6vFo0+5YJyHPWU9uwu40Qe+v+0MH8wRKYBimHvvAOyk3EzMrD/TrIlLYfXrqDqrg913PynrMJQ==" | ||||
|     }, | ||||
|     "@types/nodegit": { | ||||
|       "version": "0.24.8", | ||||
|       "resolved": "https://verdaccio.lossless.one/@types%2fnodegit/-/nodegit-0.24.8.tgz", | ||||
|       "integrity": "sha512-MgeLmeBsi8sOn0IzQuw+Il4Cw71MLUNm4du44ewd5riLXbni0DZLjWx7PJO2mVegsnv0WNosXrpifQnWJjjNkg==", | ||||
|       "version": "0.24.10", | ||||
|       "resolved": "https://registry.npmjs.org/@types/nodegit/-/nodegit-0.24.10.tgz", | ||||
|       "integrity": "sha512-8YoiONPaaKcZr2vmFZyr4+AQB66OEYJpbVIHY2/nOIYjhKZP78fJtz/CD6lecaWyrLnSxM/k7IkNueu+SwObOw==", | ||||
|       "requires": { | ||||
|         "@types/node": "*" | ||||
|       } | ||||
| @@ -746,7 +788,7 @@ | ||||
|     }, | ||||
|     "abbrev": { | ||||
|       "version": "1.1.1", | ||||
|       "resolved": "https://verdaccio.lossless.one/abbrev/-/abbrev-1.1.1.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", | ||||
|       "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" | ||||
|     }, | ||||
|     "accepts": { | ||||
| @@ -794,12 +836,12 @@ | ||||
|     }, | ||||
|     "aproba": { | ||||
|       "version": "1.2.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/aproba/-/aproba-1.2.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", | ||||
|       "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" | ||||
|     }, | ||||
|     "are-we-there-yet": { | ||||
|       "version": "1.1.5", | ||||
|       "resolved": "https://verdaccio.lossless.one/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", | ||||
|       "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", | ||||
|       "requires": { | ||||
|         "delegates": "^1.0.0", | ||||
| @@ -832,7 +874,7 @@ | ||||
|     }, | ||||
|     "asap": { | ||||
|       "version": "2.0.6", | ||||
|       "resolved": "https://verdaccio.lossless.one/asap/-/asap-2.0.6.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", | ||||
|       "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" | ||||
|     }, | ||||
|     "asn1": { | ||||
| @@ -912,7 +954,7 @@ | ||||
|     }, | ||||
|     "bl": { | ||||
|       "version": "1.2.2", | ||||
|       "resolved": "https://verdaccio.lossless.one/bl/-/bl-1.2.2.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", | ||||
|       "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", | ||||
|       "requires": { | ||||
|         "readable-stream": "^2.3.5", | ||||
| @@ -972,7 +1014,7 @@ | ||||
|     }, | ||||
|     "buffer-alloc": { | ||||
|       "version": "1.2.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/buffer-alloc/-/buffer-alloc-1.2.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", | ||||
|       "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", | ||||
|       "requires": { | ||||
|         "buffer-alloc-unsafe": "^1.1.0", | ||||
| @@ -981,12 +1023,12 @@ | ||||
|     }, | ||||
|     "buffer-alloc-unsafe": { | ||||
|       "version": "1.1.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", | ||||
|       "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" | ||||
|     }, | ||||
|     "buffer-fill": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/buffer-fill/-/buffer-fill-1.0.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", | ||||
|       "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" | ||||
|     }, | ||||
|     "buffer-from": { | ||||
| @@ -1073,7 +1115,7 @@ | ||||
|     }, | ||||
|     "chownr": { | ||||
|       "version": "1.1.2", | ||||
|       "resolved": "https://verdaccio.lossless.one/chownr/-/chownr-1.1.2.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", | ||||
|       "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==" | ||||
|     }, | ||||
|     "cli-cursor": { | ||||
| @@ -1178,7 +1220,7 @@ | ||||
|     }, | ||||
|     "console-control-strings": { | ||||
|       "version": "1.1.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/console-control-strings/-/console-control-strings-1.1.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", | ||||
|       "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" | ||||
|     }, | ||||
|     "content-disposition": { | ||||
| @@ -1263,7 +1305,7 @@ | ||||
|     }, | ||||
|     "debug": { | ||||
|       "version": "3.2.6", | ||||
|       "resolved": "https://verdaccio.lossless.one/debug/-/debug-3.2.6.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", | ||||
|       "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", | ||||
|       "requires": { | ||||
|         "ms": "^2.1.1" | ||||
| @@ -1285,7 +1327,7 @@ | ||||
|     }, | ||||
|     "deep-extend": { | ||||
|       "version": "0.6.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/deep-extend/-/deep-extend-0.6.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", | ||||
|       "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" | ||||
|     }, | ||||
|     "defaults": { | ||||
| @@ -1310,7 +1352,7 @@ | ||||
|     }, | ||||
|     "delegates": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/delegates/-/delegates-1.0.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", | ||||
|       "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" | ||||
|     }, | ||||
|     "depd": { | ||||
| @@ -1325,7 +1367,7 @@ | ||||
|     }, | ||||
|     "detect-libc": { | ||||
|       "version": "1.0.3", | ||||
|       "resolved": "https://verdaccio.lossless.one/detect-libc/-/detect-libc-1.0.3.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", | ||||
|       "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" | ||||
|     }, | ||||
|     "diff": { | ||||
| @@ -1670,7 +1712,7 @@ | ||||
|     }, | ||||
|     "fs-constants": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/fs-constants/-/fs-constants-1.0.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", | ||||
|       "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" | ||||
|     }, | ||||
|     "fs-extra": { | ||||
| @@ -1685,7 +1727,7 @@ | ||||
|     }, | ||||
|     "fs-minipass": { | ||||
|       "version": "1.2.6", | ||||
|       "resolved": "https://verdaccio.lossless.one/fs-minipass/-/fs-minipass-1.2.6.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz", | ||||
|       "integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==", | ||||
|       "requires": { | ||||
|         "minipass": "^2.2.1" | ||||
| @@ -1698,7 +1740,7 @@ | ||||
|     }, | ||||
|     "gauge": { | ||||
|       "version": "2.7.4", | ||||
|       "resolved": "https://verdaccio.lossless.one/gauge/-/gauge-2.7.4.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", | ||||
|       "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", | ||||
|       "requires": { | ||||
|         "aproba": "^1.0.3", | ||||
| @@ -1713,12 +1755,12 @@ | ||||
|       "dependencies": { | ||||
|         "ansi-regex": { | ||||
|           "version": "2.1.1", | ||||
|           "resolved": "https://verdaccio.lossless.one/ansi-regex/-/ansi-regex-2.1.1.tgz", | ||||
|           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", | ||||
|           "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" | ||||
|         }, | ||||
|         "is-fullwidth-code-point": { | ||||
|           "version": "1.0.0", | ||||
|           "resolved": "https://verdaccio.lossless.one/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", | ||||
|           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", | ||||
|           "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", | ||||
|           "requires": { | ||||
|             "number-is-nan": "^1.0.0" | ||||
| @@ -1726,7 +1768,7 @@ | ||||
|         }, | ||||
|         "string-width": { | ||||
|           "version": "1.0.2", | ||||
|           "resolved": "https://verdaccio.lossless.one/string-width/-/string-width-1.0.2.tgz", | ||||
|           "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", | ||||
|           "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", | ||||
|           "requires": { | ||||
|             "code-point-at": "^1.0.0", | ||||
| @@ -1736,7 +1778,7 @@ | ||||
|         }, | ||||
|         "strip-ansi": { | ||||
|           "version": "3.0.1", | ||||
|           "resolved": "https://verdaccio.lossless.one/strip-ansi/-/strip-ansi-3.0.1.tgz", | ||||
|           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", | ||||
|           "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", | ||||
|           "requires": { | ||||
|             "ansi-regex": "^2.0.0" | ||||
| @@ -1830,7 +1872,7 @@ | ||||
|     }, | ||||
|     "has-unicode": { | ||||
|       "version": "2.0.1", | ||||
|       "resolved": "https://verdaccio.lossless.one/has-unicode/-/has-unicode-2.0.1.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", | ||||
|       "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" | ||||
|     }, | ||||
|     "helmet": { | ||||
| @@ -1947,7 +1989,7 @@ | ||||
|     }, | ||||
|     "ignore-walk": { | ||||
|       "version": "3.0.1", | ||||
|       "resolved": "https://verdaccio.lossless.one/ignore-walk/-/ignore-walk-3.0.1.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", | ||||
|       "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", | ||||
|       "requires": { | ||||
|         "minimatch": "^3.0.4" | ||||
| @@ -1974,7 +2016,7 @@ | ||||
|     }, | ||||
|     "ini": { | ||||
|       "version": "1.3.5", | ||||
|       "resolved": "https://verdaccio.lossless.one/ini/-/ini-1.3.5.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", | ||||
|       "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" | ||||
|     }, | ||||
|     "invert-kv": { | ||||
| @@ -2074,7 +2116,7 @@ | ||||
|     }, | ||||
|     "json5": { | ||||
|       "version": "2.1.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/json5/-/json5-2.1.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", | ||||
|       "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", | ||||
|       "requires": { | ||||
|         "minimist": "^1.2.0" | ||||
| @@ -2122,9 +2164,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "lodash": { | ||||
|       "version": "4.17.14", | ||||
|       "resolved": "https://verdaccio.lossless.one/lodash/-/lodash-4.17.14.tgz", | ||||
|       "integrity": "sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==" | ||||
|       "version": "4.17.15", | ||||
|       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", | ||||
|       "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" | ||||
|     }, | ||||
|     "lodash._baseassign": { | ||||
|       "version": "3.2.0", | ||||
| @@ -2310,13 +2352,13 @@ | ||||
|     }, | ||||
|     "minimist": { | ||||
|       "version": "1.2.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/minimist/-/minimist-1.2.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", | ||||
|       "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" | ||||
|     }, | ||||
|     "minipass": { | ||||
|       "version": "2.3.5", | ||||
|       "resolved": "https://verdaccio.lossless.one/minipass/-/minipass-2.3.5.tgz", | ||||
|       "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", | ||||
|       "version": "2.4.0", | ||||
|       "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.4.0.tgz", | ||||
|       "integrity": "sha512-6PmOuSP4NnZXzs2z6rbwzLJu/c5gdzYg1mRI/WIYdx45iiX7T+a4esOzavD6V/KmBzAaopFSTZPZcUx73bqKWA==", | ||||
|       "requires": { | ||||
|         "safe-buffer": "^5.1.2", | ||||
|         "yallist": "^3.0.0" | ||||
| @@ -2324,7 +2366,7 @@ | ||||
|     }, | ||||
|     "minizlib": { | ||||
|       "version": "1.2.1", | ||||
|       "resolved": "https://verdaccio.lossless.one/minizlib/-/minizlib-1.2.1.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", | ||||
|       "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", | ||||
|       "requires": { | ||||
|         "minipass": "^2.2.1" | ||||
| @@ -2365,7 +2407,7 @@ | ||||
|     }, | ||||
|     "nan": { | ||||
|       "version": "2.14.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/nan/-/nan-2.14.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", | ||||
|       "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" | ||||
|     }, | ||||
|     "nanoid": { | ||||
| @@ -2375,7 +2417,7 @@ | ||||
|     }, | ||||
|     "needle": { | ||||
|       "version": "2.4.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/needle/-/needle-2.4.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", | ||||
|       "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", | ||||
|       "requires": { | ||||
|         "debug": "^3.2.6", | ||||
| @@ -2400,7 +2442,7 @@ | ||||
|     }, | ||||
|     "node-gyp": { | ||||
|       "version": "4.0.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/node-gyp/-/node-gyp-4.0.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", | ||||
|       "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", | ||||
|       "requires": { | ||||
|         "glob": "^7.0.3", | ||||
| @@ -2418,15 +2460,15 @@ | ||||
|       "dependencies": { | ||||
|         "semver": { | ||||
|           "version": "5.3.0", | ||||
|           "resolved": "https://verdaccio.lossless.one/semver/-/semver-5.3.0.tgz", | ||||
|           "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", | ||||
|           "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "node-pre-gyp": { | ||||
|       "version": "0.11.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", | ||||
|       "integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==", | ||||
|       "version": "0.13.0", | ||||
|       "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz", | ||||
|       "integrity": "sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==", | ||||
|       "requires": { | ||||
|         "detect-libc": "^1.0.2", | ||||
|         "mkdirp": "^0.5.1", | ||||
| @@ -2442,7 +2484,7 @@ | ||||
|       "dependencies": { | ||||
|         "nopt": { | ||||
|           "version": "4.0.1", | ||||
|           "resolved": "https://verdaccio.lossless.one/nopt/-/nopt-4.0.1.tgz", | ||||
|           "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", | ||||
|           "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", | ||||
|           "requires": { | ||||
|             "abbrev": "1", | ||||
| @@ -2452,16 +2494,16 @@ | ||||
|       } | ||||
|     }, | ||||
|     "nodegit": { | ||||
|       "version": "0.24.3", | ||||
|       "resolved": "https://verdaccio.lossless.one/nodegit/-/nodegit-0.24.3.tgz", | ||||
|       "integrity": "sha512-F9XpC5xzpoBgJXmdIRaD2z5DVG+iMttxFlzyCqmOu3y5y/DFuxBpzQtRND75oUOxJZh8sSlReVnXFV3PEyzvIw==", | ||||
|       "version": "0.25.1", | ||||
|       "resolved": "https://registry.npmjs.org/nodegit/-/nodegit-0.25.1.tgz", | ||||
|       "integrity": "sha512-j2kEd4jTraimRPKDX31DsLcfY9fWpcYG8zT0tiLVtN5jMm9fDFgn3WOQ+Nk+3NcBqxr4p5N5pZqNrCS0nGdTbg==", | ||||
|       "requires": { | ||||
|         "fs-extra": "^7.0.0", | ||||
|         "json5": "^2.1.0", | ||||
|         "lodash": "^4.17.11", | ||||
|         "nan": "^2.11.1", | ||||
|         "lodash": "^4.17.14", | ||||
|         "nan": "^2.14.0", | ||||
|         "node-gyp": "^4.0.0", | ||||
|         "node-pre-gyp": "^0.11.0", | ||||
|         "node-pre-gyp": "^0.13.0", | ||||
|         "promisify-node": "~0.3.0", | ||||
|         "ramda": "^0.25.0", | ||||
|         "request-promise-native": "^1.0.5", | ||||
| @@ -2470,7 +2512,7 @@ | ||||
|     }, | ||||
|     "nodegit-promise": { | ||||
|       "version": "4.0.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/nodegit-promise/-/nodegit-promise-4.0.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/nodegit-promise/-/nodegit-promise-4.0.0.tgz", | ||||
|       "integrity": "sha1-VyKxhPLfcycWEGSnkdLoQskWezQ=", | ||||
|       "requires": { | ||||
|         "asap": "~2.0.3" | ||||
| @@ -2478,7 +2520,7 @@ | ||||
|     }, | ||||
|     "nopt": { | ||||
|       "version": "3.0.6", | ||||
|       "resolved": "https://verdaccio.lossless.one/nopt/-/nopt-3.0.6.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", | ||||
|       "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", | ||||
|       "requires": { | ||||
|         "abbrev": "1" | ||||
| @@ -2491,12 +2533,12 @@ | ||||
|     }, | ||||
|     "npm-bundled": { | ||||
|       "version": "1.0.6", | ||||
|       "resolved": "https://verdaccio.lossless.one/npm-bundled/-/npm-bundled-1.0.6.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", | ||||
|       "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==" | ||||
|     }, | ||||
|     "npm-packlist": { | ||||
|       "version": "1.4.4", | ||||
|       "resolved": "https://verdaccio.lossless.one/npm-packlist/-/npm-packlist-1.4.4.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.4.tgz", | ||||
|       "integrity": "sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw==", | ||||
|       "requires": { | ||||
|         "ignore-walk": "^3.0.1", | ||||
| @@ -2513,7 +2555,7 @@ | ||||
|     }, | ||||
|     "npmlog": { | ||||
|       "version": "4.1.2", | ||||
|       "resolved": "https://verdaccio.lossless.one/npmlog/-/npmlog-4.1.2.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", | ||||
|       "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", | ||||
|       "requires": { | ||||
|         "are-we-there-yet": "~1.1.2", | ||||
| @@ -2603,7 +2645,7 @@ | ||||
|     }, | ||||
|     "os-homedir": { | ||||
|       "version": "1.0.2", | ||||
|       "resolved": "https://verdaccio.lossless.one/os-homedir/-/os-homedir-1.0.2.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", | ||||
|       "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" | ||||
|     }, | ||||
|     "os-locale": { | ||||
| @@ -2618,12 +2660,12 @@ | ||||
|     }, | ||||
|     "os-tmpdir": { | ||||
|       "version": "1.0.2", | ||||
|       "resolved": "https://verdaccio.lossless.one/os-tmpdir/-/os-tmpdir-1.0.2.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", | ||||
|       "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" | ||||
|     }, | ||||
|     "osenv": { | ||||
|       "version": "0.1.5", | ||||
|       "resolved": "https://verdaccio.lossless.one/osenv/-/osenv-0.1.5.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", | ||||
|       "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", | ||||
|       "requires": { | ||||
|         "os-homedir": "^1.0.0", | ||||
| @@ -2741,7 +2783,7 @@ | ||||
|     }, | ||||
|     "promisify-node": { | ||||
|       "version": "0.3.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/promisify-node/-/promisify-node-0.3.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/promisify-node/-/promisify-node-0.3.0.tgz", | ||||
|       "integrity": "sha1-tLVaz5D6p9K4uQyjlomQhsAwYM8=", | ||||
|       "requires": { | ||||
|         "nodegit-promise": "~4.0.0" | ||||
| @@ -2782,7 +2824,7 @@ | ||||
|     }, | ||||
|     "ramda": { | ||||
|       "version": "0.25.0", | ||||
|       "resolved": "https://verdaccio.lossless.one/ramda/-/ramda-0.25.0.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", | ||||
|       "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==" | ||||
|     }, | ||||
|     "randomatic": { | ||||
| @@ -2813,7 +2855,7 @@ | ||||
|     }, | ||||
|     "rc": { | ||||
|       "version": "1.2.8", | ||||
|       "resolved": "https://verdaccio.lossless.one/rc/-/rc-1.2.8.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", | ||||
|       "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", | ||||
|       "requires": { | ||||
|         "deep-extend": "^0.6.0", | ||||
| @@ -2901,7 +2943,7 @@ | ||||
|     }, | ||||
|     "request-promise-core": { | ||||
|       "version": "1.1.2", | ||||
|       "resolved": "https://verdaccio.lossless.one/request-promise-core/-/request-promise-core-1.1.2.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", | ||||
|       "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", | ||||
|       "requires": { | ||||
|         "lodash": "^4.17.11" | ||||
| @@ -2909,7 +2951,7 @@ | ||||
|     }, | ||||
|     "request-promise-native": { | ||||
|       "version": "1.0.7", | ||||
|       "resolved": "https://verdaccio.lossless.one/request-promise-native/-/request-promise-native-1.0.7.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", | ||||
|       "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", | ||||
|       "requires": { | ||||
|         "request-promise-core": "1.1.2", | ||||
| @@ -2946,9 +2988,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "rimraf": { | ||||
|       "version": "2.6.3", | ||||
|       "resolved": "https://verdaccio.lossless.one/rimraf/-/rimraf-2.6.3.tgz", | ||||
|       "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", | ||||
|       "version": "2.7.1", | ||||
|       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", | ||||
|       "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", | ||||
|       "requires": { | ||||
|         "glob": "^7.1.3" | ||||
|       } | ||||
| @@ -2973,7 +3015,7 @@ | ||||
|     }, | ||||
|     "sax": { | ||||
|       "version": "1.2.4", | ||||
|       "resolved": "https://verdaccio.lossless.one/sax/-/sax-1.2.4.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", | ||||
|       "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" | ||||
|     }, | ||||
|     "semver": { | ||||
| @@ -3233,7 +3275,7 @@ | ||||
|     }, | ||||
|     "stealthy-require": { | ||||
|       "version": "1.1.1", | ||||
|       "resolved": "https://verdaccio.lossless.one/stealthy-require/-/stealthy-require-1.1.1.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", | ||||
|       "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" | ||||
|     }, | ||||
|     "string-width": { | ||||
| @@ -3298,7 +3340,7 @@ | ||||
|     }, | ||||
|     "strip-json-comments": { | ||||
|       "version": "2.0.1", | ||||
|       "resolved": "https://verdaccio.lossless.one/strip-json-comments/-/strip-json-comments-2.0.1.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", | ||||
|       "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" | ||||
|     }, | ||||
|     "supports-color": { | ||||
| @@ -3316,7 +3358,7 @@ | ||||
|     }, | ||||
|     "tar": { | ||||
|       "version": "4.4.10", | ||||
|       "resolved": "https://verdaccio.lossless.one/tar/-/tar-4.4.10.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", | ||||
|       "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", | ||||
|       "requires": { | ||||
|         "chownr": "^1.1.1", | ||||
| @@ -3330,7 +3372,7 @@ | ||||
|     }, | ||||
|     "tar-fs": { | ||||
|       "version": "1.16.3", | ||||
|       "resolved": "https://verdaccio.lossless.one/tar-fs/-/tar-fs-1.16.3.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", | ||||
|       "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", | ||||
|       "requires": { | ||||
|         "chownr": "^1.0.1", | ||||
| @@ -3341,7 +3383,7 @@ | ||||
|       "dependencies": { | ||||
|         "pump": { | ||||
|           "version": "1.0.3", | ||||
|           "resolved": "https://verdaccio.lossless.one/pump/-/pump-1.0.3.tgz", | ||||
|           "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", | ||||
|           "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", | ||||
|           "requires": { | ||||
|             "end-of-stream": "^1.1.0", | ||||
| @@ -3352,7 +3394,7 @@ | ||||
|     }, | ||||
|     "tar-stream": { | ||||
|       "version": "1.6.2", | ||||
|       "resolved": "https://verdaccio.lossless.one/tar-stream/-/tar-stream-1.6.2.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", | ||||
|       "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", | ||||
|       "requires": { | ||||
|         "bl": "^1.0.0", | ||||
| @@ -3379,7 +3421,7 @@ | ||||
|     }, | ||||
|     "to-buffer": { | ||||
|       "version": "1.1.1", | ||||
|       "resolved": "https://verdaccio.lossless.one/to-buffer/-/to-buffer-1.1.1.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", | ||||
|       "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" | ||||
|     }, | ||||
|     "toidentifier": { | ||||
| @@ -3618,7 +3660,7 @@ | ||||
|     }, | ||||
|     "wide-align": { | ||||
|       "version": "1.1.3", | ||||
|       "resolved": "https://verdaccio.lossless.one/wide-align/-/wide-align-1.1.3.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", | ||||
|       "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", | ||||
|       "requires": { | ||||
|         "string-width": "^1.0.2 || 2" | ||||
| @@ -3696,7 +3738,7 @@ | ||||
|     }, | ||||
|     "xtend": { | ||||
|       "version": "4.0.2", | ||||
|       "resolved": "https://verdaccio.lossless.one/xtend/-/xtend-4.0.2.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", | ||||
|       "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" | ||||
|     }, | ||||
|     "y18n": { | ||||
| @@ -3706,7 +3748,7 @@ | ||||
|     }, | ||||
|     "yallist": { | ||||
|       "version": "3.0.3", | ||||
|       "resolved": "https://verdaccio.lossless.one/yallist/-/yallist-3.0.3.tgz", | ||||
|       "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", | ||||
|       "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" | ||||
|     }, | ||||
|     "yargs": { | ||||
|   | ||||
							
								
								
									
										15
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@shipzone/npmci", | ||||
|   "version": "3.1.38", | ||||
|   "version": "3.1.46", | ||||
|   "private": false, | ||||
|   "description": "node and docker in gitlab ci on steroids", | ||||
|   "main": "dist/index.js", | ||||
| @@ -24,32 +24,35 @@ | ||||
|   }, | ||||
|   "homepage": "https://gitlab.com/gitzone/npmci#README", | ||||
|   "devDependencies": { | ||||
|     "@gitzone/tsbuild": "^2.1.11", | ||||
|     "@gitzone/tsbuild": "^2.1.17", | ||||
|     "@gitzone/tsrun": "^1.2.6", | ||||
|     "@gitzone/tstest": "^1.0.24", | ||||
|     "@pushrocks/tapbundle": "^3.0.13", | ||||
|     "@types/node": "^12.7.2", | ||||
|     "@types/node": "^12.7.3", | ||||
|     "tslint": "^5.19.0", | ||||
|     "tslint-config-prettier": "^1.18.0" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@pushrocks/lik": "^3.0.10", | ||||
|     "@apiglobal/typedrequest": "^1.0.17", | ||||
|     "@pushrocks/lik": "^3.0.11", | ||||
|     "@pushrocks/npmextra": "^3.0.5", | ||||
|     "@pushrocks/projectinfo": "^4.0.2", | ||||
|     "@pushrocks/qenv": "^4.0.4", | ||||
|     "@pushrocks/smartanalytics": "^2.0.15", | ||||
|     "@pushrocks/smartcli": "^3.0.7", | ||||
|     "@pushrocks/smartdelay": "^2.0.3", | ||||
|     "@pushrocks/smartfile": "^7.0.2", | ||||
|     "@pushrocks/smartgit": "^1.0.9", | ||||
|     "@pushrocks/smartgit": "^1.0.13", | ||||
|     "@pushrocks/smartlog": "^2.0.19", | ||||
|     "@pushrocks/smartlog-destination-local": "^8.0.2", | ||||
|     "@pushrocks/smartparam": "^1.0.4", | ||||
|     "@pushrocks/smartpromise": "^3.0.2", | ||||
|     "@pushrocks/smartrequest": "^1.1.23", | ||||
|     "@pushrocks/smartshell": "^2.0.23", | ||||
|     "@pushrocks/smartshell": "^2.0.25", | ||||
|     "@pushrocks/smartsocket": "^1.1.45", | ||||
|     "@pushrocks/smartssh": "^1.2.3", | ||||
|     "@pushrocks/smartstring": "^3.0.10", | ||||
|     "@servezone/servezone-interfaces": "^2.0.29", | ||||
|     "@types/shelljs": "^0.8.5", | ||||
|     "@types/through2": "^2.0.34", | ||||
|     "through2": "^3.0.1" | ||||
|   | ||||
| @@ -96,6 +96,6 @@ Use TypeScript for best in class instellisense. | ||||
| For further information read the linked docs at the top of this readme. | ||||
|  | ||||
| > MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh) | ||||
| | By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html) | ||||
| | By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy) | ||||
|  | ||||
| [](https://maintainedby.lossless.com) | ||||
| [](https://maintainedby.lossless.com) | ||||
|   | ||||
							
								
								
									
										63
									
								
								test/test.ts
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								test/test.ts
									
									
									
									
									
								
							| @@ -1,7 +1,6 @@ | ||||
| import { tap, expect } from '@pushrocks/tapbundle'; | ||||
| import * as path from 'path'; | ||||
|  | ||||
| // Setup test | ||||
| process.env.NPMTS_TEST = 'true'; | ||||
|  | ||||
| // set up environment | ||||
| @@ -18,66 +17,72 @@ process.cwd = () => { | ||||
|   return path.join(__dirname, 'assets/'); | ||||
| }; | ||||
|  | ||||
| // require NPMCI files | ||||
| import '../ts/index'; | ||||
| import npmciModDocker = require('../ts/mod_docker/index'); | ||||
| import npmciModNpm = require('../ts/mod_npm/index'); | ||||
| import npmciModNode = require('../ts/mod_node/index'); | ||||
| import npmciModSsh = require('../ts/mod_ssh/index'); | ||||
| import npmciEnv = require('../ts/npmci.env'); | ||||
| import * as npmci from '../ts'; | ||||
|  | ||||
| // ====== | ||||
| // Docker | ||||
| // ====== | ||||
|  | ||||
| let dockerfile1: npmciModDocker.Dockerfile; | ||||
| let dockerfile2: npmciModDocker.Dockerfile; | ||||
| let sortableArray: npmciModDocker.Dockerfile[]; | ||||
| let dockerfile1: npmci.Dockerfile; | ||||
| let dockerfile2: npmci.Dockerfile; | ||||
| let sortableArray: npmci.Dockerfile[]; | ||||
|  | ||||
| tap.test('should return valid Dockerfiles', async () => { | ||||
|   dockerfile1 = new npmciModDocker.Dockerfile({ filePath: './Dockerfile', read: true }); | ||||
|   dockerfile2 = new npmciModDocker.Dockerfile({ filePath: './Dockerfile_sometag1', read: true }); | ||||
|   const npmciInstance = new npmci.Npmci(); | ||||
|   dockerfile1 = new npmci.Dockerfile(npmciInstance.dockerManager, { | ||||
|     filePath: './Dockerfile', | ||||
|     read: true | ||||
|   }); | ||||
|   dockerfile2 = new npmci.Dockerfile(npmciInstance.dockerManager, { | ||||
|     filePath: './Dockerfile_sometag1', | ||||
|     read: true | ||||
|   }); | ||||
|   expect(dockerfile1.version).to.equal('latest'); | ||||
|   return expect(dockerfile2.version).to.equal('sometag1'); | ||||
| }); | ||||
|  | ||||
| tap.test('should read a directory of Dockerfiles', async () => { | ||||
|   return npmciModDocker.helpers | ||||
|     .readDockerfiles() | ||||
|     .then(async (readDockerfilesArrayArg: npmciModDocker.Dockerfile[]) => { | ||||
|   const npmciInstance = new npmci.Npmci(); | ||||
|   return npmci.Dockerfile.readDockerfiles(npmciInstance.dockerManager).then( | ||||
|     async (readDockerfilesArrayArg: npmci.Dockerfile[]) => { | ||||
|       sortableArray = readDockerfilesArrayArg; | ||||
|       return expect(readDockerfilesArrayArg[1].version).to.equal('sometag1'); | ||||
|     }); | ||||
|     } | ||||
|   ); | ||||
| }); | ||||
|  | ||||
| tap.test('should sort an array of Dockerfiles', async () => { | ||||
|   return npmciModDocker.helpers | ||||
|     .sortDockerfiles(sortableArray) | ||||
|     .then(async (sortedArrayArg: npmciModDocker.Dockerfile[]) => { | ||||
|   return npmci.Dockerfile.sortDockerfiles(sortableArray).then( | ||||
|     async (sortedArrayArg: npmci.Dockerfile[]) => { | ||||
|       console.log(sortedArrayArg); | ||||
|     }); | ||||
|     } | ||||
|   ); | ||||
| }); | ||||
|  | ||||
| tap.test('should build all Dockerfiles', async () => { | ||||
|   return npmciModDocker.handleCli({ | ||||
|   const npmciInstance = new npmci.Npmci(); | ||||
|   return npmciInstance.dockerManager.handleCli({ | ||||
|     _: ['docker', 'build'] | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| tap.test('should test all Dockerfiles', async () => { | ||||
|   return await npmciModDocker.handleCli({ | ||||
|   const npmciInstance = new npmci.Npmci(); | ||||
|   return npmciInstance.dockerManager.handleCli({ | ||||
|     _: ['docker', 'test'] | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| tap.test('should test dockerfiles', async () => { | ||||
|   return await npmciModDocker.handleCli({ | ||||
|   const npmciInstance = new npmci.Npmci(); | ||||
|   return npmciInstance.dockerManager.handleCli({ | ||||
|     _: ['docker', 'test'] | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| tap.test('should login docker daemon', async () => { | ||||
|   return await npmciModDocker.handleCli({ | ||||
|   const npmciInstance = new npmci.Npmci(); | ||||
|   return npmciInstance.dockerManager.handleCli({ | ||||
|     _: ['docker', 'login'] | ||||
|   }); | ||||
| }); | ||||
| @@ -86,6 +91,7 @@ tap.test('should login docker daemon', async () => { | ||||
| // SSH | ||||
| // === | ||||
| tap.test('should prepare SSH keys', async () => { | ||||
|   const npmciModSsh = await import('../ts/mod_ssh'); | ||||
|   return await npmciModSsh.handleCli({ | ||||
|     _: ['ssh', 'prepare'] | ||||
|   }); | ||||
| @@ -95,13 +101,14 @@ tap.test('should prepare SSH keys', async () => { | ||||
| // node | ||||
| // ==== | ||||
| tap.test('should install a certain version of node', async () => { | ||||
|   await npmciModNode.handleCli({ | ||||
|   const npmciInstance = new npmci.Npmci(); | ||||
|   await npmciInstance.nodejsManager.handleCli({ | ||||
|     _: ['node', 'install', 'stable'] | ||||
|   }); | ||||
|   await npmciModNode.handleCli({ | ||||
|   await npmciInstance.nodejsManager.handleCli({ | ||||
|     _: ['node', 'install', 'lts'] | ||||
|   }); | ||||
|   await npmciModNode.handleCli({ | ||||
|   await npmciInstance.nodejsManager.handleCli({ | ||||
|     _: ['node', 'install', 'legacy'] | ||||
|   }); | ||||
| }); | ||||
|   | ||||
							
								
								
									
										30
									
								
								ts/connector.cloudly/cloudlyconnector.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								ts/connector.cloudly/cloudlyconnector.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| import * as plugins from '../npmci.plugins'; | ||||
|  | ||||
| import {Npmci} from '../npmci.classes.npmci'; | ||||
| import { logger } from '../npmci.logging'; | ||||
|  | ||||
| /** | ||||
|  * connects to cloudly | ||||
|  */ | ||||
| export class CloudlyConnector { | ||||
|   public npmciRef: Npmci; | ||||
|  | ||||
|   constructor(npmciRefArg: Npmci) { | ||||
|     this.npmciRef = npmciRefArg; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   public async announceDockerContainer(optionsArg: plugins.servezoneInterfaces.IVersionData) { | ||||
|     const cloudlyUrl = this.npmciRef.npmciConfig.getConfig().urlCloudly; | ||||
|     if (!cloudlyUrl) { | ||||
|       logger.log('warn', 'no cloudly url provided. Thus we cannot announce the newly built Dockerimage!'); | ||||
|       return; | ||||
|     } | ||||
|      | ||||
|     const typedrequest = new plugins.typedrequest.TypedRequest< | ||||
|       plugins.servezoneInterfaces.IRequest_Any_Cloudly_VersionManager_Update | ||||
|     >(`https://${cloudlyUrl}/versionmanager`, 'update'); | ||||
|  | ||||
|     const response = (await typedrequest.fire(optionsArg)); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										11
									
								
								ts/index.ts
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								ts/index.ts
									
									
									
									
									
								
							| @@ -1 +1,10 @@ | ||||
| import './npmci.cli'; | ||||
| import { Npmci } from './npmci.classes.npmci'; | ||||
| import { Dockerfile } from './manager.docker/mod.classes.dockerfile'; | ||||
|  | ||||
| export const npmciInstance = new Npmci(); | ||||
|  | ||||
| export { Dockerfile, Npmci }; | ||||
|  | ||||
| if (process.env.CLI_CALL) { | ||||
|   npmciInstance.start(); | ||||
| } | ||||
|   | ||||
							
								
								
									
										177
									
								
								ts/manager.docker/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								ts/manager.docker/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,177 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
| import { bash } from '../npmci.bash'; | ||||
|  | ||||
| // classes | ||||
| import { Npmci } from '../npmci.classes.npmci'; | ||||
| import { Dockerfile } from './mod.classes.dockerfile'; | ||||
| import { DockerRegistry } from './mod.classes.dockerregistry'; | ||||
| import { RegistryStorage } from './mod.classes.registrystorage'; | ||||
|  | ||||
| export class NpmciDockerManager { | ||||
|   public npmciRef: Npmci; | ||||
|   public npmciRegistryStorage = new RegistryStorage(); | ||||
|  | ||||
|   constructor(npmciArg: Npmci) { | ||||
|     this.npmciRef = npmciArg; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * handle cli input | ||||
|    * @param argvArg | ||||
|    */ | ||||
|   public handleCli = async argvArg => { | ||||
|     if (argvArg._.length >= 2) { | ||||
|       const action: string = argvArg._[1]; | ||||
|       switch (action) { | ||||
|         case 'build': | ||||
|           await this.build(); | ||||
|           break; | ||||
|         case 'login': | ||||
|         case 'prepare': | ||||
|           await this.login(); | ||||
|           break; | ||||
|         case 'test': | ||||
|           await this.test(); | ||||
|           break; | ||||
|         case 'push': | ||||
|           await this.push(argvArg); | ||||
|           break; | ||||
|         case 'pull': | ||||
|           await this.pull(argvArg); | ||||
|           break; | ||||
|         default: | ||||
|           logger.log('error', `>>npmci docker ...<< action >>${action}<< not supported`); | ||||
|       } | ||||
|     } else { | ||||
|       logger.log( | ||||
|         'info', | ||||
|         `>>npmci docker ...<< cli arguments invalid... Please read the documentation.` | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * builds a cwd of Dockerfiles by triggering a promisechain | ||||
|    */ | ||||
|   public build = async () => { | ||||
|     await this.prepare(); | ||||
|     logger.log('info', 'now building Dockerfiles...'); | ||||
|     await Dockerfile.readDockerfiles(this) | ||||
|       .then(Dockerfile.sortDockerfiles) | ||||
|       .then(Dockerfile.mapDockerfiles) | ||||
|       .then(Dockerfile.buildDockerfiles); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * login to the DockerRegistries | ||||
|    */ | ||||
|   public login = async () => { | ||||
|     await this.prepare(); | ||||
|     await this.npmciRegistryStorage.loginAll(); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * logs in docker | ||||
|    */ | ||||
|   public prepare = async () => { | ||||
|     // Always login to GitLab Registry | ||||
|     if (!process.env.CI_BUILD_TOKEN || process.env.CI_BUILD_TOKEN === '') { | ||||
|       logger.log('error', 'No registry token specified by gitlab!'); | ||||
|       process.exit(1); | ||||
|     } | ||||
|     this.npmciRegistryStorage.addRegistry( | ||||
|       new DockerRegistry({ | ||||
|         registryUrl: 'registry.gitlab.com', | ||||
|         username: 'gitlab-ci-token', | ||||
|         password: process.env.CI_BUILD_TOKEN | ||||
|       }) | ||||
|     ); | ||||
|  | ||||
|     // handle registries | ||||
|     await plugins.smartparam.forEachMinimatch( | ||||
|       process.env, | ||||
|       'NPMCI_LOGIN_DOCKER*', | ||||
|       async envString => { | ||||
|         this.npmciRegistryStorage.addRegistry(DockerRegistry.fromEnvString(envString)); | ||||
|       } | ||||
|     ); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * pushes an image towards a registry | ||||
|    * @param argvArg | ||||
|    */ | ||||
|   public push = async argvArg => { | ||||
|     await this.prepare(); | ||||
|     let dockerRegistryUrls: string[] = []; | ||||
|  | ||||
|     // lets parse the input of cli and npmextra | ||||
|     if (argvArg._.length >= 3 && argvArg._[2] !== 'npmextra') { | ||||
|       dockerRegistryUrls.push(argvArg._[2]); | ||||
|     } else { | ||||
|       if (this.npmciRef.npmciConfig.getConfig().dockerRegistries.length === 0) { | ||||
|         logger.log( | ||||
|           'warn', | ||||
|           `There are no docker registries listed in npmextra.json! This is strange!` | ||||
|         ); | ||||
|       } | ||||
|       dockerRegistryUrls = dockerRegistryUrls.concat( | ||||
|         this.npmciRef.npmciConfig.getConfig().dockerRegistries | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     // lets determine the suffix | ||||
|     let suffix = null; | ||||
|     if (argvArg._.length >= 4) { | ||||
|       suffix = argvArg._[3]; | ||||
|     } | ||||
|  | ||||
|     // lets push to the registries | ||||
|     for (const dockerRegistryUrl of dockerRegistryUrls) { | ||||
|       const dockerfileArray = await Dockerfile.readDockerfiles(this) | ||||
|         .then(Dockerfile.sortDockerfiles) | ||||
|         .then(Dockerfile.mapDockerfiles); | ||||
|       const dockerRegistryToPushTo = this.npmciRegistryStorage.getRegistryByUrl(dockerRegistryUrl); | ||||
|       if (!dockerRegistryToPushTo) { | ||||
|         logger.log( | ||||
|           'error', | ||||
|           `Cannot push to registry ${dockerRegistryUrl}, because it was not found in the authenticated registry list.` | ||||
|         ); | ||||
|         process.exit(1); | ||||
|       } | ||||
|       for (const dockerfile of dockerfileArray) { | ||||
|         await dockerfile.push(dockerRegistryToPushTo, suffix); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * pulls an image | ||||
|    */ | ||||
|   public pull = async argvArg => { | ||||
|     await this.prepare(); | ||||
|     const registryUrlArg = argvArg._[2]; | ||||
|     let suffix = null; | ||||
|     if (argvArg._.length >= 4) { | ||||
|       suffix = argvArg._[3]; | ||||
|     } | ||||
|     const localDockerRegistry = this.npmciRegistryStorage.getRegistryByUrl(registryUrlArg); | ||||
|     const dockerfileArray = await Dockerfile.readDockerfiles(this) | ||||
|       .then(Dockerfile.sortDockerfiles) | ||||
|       .then(Dockerfile.mapDockerfiles); | ||||
|     for (const dockerfile of dockerfileArray) { | ||||
|       await dockerfile.pull(localDockerRegistry, suffix); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * tests docker files | ||||
|    */ | ||||
|   public test = async () => { | ||||
|     await this.prepare(); | ||||
|     return await Dockerfile.readDockerfiles(this).then(Dockerfile.testDockerfiles); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										329
									
								
								ts/manager.docker/mod.classes.dockerfile.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										329
									
								
								ts/manager.docker/mod.classes.dockerfile.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,329 @@ | ||||
| import * as plugins from './mod.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
|  | ||||
| import { logger } from '../npmci.logging'; | ||||
| import { bash } from '../npmci.bash'; | ||||
|  | ||||
| import { DockerRegistry } from './mod.classes.dockerregistry'; | ||||
| import * as helpers from './mod.helpers'; | ||||
| import { NpmciDockerManager } from '.'; | ||||
| import { Npmci } from '../npmci.classes.npmci'; | ||||
|  | ||||
| /** | ||||
|  * class Dockerfile represents a Dockerfile on disk in npmci | ||||
|  */ | ||||
| export class Dockerfile { | ||||
|   // STATIC | ||||
|  | ||||
|   /** | ||||
|    * creates instance of class Dockerfile for all Dockerfiles in cwd | ||||
|    * @returns Promise<Dockerfile[]> | ||||
|    */ | ||||
|   public static async readDockerfiles( | ||||
|     npmciDockerManagerRefArg: NpmciDockerManager | ||||
|   ): Promise<Dockerfile[]> { | ||||
|     const fileTree = await plugins.smartfile.fs.listFileTree(paths.cwd, 'Dockerfile*'); | ||||
|  | ||||
|     // create the Dockerfile array | ||||
|     const readDockerfilesArray: Dockerfile[] = []; | ||||
|     logger.log('info', `found ${fileTree.length} Dockerfiles:`); | ||||
|     console.log(fileTree); | ||||
|     for (const dockerfilePath of fileTree) { | ||||
|       const myDockerfile = new Dockerfile(npmciDockerManagerRefArg, { | ||||
|         filePath: dockerfilePath, | ||||
|         read: true | ||||
|       }); | ||||
|       readDockerfilesArray.push(myDockerfile); | ||||
|     } | ||||
|  | ||||
|     return readDockerfilesArray; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * sorts Dockerfiles into a dependency chain | ||||
|    * @param sortableArrayArg an array of instances of class Dockerfile | ||||
|    * @returns Promise<Dockerfile[]> | ||||
|    */ | ||||
|   public static async sortDockerfiles(sortableArrayArg: Dockerfile[]): Promise<Dockerfile[]> { | ||||
|     const done = plugins.smartpromise.defer<Dockerfile[]>(); | ||||
|     logger.log('info', 'sorting Dockerfiles:'); | ||||
|     const sortedArray: Dockerfile[] = []; | ||||
|     const cleanTagsOriginal = Dockerfile.cleanTagsArrayFunction(sortableArrayArg, sortedArray); | ||||
|     let sorterFunctionCounter: number = 0; | ||||
|     const sorterFunction = () => { | ||||
|       sortableArrayArg.forEach(dockerfileArg => { | ||||
|         const cleanTags = Dockerfile.cleanTagsArrayFunction(sortableArrayArg, sortedArray); | ||||
|         if ( | ||||
|           cleanTags.indexOf(dockerfileArg.baseImage) === -1 && | ||||
|           sortedArray.indexOf(dockerfileArg) === -1 | ||||
|         ) { | ||||
|           sortedArray.push(dockerfileArg); | ||||
|         } | ||||
|         if (cleanTagsOriginal.indexOf(dockerfileArg.baseImage) !== -1) { | ||||
|           dockerfileArg.localBaseImageDependent = true; | ||||
|         } | ||||
|       }); | ||||
|       if (sortableArrayArg.length === sortedArray.length) { | ||||
|         let counter = 1; | ||||
|         for (const dockerfile of sortedArray) { | ||||
|           logger.log('info', `tag ${counter}: -> ${dockerfile.cleanTag}`); | ||||
|           counter++; | ||||
|         } | ||||
|         done.resolve(sortedArray); | ||||
|       } else if (sorterFunctionCounter < 10) { | ||||
|         sorterFunctionCounter++; | ||||
|         sorterFunction(); | ||||
|       } | ||||
|     }; | ||||
|     sorterFunction(); | ||||
|     return done.promise; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * maps local Dockerfiles dependencies to the correspoding Dockerfile class instances | ||||
|    */ | ||||
|   public static async mapDockerfiles(sortedDockerfileArray: Dockerfile[]): Promise<Dockerfile[]> { | ||||
|     sortedDockerfileArray.forEach(dockerfileArg => { | ||||
|       if (dockerfileArg.localBaseImageDependent) { | ||||
|         sortedDockerfileArray.forEach((dockfile2: Dockerfile) => { | ||||
|           if (dockfile2.cleanTag === dockerfileArg.baseImage) { | ||||
|             dockerfileArg.localBaseDockerfile = dockfile2; | ||||
|           } | ||||
|         }); | ||||
|       } | ||||
|     }); | ||||
|     return sortedDockerfileArray; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * builds the correspoding real docker image for each Dockerfile class instance | ||||
|    */ | ||||
|   public static async buildDockerfiles(sortedArrayArg: Dockerfile[]) { | ||||
|     for (const dockerfileArg of sortedArrayArg) { | ||||
|       await dockerfileArg.build(); | ||||
|     } | ||||
|     return sortedArrayArg; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * tests all Dockerfiles in by calling class Dockerfile.test(); | ||||
|    * @param sortedArrayArg Dockerfile[] that contains all Dockerfiles in cwd | ||||
|    */ | ||||
|   public static async testDockerfiles(sortedArrayArg: Dockerfile[]) { | ||||
|     for (const dockerfileArg of sortedArrayArg) { | ||||
|       await dockerfileArg.test(); | ||||
|     } | ||||
|     return sortedArrayArg; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * returns a version for a docker file | ||||
|    * @execution SYNC | ||||
|    */ | ||||
|   public static dockerFileVersion(dockerfileNameArg: string): string { | ||||
|     let versionString: string; | ||||
|     const versionRegex = /Dockerfile_([a-zA-Z0-9\.]*)$/; | ||||
|     const regexResultArray = versionRegex.exec(dockerfileNameArg); | ||||
|     if (regexResultArray && regexResultArray.length === 2) { | ||||
|       versionString = regexResultArray[1]; | ||||
|     } else { | ||||
|       versionString = 'latest'; | ||||
|     } | ||||
|     return versionString; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * returns the docker base image for a Dockerfile | ||||
|    */ | ||||
|   public static dockerBaseImage(dockerfileContentArg: string): string { | ||||
|     const baseImageRegex = /FROM\s([a-zA-z0-9\/\-\:]*)\n?/; | ||||
|     const regexResultArray = baseImageRegex.exec(dockerfileContentArg); | ||||
|     return regexResultArray[1]; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * returns the docker tag | ||||
|    */ | ||||
|   public static getDockerTagString( | ||||
|     npmciDockerManagerRef: NpmciDockerManager, | ||||
|     registryArg: string, | ||||
|     repoArg: string, | ||||
|     versionArg: string, | ||||
|     suffixArg?: string | ||||
|   ): string { | ||||
|     // determine wether the repo should be mapped accordingly to the registry | ||||
|     const mappedRepo = npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerRegistryRepoMap[ | ||||
|       registryArg | ||||
|     ]; | ||||
|     const repo = (() => { | ||||
|       if (mappedRepo) { | ||||
|         return mappedRepo; | ||||
|       } else { | ||||
|         return repoArg; | ||||
|       } | ||||
|     })(); | ||||
|  | ||||
|     // determine wether the version contais a suffix | ||||
|     let version = versionArg; | ||||
|     if (suffixArg) { | ||||
|       version = versionArg + '_' + suffixArg; | ||||
|     } | ||||
|  | ||||
|     const tagString = `${registryArg}/${repo}:${version}`; | ||||
|     return tagString; | ||||
|   } | ||||
|  | ||||
|   public static async getDockerBuildArgs( | ||||
|     npmciDockerManagerRef: NpmciDockerManager | ||||
|   ): Promise<string> { | ||||
|     logger.log('info', 'checking for env vars to be supplied to the docker build'); | ||||
|     let buildArgsString: string = ''; | ||||
|     for (const key of Object.keys( | ||||
|       npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerBuildargEnvMap | ||||
|     )) { | ||||
|       const targetValue = | ||||
|         process.env[ | ||||
|           npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerBuildargEnvMap[key] | ||||
|         ]; | ||||
|       buildArgsString = `${buildArgsString} --build-arg ${key}="${targetValue}"`; | ||||
|     } | ||||
|     return buildArgsString; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * | ||||
|    */ | ||||
|   public static cleanTagsArrayFunction( | ||||
|     dockerfileArrayArg: Dockerfile[], | ||||
|     trackingArrayArg: Dockerfile[] | ||||
|   ): string[] { | ||||
|     const cleanTagsArray: string[] = []; | ||||
|     dockerfileArrayArg.forEach(dockerfileArg => { | ||||
|       if (trackingArrayArg.indexOf(dockerfileArg) === -1) { | ||||
|         cleanTagsArray.push(dockerfileArg.cleanTag); | ||||
|       } | ||||
|     }); | ||||
|     return cleanTagsArray; | ||||
|   } | ||||
|  | ||||
|   // INSTANCE | ||||
|   public npmciDockerManagerRef: NpmciDockerManager; | ||||
|  | ||||
|   public filePath: string; | ||||
|   public repo: string; | ||||
|   public version: string; | ||||
|   public cleanTag: string; | ||||
|   public buildTag: string; | ||||
|   public pushTag: string; | ||||
|   public containerName: string; | ||||
|   public content: string; | ||||
|   public baseImage: string; | ||||
|   public localBaseImageDependent: boolean; | ||||
|   public localBaseDockerfile: Dockerfile; | ||||
|  | ||||
|   constructor( | ||||
|     dockerManagerRefArg: NpmciDockerManager, | ||||
|     options: { filePath?: string; fileContents?: string | Buffer; read?: boolean } | ||||
|   ) { | ||||
|     this.npmciDockerManagerRef = dockerManagerRefArg; | ||||
|     this.filePath = options.filePath; | ||||
|     this.repo = | ||||
|       this.npmciDockerManagerRef.npmciRef.npmciEnv.repo.user + | ||||
|       '/' + | ||||
|       this.npmciDockerManagerRef.npmciRef.npmciEnv.repo.repo; | ||||
|     this.version = Dockerfile.dockerFileVersion(plugins.path.parse(options.filePath).base); | ||||
|     this.cleanTag = this.repo + ':' + this.version; | ||||
|     this.buildTag = this.cleanTag; | ||||
|  | ||||
|     this.containerName = 'dockerfile-' + this.version; | ||||
|     if (options.filePath && options.read) { | ||||
|       this.content = plugins.smartfile.fs.toStringSync(plugins.path.resolve(options.filePath)); | ||||
|     } | ||||
|     this.baseImage = Dockerfile.dockerBaseImage(this.content); | ||||
|     this.localBaseImageDependent = false; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * builds the Dockerfile | ||||
|    */ | ||||
|   public async build() { | ||||
|     logger.log('info', 'now building Dockerfile for ' + this.cleanTag); | ||||
|     const buildArgsString = await Dockerfile.getDockerBuildArgs(this.npmciDockerManagerRef); | ||||
|     const buildCommand = `docker build --label="version=${ | ||||
|       this.npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().projectInfo.npm.version | ||||
|     }" -t ${this.buildTag} -f ${this.filePath} ${buildArgsString} .`; | ||||
|     await bash(buildCommand); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * pushes the Dockerfile to a registry | ||||
|    */ | ||||
|   public async push(dockerRegistryArg: DockerRegistry, versionSuffix: string = null) { | ||||
|     this.pushTag = Dockerfile.getDockerTagString( | ||||
|       this.npmciDockerManagerRef, | ||||
|       dockerRegistryArg.registryUrl, | ||||
|       this.repo, | ||||
|       this.version, | ||||
|       versionSuffix | ||||
|     ); | ||||
|     await bash(`docker tag ${this.buildTag} ${this.pushTag}`); | ||||
|     await bash(`docker push ${this.pushTag}`); | ||||
|     console.log('you can get the digest using this command'); | ||||
|     console.log(`docker inspect --format='{{index .RepoDigests 0}}' ${this.pushTag}`); | ||||
|     /* const imageDigest = (await bash( | ||||
|       `docker inspect --format='{{index .RepoDigests 0}}' ${pushTag}` | ||||
|     )).split('@')[1]; */ | ||||
|     await this.npmciDockerManagerRef.npmciRef.cloudlyConnector.announceDockerContainer({ | ||||
|       dockerImageUrl: this.pushTag, | ||||
|       dockerImageVersion: this.npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().projectInfo | ||||
|         .npm.version | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * pulls the Dockerfile from a registry | ||||
|    */ | ||||
|   public async pull(registryArg: DockerRegistry, versionSuffixArg: string = null) { | ||||
|     const pullTag = Dockerfile.getDockerTagString( | ||||
|       this.npmciDockerManagerRef, | ||||
|       registryArg.registryUrl, | ||||
|       this.repo, | ||||
|       this.version, | ||||
|       versionSuffixArg | ||||
|     ); | ||||
|     await bash(`docker pull ${pullTag}`); | ||||
|     await bash(`docker tag ${pullTag} ${this.buildTag}`); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * tests the Dockerfile; | ||||
|    */ | ||||
|   public async test() { | ||||
|     const testFile: string = plugins.path.join(paths.NpmciTestDir, 'test_' + this.version + '.sh'); | ||||
|     const testFileExists: boolean = plugins.smartfile.fs.fileExistsSync(testFile); | ||||
|     if (testFileExists) { | ||||
|       // run tests | ||||
|       await bash( | ||||
|         `docker run --name npmci_test_container --entrypoint="bash" ${this.buildTag} -c "mkdir /npmci_test"` | ||||
|       ); | ||||
|       await bash(`docker cp ${testFile} npmci_test_container:/npmci_test/test.sh`); | ||||
|       await bash(`docker commit npmci_test_container npmci_test_image`); | ||||
|       await bash(`docker run --entrypoint="bash" npmci_test_image -x /npmci_test/test.sh`); | ||||
|       await bash(`docker rm npmci_test_container`); | ||||
|       await bash(`docker rmi --force npmci_test_image`); | ||||
|     } else { | ||||
|       logger.log('warn', 'skipping tests for ' + this.cleanTag + ' because no testfile was found!'); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * gets the id of a Dockerfile | ||||
|    */ | ||||
|   public async getId() { | ||||
|     const containerId = await bash( | ||||
|       'docker inspect --type=image --format="{{.Id}}" ' + this.buildTag | ||||
|     ); | ||||
|     return containerId; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										5
									
								
								ts/manager.docker/mod.helpers.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								ts/manager.docker/mod.helpers.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
|  | ||||
| import { Dockerfile } from './mod.classes.dockerfile'; | ||||
							
								
								
									
										65
									
								
								ts/manager.git/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								ts/manager.git/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import { bash } from '../npmci.bash'; | ||||
| import { Npmci } from '../npmci.classes.npmci'; | ||||
|  | ||||
| export class NpmciGitManager { | ||||
|   public npmciRef: Npmci; | ||||
|  | ||||
|   constructor(npmciRefArg: Npmci) { | ||||
|     this.npmciRef = npmciRefArg; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * handle cli input | ||||
|    * @param argvArg | ||||
|    */ | ||||
|   public handleCli = async argvArg => { | ||||
|     if (argvArg._.length >= 2) { | ||||
|       const action: string = argvArg._[1]; | ||||
|       switch (action) { | ||||
|         case 'mirror': | ||||
|           await this.mirror(); | ||||
|           break; | ||||
|         default: | ||||
|           logger.log('error', `npmci git -> action >>${action}<< not supported!`); | ||||
|       } | ||||
|     } else { | ||||
|       logger.log('info', `npmci git -> cli arguments invalid! Please read the documentation.`); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   public mirror = async () => { | ||||
|     const githubToken = process.env.NPMCI_GIT_GITHUBTOKEN; | ||||
|     const githubUser = process.env.NPMCI_GIT_GITHUBGROUP || this.npmciRef.npmciEnv.repo.user; | ||||
|     const githubRepo = process.env.NPMCI_GIT_GITHUB || this.npmciRef.npmciEnv.repo; | ||||
|     if ( | ||||
|       this.npmciRef.npmciConfig.getConfig().projectInfo.npm.packageJson.private === true || | ||||
|       this.npmciRef.npmciConfig.getConfig().npmAccessLevel === 'private' | ||||
|     ) { | ||||
|       logger.log( | ||||
|         'warn', | ||||
|         `refusing to mirror due to private property use a private mirror location instead` | ||||
|       ); | ||||
|       return; | ||||
|     } | ||||
|     if (githubToken) { | ||||
|       logger.log('info', 'found github token.'); | ||||
|       logger.log('info', 'attempting the mirror the repository to GitHub'); | ||||
|  | ||||
|       // plugins.smartgit.GitRepo; | ||||
|  | ||||
|       // add the mirror | ||||
|       await bash( | ||||
|         `git remote add mirror https://${githubToken}@github.com/${githubUser}/${githubRepo}.git` | ||||
|       ); | ||||
|       await bash(`git push mirror --all`); | ||||
|       logger.log('ok', 'pushed all branches to mirror!'); | ||||
|       await bash(`git push mirror --tags`); | ||||
|       logger.log('ok', 'pushed all tags to mirror!'); | ||||
|     } else { | ||||
|       logger.log('error', `cannot find NPMCI_GIT_GITHUBTOKEN env var!`); | ||||
|       process.exit(1); | ||||
|     } | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										83
									
								
								ts/manager.nodejs/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								ts/manager.nodejs/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| import * as plugins from '../npmci.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
|  | ||||
| import { logger } from '../npmci.logging'; | ||||
| import { bash, bashNoError, nvmAvailable } from '../npmci.bash'; | ||||
| import { Npmci } from '../npmci.classes.npmci'; | ||||
|  | ||||
| export class NpmciNodeJsManager { | ||||
|   public npmciRef: Npmci; | ||||
|  | ||||
|   constructor(npmciRefArg: Npmci) { | ||||
|     this.npmciRef = npmciRefArg; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * handle cli input | ||||
|    * @param argvArg | ||||
|    */ | ||||
|   public async handleCli(argvArg) { | ||||
|     if (argvArg._.length >= 3) { | ||||
|       const action: string = argvArg._[1]; | ||||
|       switch (action) { | ||||
|         case 'install': | ||||
|           await this.install(argvArg._[2]); | ||||
|           break; | ||||
|         default: | ||||
|           logger.log('error', `>>npmci node ...<< action >>${action}<< not supported`); | ||||
|           process.exit(1); | ||||
|       } | ||||
|     } else { | ||||
|       logger.log( | ||||
|         'error', | ||||
|         `>>npmci node ...<< cli arguments invalid... Please read the documentation.` | ||||
|       ); | ||||
|       process.exit(1); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Install a specific version of node | ||||
|    * @param versionArg | ||||
|    */ | ||||
|   public async install(versionArg) { | ||||
|     logger.log('info', `now installing node version ${versionArg}`); | ||||
|     let version: string; | ||||
|     if (versionArg === 'stable') { | ||||
|       version = '12'; | ||||
|     } else if (versionArg === 'lts') { | ||||
|       version = '10'; | ||||
|     } else if (versionArg === 'legacy') { | ||||
|       version = '8'; | ||||
|     } else { | ||||
|       version = versionArg; | ||||
|     } | ||||
|     if (await nvmAvailable.promise) { | ||||
|       await bash(`nvm install ${version} && nvm alias default ${version}`); | ||||
|       logger.log('success', `Node version ${version} successfully installed!`); | ||||
|     } else { | ||||
|       logger.log('warn', 'Nvm not in path so staying at installed node version!'); | ||||
|     } | ||||
|     logger.log('info', 'now installing latest npm version'); | ||||
|     await bash('npm install -g npm'); | ||||
|     await bash('node -v'); | ||||
|     await bash('npm -v'); | ||||
|     await bash(`npm config set cache ${paths.NpmciCacheDir}  --global `); | ||||
|  | ||||
|     // lets look for further config | ||||
|     const config = await this.npmciRef.npmciConfig.getConfig(); | ||||
|     logger.log('info', 'Now checking for needed global npm tools...'); | ||||
|     for (const npmTool of config.npmGlobalTools) { | ||||
|       logger.log('info', `Checking for global "${npmTool}"`); | ||||
|       const whichOutput: string = await bashNoError(`which ${npmTool}`); | ||||
|       const toolAvailable: boolean = !(/not\sfound/.test(whichOutput) || whichOutput === ''); | ||||
|       if (toolAvailable) { | ||||
|         logger.log('info', `Tool ${npmTool} is available`); | ||||
|       } else { | ||||
|         logger.log('info', `globally installing ${npmTool} from npm`); | ||||
|         await bash(`npm install ${npmTool} -q -g`); | ||||
|       } | ||||
|     } | ||||
|     logger.log('success', 'all global npm tools specified in npmextra.json are now available!'); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										162
									
								
								ts/manager.npm/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								ts/manager.npm/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | ||||
| import * as plugins from './mod.plugins'; | ||||
|  | ||||
| import { logger } from '../npmci.logging'; | ||||
| import { bash, bashNoError, nvmAvailable } from '../npmci.bash'; | ||||
| import { Npmci } from '../npmci.classes.npmci'; | ||||
|  | ||||
| export class NpmciNpmManager { | ||||
|   public npmciRef: Npmci; | ||||
|  | ||||
|   constructor(npmciRefArg) { | ||||
|     this.npmciRef = npmciRefArg; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * handle cli input | ||||
|    * @param argvArg | ||||
|    */ | ||||
|   public async handleCli(argvArg) { | ||||
|     if (argvArg._.length >= 2) { | ||||
|       const action: string = argvArg._[1]; | ||||
|       switch (action) { | ||||
|         case 'install': | ||||
|           await this.install(); | ||||
|           break; | ||||
|         case 'prepare': | ||||
|           await this.prepare(); | ||||
|           break; | ||||
|         case 'test': | ||||
|           await this.test(); | ||||
|           break; | ||||
|         case 'publish': | ||||
|           await this.publish(); | ||||
|           break; | ||||
|         default: | ||||
|           logger.log('error', `>>npmci npm ...<< action >>${action}<< not supported`); | ||||
|           process.exit(1); | ||||
|       } | ||||
|     } else { | ||||
|       logger.log( | ||||
|         'info', | ||||
|         `>>npmci npm ...<< cli arguments invalid... Please read the documentation.` | ||||
|       ); | ||||
|       process.exit(1); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * authenticates npm with token from env var | ||||
|    */ | ||||
|   public async prepare() { | ||||
|     const config = this.npmciRef.npmciConfig.getConfig(); | ||||
|     let npmrcFileString: string = ''; | ||||
|     await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TOKEN_NPM*', npmEnvArg => { | ||||
|       const npmRegistryUrl = npmEnvArg.split('|')[0]; | ||||
|       const npmToken = npmEnvArg.split('|')[1]; | ||||
|       npmrcFileString += `//${npmRegistryUrl}/:_authToken="${plugins.smartstring.base64.decode( | ||||
|         npmToken | ||||
|       )}"\n`; | ||||
|     }); | ||||
|     logger.log('info', `setting default npm registry to ${config.npmRegistryUrl}`); | ||||
|     npmrcFileString += `registry=https://${config.npmRegistryUrl}\n`; | ||||
|  | ||||
|     // final check | ||||
|     if (npmrcFileString.length > 0) { | ||||
|       logger.log('info', 'found one or more access tokens'); | ||||
|     } else { | ||||
|       logger.log('error', 'no access token found! Exiting!'); | ||||
|       process.exit(1); | ||||
|     } | ||||
|  | ||||
|     // lets save it to disk | ||||
|     plugins.smartfile.memory.toFsSync(npmrcFileString, '/root/.npmrc'); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * publish a package to npm | ||||
|    */ | ||||
|   public async publish() { | ||||
|     const buildPublishCommand = async () => { | ||||
|       let npmAccessCliString = ``; | ||||
|       let npmRegistryCliString = ``; | ||||
|       let publishVerdaccioAsWell = false; | ||||
|       const config = this.npmciRef.npmciConfig.getConfig(); | ||||
|       const availableRegistries: string[] = []; | ||||
|       await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TOKEN_NPM*', npmEnvArg => { | ||||
|         availableRegistries.push(npmEnvArg.split('|')[0]); | ||||
|       }); | ||||
|  | ||||
|       // -> configure package access level | ||||
|       if (config.npmAccessLevel) { | ||||
|         npmAccessCliString = `--access=${config.npmAccessLevel}`; | ||||
|         if (config.npmAccessLevel === 'public') { | ||||
|           publishVerdaccioAsWell = true; | ||||
|         } | ||||
|       } else { | ||||
|         throw new Error('You need to set a npmAccessLevel!!!'); | ||||
|       } | ||||
|       // -> configure registry url | ||||
|       if (config.npmRegistryUrl) { | ||||
|         npmRegistryCliString = `--registry=https://${config.npmRegistryUrl}`; | ||||
|       } else { | ||||
|         logger.log('error', `no registry url specified. Can't publish!`); | ||||
|         process.exit(1); | ||||
|       } | ||||
|  | ||||
|       let publishCommand = `npm publish ${npmAccessCliString} ${npmRegistryCliString} `; | ||||
|  | ||||
|       // publishEverywhere | ||||
|       if (publishVerdaccioAsWell) { | ||||
|         const verdaccioRegistry = availableRegistries.find(registryString => | ||||
|           registryString.startsWith('verdaccio') | ||||
|         ); | ||||
|         if (verdaccioRegistry) { | ||||
|           logger.log( | ||||
|             'info', | ||||
|             `package is public and verdaccio registry is specified. Also publishing to Verdaccio!` | ||||
|           ); | ||||
|           publishCommand = `${publishCommand} && npm publish ${npmAccessCliString} --registry=https://${verdaccioRegistry}`; | ||||
|         } else { | ||||
|           logger.log( | ||||
|             'error', | ||||
|             `This package should also be published to Verdaccio, however there is no Verdaccio registry data available!` | ||||
|           ); | ||||
|         } | ||||
|       } | ||||
|       return publishCommand; | ||||
|     }; | ||||
|  | ||||
|     // -> preparing | ||||
|     logger.log('info', `now preparing environment:`); | ||||
|     this.prepare(); | ||||
|     await bash(`npm -v`); | ||||
|  | ||||
|     // -> build it | ||||
|     await bash(`npm install`); | ||||
|     await bash(`npm run build`); | ||||
|  | ||||
|     logger.log('success', `Nice!!! The build for the publication was successfull!`); | ||||
|     logger.log('info', `Lets clean up so we don't publish any packages that don't belong to us:`); | ||||
|     // -> clean up before we publish stuff | ||||
|     await bashNoError(`rm -r ./.npmci_cache`); | ||||
|     await bash(`rm -r ./node_modules`); | ||||
|  | ||||
|     logger.log('success', `Cleaned up!:`); | ||||
|  | ||||
|     // -> publish it | ||||
|     logger.log('info', `now invoking npm to publish the package!`); | ||||
|     await bash(await buildPublishCommand()); | ||||
|     logger.log('success', `Package was successfully published!`); | ||||
|   } | ||||
|  | ||||
|   public async install(): Promise<void> { | ||||
|     logger.log('info', 'now installing dependencies:'); | ||||
|     await bash('npm install'); | ||||
|   } | ||||
|  | ||||
|   public async test(): Promise<void> { | ||||
|     logger.log('info', 'now starting tests:'); | ||||
|     await bash('npm test'); | ||||
|   } | ||||
| } | ||||
| @@ -1,174 +0,0 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
| import { bash } from '../npmci.bash'; | ||||
|  | ||||
| import * as helpers from './mod.helpers'; | ||||
|  | ||||
| // classes | ||||
| import { Dockerfile } from './mod.classes.dockerfile'; | ||||
| import { DockerRegistry } from './mod.classes.dockerregistry'; | ||||
| import { RegistryStorage } from './mod.classes.registrystorage'; | ||||
|  | ||||
| // config | ||||
| import { configObject } from '../npmci.config'; | ||||
|  | ||||
| // instances | ||||
| const npmciRegistryStorage = new RegistryStorage(); | ||||
|  | ||||
| export { Dockerfile, helpers }; | ||||
|  | ||||
| export let modArgvArg; // will be set through the build command | ||||
|  | ||||
| /** | ||||
|  * handle cli input | ||||
|  * @param argvArg | ||||
|  */ | ||||
| export const handleCli = async argvArg => { | ||||
|   modArgvArg = argvArg; | ||||
|   if (argvArg._.length >= 2) { | ||||
|     const action: string = argvArg._[1]; | ||||
|     switch (action) { | ||||
|       case 'build': | ||||
|         await build(); | ||||
|         break; | ||||
|       case 'login': | ||||
|       case 'prepare': | ||||
|         await login(); | ||||
|         break; | ||||
|       case 'test': | ||||
|         await test(); | ||||
|         break; | ||||
|       case 'push': | ||||
|         await push(argvArg); | ||||
|         break; | ||||
|       case 'pull': | ||||
|         await pull(argvArg); | ||||
|         break; | ||||
|       default: | ||||
|         logger.log('error', `>>npmci docker ...<< action >>${action}<< not supported`); | ||||
|     } | ||||
|   } else { | ||||
|     logger.log( | ||||
|       'info', | ||||
|       `>>npmci docker ...<< cli arguments invalid... Please read the documentation.` | ||||
|     ); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * builds a cwd of Dockerfiles by triggering a promisechain | ||||
|  */ | ||||
| export const build = async () => { | ||||
|   await prepare(); | ||||
|   logger.log('info', 'now building Dockerfiles...'); | ||||
|   await helpers | ||||
|     .readDockerfiles() | ||||
|     .then(helpers.sortDockerfiles) | ||||
|     .then(helpers.mapDockerfiles) | ||||
|     .then(helpers.buildDockerfiles); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * login to the DockerRegistries | ||||
|  */ | ||||
| export const login = async () => { | ||||
|   await prepare(); | ||||
|   await npmciRegistryStorage.loginAll(); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * logs in docker | ||||
|  */ | ||||
| export const prepare = async () => { | ||||
|   // Always login to GitLab Registry | ||||
|   if (!process.env.CI_BUILD_TOKEN || process.env.CI_BUILD_TOKEN === '') { | ||||
|     logger.log('error', 'No registry token specified by gitlab!'); | ||||
|     process.exit(1); | ||||
|   } | ||||
|   npmciRegistryStorage.addRegistry( | ||||
|     new DockerRegistry({ | ||||
|       registryUrl: 'registry.gitlab.com', | ||||
|       username: 'gitlab-ci-token', | ||||
|       password: process.env.CI_BUILD_TOKEN | ||||
|     }) | ||||
|   ); | ||||
|  | ||||
|   // handle registries | ||||
|   await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_LOGIN_DOCKER*', async envString => { | ||||
|     npmciRegistryStorage.addRegistry(DockerRegistry.fromEnvString(envString)); | ||||
|   }); | ||||
|   return; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * pushes an image towards a registry | ||||
|  * @param argvArg | ||||
|  */ | ||||
| export const push = async argvArg => { | ||||
|   await prepare(); | ||||
|   let dockerRegistryUrls: string[] = []; | ||||
|  | ||||
|   // lets parse the input of cli and npmextra | ||||
|   if (argvArg._.length >= 3 && argvArg._[2] !== 'npmextra') { | ||||
|     dockerRegistryUrls.push(argvArg._[2]); | ||||
|   } else { | ||||
|     if (configObject.dockerRegistries.length === 0) { | ||||
|       logger.log( | ||||
|         'warn', | ||||
|         `There are no docker registries listed in npmextra.json! This is strange!` | ||||
|       ); | ||||
|     } | ||||
|     dockerRegistryUrls = dockerRegistryUrls.concat(configObject.dockerRegistries); | ||||
|   } | ||||
|  | ||||
|   // lets determine the suffix | ||||
|   let suffix = null; | ||||
|   if (argvArg._.length >= 4) { | ||||
|     suffix = argvArg._[3]; | ||||
|   } | ||||
|  | ||||
|   // lets push to the registries | ||||
|   for (const dockerRegistryUrl of dockerRegistryUrls) { | ||||
|     const dockerfileArray = await helpers | ||||
|       .readDockerfiles() | ||||
|       .then(helpers.sortDockerfiles) | ||||
|       .then(helpers.mapDockerfiles); | ||||
|     const dockerRegistryToPushTo = npmciRegistryStorage.getRegistryByUrl(dockerRegistryUrl); | ||||
|     if (!dockerRegistryToPushTo) { | ||||
|       logger.log( | ||||
|         'error', | ||||
|         `Cannot push to registry ${dockerRegistryUrl}, because it was not found in the authenticated registry list.` | ||||
|       ); | ||||
|       process.exit(1); | ||||
|     } | ||||
|     for (const dockerfile of dockerfileArray) { | ||||
|       await dockerfile.push(dockerRegistryToPushTo, suffix); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| export const pull = async argvArg => { | ||||
|   await prepare(); | ||||
|   const registryUrlArg = argvArg._[2]; | ||||
|   let suffix = null; | ||||
|   if (argvArg._.length >= 4) { | ||||
|     suffix = argvArg._[3]; | ||||
|   } | ||||
|   const localDockerRegistry = npmciRegistryStorage.getRegistryByUrl(registryUrlArg); | ||||
|   const dockerfileArray = await helpers | ||||
|     .readDockerfiles() | ||||
|     .then(helpers.sortDockerfiles) | ||||
|     .then(helpers.mapDockerfiles); | ||||
|   for (const dockerfile of dockerfileArray) { | ||||
|     await dockerfile.pull(localDockerRegistry, suffix); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * tests docker files | ||||
|  */ | ||||
| export const test = async () => { | ||||
|   await prepare(); | ||||
|   return await helpers.readDockerfiles().then(helpers.testDockerfiles); | ||||
| }; | ||||
| @@ -1,108 +0,0 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import * as NpmciEnv from '../npmci.env'; | ||||
| import { bash } from '../npmci.bash'; | ||||
| import * as paths from '../npmci.paths'; | ||||
|  | ||||
| import { DockerRegistry } from './mod.classes.dockerregistry'; | ||||
| import * as helpers from './mod.helpers'; | ||||
|  | ||||
| /** | ||||
|  * class Dockerfile represents a Dockerfile on disk in npmci | ||||
|  */ | ||||
| export class Dockerfile { | ||||
|   public filePath: string; | ||||
|   public repo: string; | ||||
|   public version: string; | ||||
|   public cleanTag: string; | ||||
|   public buildTag: string; | ||||
|   public containerName: string; | ||||
|   public content: string; | ||||
|   public baseImage: string; | ||||
|   public localBaseImageDependent: boolean; | ||||
|   public localBaseDockerfile: Dockerfile; | ||||
|   constructor(options: { filePath?: string; fileContents?: string | Buffer; read?: boolean }) { | ||||
|     this.filePath = options.filePath; | ||||
|     this.repo = NpmciEnv.repo.user + '/' + NpmciEnv.repo.repo; | ||||
|     this.version = helpers.dockerFileVersion(plugins.path.parse(options.filePath).base); | ||||
|     this.cleanTag = this.repo + ':' + this.version; | ||||
|     this.buildTag = this.cleanTag; | ||||
|  | ||||
|     this.containerName = 'dockerfile-' + this.version; | ||||
|     if (options.filePath && options.read) { | ||||
|       this.content = plugins.smartfile.fs.toStringSync(plugins.path.resolve(options.filePath)); | ||||
|     } | ||||
|     this.baseImage = helpers.dockerBaseImage(this.content); | ||||
|     this.localBaseImageDependent = false; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * builds the Dockerfile | ||||
|    */ | ||||
|   public async build() { | ||||
|     logger.log('info', 'now building Dockerfile for ' + this.cleanTag); | ||||
|     const buildArgsString = await helpers.getDockerBuildArgs(); | ||||
|     const buildCommand = `docker build -t ${this.buildTag} -f ${this.filePath} ${buildArgsString} .`; | ||||
|     await bash(buildCommand); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * pushes the Dockerfile to a registry | ||||
|    */ | ||||
|   public async push(dockerRegistryArg: DockerRegistry, versionSuffix: string = null) { | ||||
|     const pushTag = helpers.getDockerTagString( | ||||
|       dockerRegistryArg.registryUrl, | ||||
|       this.repo, | ||||
|       this.version, | ||||
|       versionSuffix | ||||
|     ); | ||||
|     await bash(`docker tag ${this.buildTag} ${pushTag}`); | ||||
|     await bash(`docker push ${pushTag}`); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * pulls the Dockerfile from a registry | ||||
|    */ | ||||
|   public async pull(registryArg: DockerRegistry, versionSuffixArg: string = null) { | ||||
|     const pullTag = helpers.getDockerTagString( | ||||
|       registryArg.registryUrl, | ||||
|       this.repo, | ||||
|       this.version, | ||||
|       versionSuffixArg | ||||
|     ); | ||||
|     await bash(`docker pull ${pullTag}`); | ||||
|     await bash(`docker tag ${pullTag} ${this.buildTag}`); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * tests the Dockerfile; | ||||
|    */ | ||||
|   public async test() { | ||||
|     const testFile: string = plugins.path.join(paths.NpmciTestDir, 'test_' + this.version + '.sh'); | ||||
|     const testFileExists: boolean = plugins.smartfile.fs.fileExistsSync(testFile); | ||||
|     if (testFileExists) { | ||||
|       // run tests | ||||
|       await bash( | ||||
|         `docker run --name npmci_test_container --entrypoint="bash" ${this.buildTag} -c "mkdir /npmci_test"` | ||||
|       ); | ||||
|       await bash(`docker cp ${testFile} npmci_test_container:/npmci_test/test.sh`); | ||||
|       await bash(`docker commit npmci_test_container npmci_test_image`); | ||||
|       await bash(`docker run --entrypoint="bash" npmci_test_image -x /npmci_test/test.sh`); | ||||
|       await bash(`docker rm npmci_test_container`); | ||||
|       await bash(`docker rmi --force npmci_test_image`); | ||||
|     } else { | ||||
|       logger.log('warn', 'skipping tests for ' + this.cleanTag + ' because no testfile was found!'); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * gets the id of a Dockerfile | ||||
|    */ | ||||
|   public async getId() { | ||||
|     const containerId = await bash( | ||||
|       'docker inspect --type=image --format="{{.Id}}" ' + this.buildTag | ||||
|     ); | ||||
|     return containerId; | ||||
|   } | ||||
| } | ||||
| @@ -1,187 +0,0 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
| import * as NpmciEnv from '../npmci.env'; | ||||
| import * as NpmciConfig from '../npmci.config'; | ||||
| import { bash } from '../npmci.bash'; | ||||
|  | ||||
| import { Dockerfile } from './mod.classes.dockerfile'; | ||||
|  | ||||
| /** | ||||
|  * creates instance of class Dockerfile for all Dockerfiles in cwd | ||||
|  * @returns Promise<Dockerfile[]> | ||||
|  */ | ||||
| export let readDockerfiles = async (): Promise<Dockerfile[]> => { | ||||
|   const fileTree = await plugins.smartfile.fs.listFileTree(paths.cwd, 'Dockerfile*'); | ||||
|  | ||||
|   // create the Dockerfile array | ||||
|   const readDockerfilesArray: Dockerfile[] = []; | ||||
|   logger.log('info', `found ${fileTree.length} Dockerfiles:`); | ||||
|   console.log(fileTree); | ||||
|   for (const dockerfilePath of fileTree) { | ||||
|     const myDockerfile = new Dockerfile({ | ||||
|       filePath: dockerfilePath, | ||||
|       read: true | ||||
|     }); | ||||
|     readDockerfilesArray.push(myDockerfile); | ||||
|   } | ||||
|  | ||||
|   return readDockerfilesArray; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * sorts Dockerfiles into a dependency chain | ||||
|  * @param sortableArrayArg an array of instances of class Dockerfile | ||||
|  * @returns Promise<Dockerfile[]> | ||||
|  */ | ||||
| export let sortDockerfiles = (sortableArrayArg: Dockerfile[]): Promise<Dockerfile[]> => { | ||||
|   const done = plugins.smartpromise.defer<Dockerfile[]>(); | ||||
|   logger.log('info', 'sorting Dockerfiles:'); | ||||
|   const sortedArray: Dockerfile[] = []; | ||||
|   const cleanTagsOriginal = cleanTagsArrayFunction(sortableArrayArg, sortedArray); | ||||
|   let sorterFunctionCounter: number = 0; | ||||
|   const sorterFunction = () => { | ||||
|     sortableArrayArg.forEach(dockerfileArg => { | ||||
|       const cleanTags = cleanTagsArrayFunction(sortableArrayArg, sortedArray); | ||||
|       if ( | ||||
|         cleanTags.indexOf(dockerfileArg.baseImage) === -1 && | ||||
|         sortedArray.indexOf(dockerfileArg) === -1 | ||||
|       ) { | ||||
|         sortedArray.push(dockerfileArg); | ||||
|       } | ||||
|       if (cleanTagsOriginal.indexOf(dockerfileArg.baseImage) !== -1) { | ||||
|         dockerfileArg.localBaseImageDependent = true; | ||||
|       } | ||||
|     }); | ||||
|     if (sortableArrayArg.length === sortedArray.length) { | ||||
|       let counter = 1; | ||||
|       for (const dockerfile of sortedArray) { | ||||
|         logger.log('info', `tag ${counter}: -> ${dockerfile.cleanTag}`); | ||||
|         counter++; | ||||
|       } | ||||
|       done.resolve(sortedArray); | ||||
|     } else if (sorterFunctionCounter < 10) { | ||||
|       sorterFunctionCounter++; | ||||
|       sorterFunction(); | ||||
|     } | ||||
|   }; | ||||
|   sorterFunction(); | ||||
|   return done.promise; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * maps local Dockerfiles dependencies to the correspoding Dockerfile class instances | ||||
|  */ | ||||
| export let mapDockerfiles = async (sortedArray: Dockerfile[]): Promise<Dockerfile[]> => { | ||||
|   sortedArray.forEach(dockerfileArg => { | ||||
|     if (dockerfileArg.localBaseImageDependent) { | ||||
|       sortedArray.forEach((dockfile2: Dockerfile) => { | ||||
|         if (dockfile2.cleanTag === dockerfileArg.baseImage) { | ||||
|           dockerfileArg.localBaseDockerfile = dockfile2; | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
|   }); | ||||
|   return sortedArray; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * builds the correspoding real docker image for each Dockerfile class instance | ||||
|  */ | ||||
| export let buildDockerfiles = async (sortedArrayArg: Dockerfile[]) => { | ||||
|   for (const dockerfileArg of sortedArrayArg) { | ||||
|     await dockerfileArg.build(); | ||||
|   } | ||||
|   return sortedArrayArg; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * tests all Dockerfiles in by calling class Dockerfile.test(); | ||||
|  * @param sortedArrayArg Dockerfile[] that contains all Dockerfiles in cwd | ||||
|  */ | ||||
| export let testDockerfiles = async (sortedArrayArg: Dockerfile[]) => { | ||||
|   for (const dockerfileArg of sortedArrayArg) { | ||||
|     await dockerfileArg.test(); | ||||
|   } | ||||
|   return sortedArrayArg; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * returns a version for a docker file | ||||
|  * @execution SYNC | ||||
|  */ | ||||
| export let dockerFileVersion = (dockerfileNameArg: string): string => { | ||||
|   let versionString: string; | ||||
|   const versionRegex = /Dockerfile_([a-zA-Z0-9\.]*)$/; | ||||
|   const regexResultArray = versionRegex.exec(dockerfileNameArg); | ||||
|   if (regexResultArray && regexResultArray.length === 2) { | ||||
|     versionString = regexResultArray[1]; | ||||
|   } else { | ||||
|     versionString = 'latest'; | ||||
|   } | ||||
|   return versionString; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * returns the docker base image for a Dockerfile | ||||
|  */ | ||||
| export let dockerBaseImage = (dockerfileContentArg: string) => { | ||||
|   const baseImageRegex = /FROM\s([a-zA-z0-9\/\-\:]*)\n?/; | ||||
|   const regexResultArray = baseImageRegex.exec(dockerfileContentArg); | ||||
|   return regexResultArray[1]; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * returns the docker tag | ||||
|  */ | ||||
| export let getDockerTagString = ( | ||||
|   registryArg: string, | ||||
|   repoArg: string, | ||||
|   versionArg: string, | ||||
|   suffixArg?: string | ||||
| ): string => { | ||||
|   // determine wether the repo should be mapped accordingly to the registry | ||||
|   const mappedRepo = NpmciConfig.configObject.dockerRegistryRepoMap[registryArg]; | ||||
|   const repo = (() => { | ||||
|     if (mappedRepo) { | ||||
|       return mappedRepo; | ||||
|     } else { | ||||
|       return repoArg; | ||||
|     } | ||||
|   })(); | ||||
|  | ||||
|   // determine wether the version contais a suffix | ||||
|   let version = versionArg; | ||||
|   if (suffixArg) { | ||||
|     version = versionArg + '_' + suffixArg; | ||||
|   } | ||||
|  | ||||
|   const tagString = `${registryArg}/${repo}:${version}`; | ||||
|   return tagString; | ||||
| }; | ||||
|  | ||||
| export let getDockerBuildArgs = async (): Promise<string> => { | ||||
|   logger.log('info', 'checking for env vars to be supplied to the docker build'); | ||||
|   let buildArgsString: string = ''; | ||||
|   for (const key in NpmciConfig.configObject.dockerBuildargEnvMap) { | ||||
|     const targetValue = process.env[NpmciConfig.configObject.dockerBuildargEnvMap[key]]; | ||||
|     buildArgsString = `${buildArgsString} --build-arg ${key}="${targetValue}"`; | ||||
|   } | ||||
|   return buildArgsString; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  */ | ||||
| export let cleanTagsArrayFunction = ( | ||||
|   dockerfileArrayArg: Dockerfile[], | ||||
|   trackingArrayArg: Dockerfile[] | ||||
| ): string[] => { | ||||
|   const cleanTagsArray: string[] = []; | ||||
|   dockerfileArrayArg.forEach(dockerfileArg => { | ||||
|     if (trackingArrayArg.indexOf(dockerfileArg) === -1) { | ||||
|       cleanTagsArray.push(dockerfileArg.cleanTag); | ||||
|     } | ||||
|   }); | ||||
|   return cleanTagsArray; | ||||
| }; | ||||
| @@ -1,59 +0,0 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import { bash } from '../npmci.bash'; | ||||
| import { repo } from '../npmci.env'; | ||||
|  | ||||
| import { configObject } from '../npmci.config'; | ||||
|  | ||||
| /** | ||||
|  * handle cli input | ||||
|  * @param argvArg | ||||
|  */ | ||||
| export let handleCli = async argvArg => { | ||||
|   if (argvArg._.length >= 2) { | ||||
|     const action: string = argvArg._[1]; | ||||
|     switch (action) { | ||||
|       case 'mirror': | ||||
|         await mirror(); | ||||
|         break; | ||||
|       default: | ||||
|         logger.log('error', `npmci git -> action >>${action}<< not supported!`); | ||||
|     } | ||||
|   } else { | ||||
|     logger.log('info', `npmci git -> cli arguments invalid! Please read the documentation.`); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| export let mirror = async () => { | ||||
|   const githubToken = process.env.NPMCI_GIT_GITHUBTOKEN; | ||||
|   const githubUser = process.env.NPMCI_GIT_GITHUBGROUP || repo.user; | ||||
|   const githubRepo = process.env.NPMCI_GIT_GITHUB || repo.repo; | ||||
|   if ( | ||||
|     configObject.projectInfo.npm.packageJson.private === true || | ||||
|     configObject.npmAccessLevel === 'private' | ||||
|   ) { | ||||
|     logger.log( | ||||
|       'warn', | ||||
|       `refusing to mirror due to private property use a private mirror location instead` | ||||
|     ); | ||||
|     return; | ||||
|   } | ||||
|   if (githubToken) { | ||||
|     logger.log('info', 'found github token.'); | ||||
|     logger.log('info', 'attempting the mirror the repository to GitHub'); | ||||
|  | ||||
|     // plugins.smartgit.GitRepo; | ||||
|  | ||||
|     // add the mirror | ||||
|     await bash( | ||||
|       `git remote add mirror https://${githubToken}@github.com/${githubUser}/${githubRepo}.git` | ||||
|     ); | ||||
|     await bash(`git push mirror --all`); | ||||
|     logger.log('ok', 'pushed all branches to mirror!'); | ||||
|     await bash(`git push mirror --tags`); | ||||
|     logger.log('ok', 'pushed all tags to mirror!'); | ||||
|   } else { | ||||
|     logger.log('error', `cannot find NPMCI_GIT_GITHUBTOKEN env var!`); | ||||
|     process.exit(1); | ||||
|   } | ||||
| }; | ||||
| @@ -1,72 +0,0 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from '../npmci.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
| import * as npmciConfig from '../npmci.config'; | ||||
| import { bash, bashNoError, nvmAvailable } from '../npmci.bash'; | ||||
|  | ||||
| /** | ||||
|  * handle cli input | ||||
|  * @param argvArg | ||||
|  */ | ||||
| export let handleCli = async argvArg => { | ||||
|   if (argvArg._.length >= 3) { | ||||
|     const action: string = argvArg._[1]; | ||||
|     switch (action) { | ||||
|       case 'install': | ||||
|         await install(argvArg._[2]); | ||||
|         break; | ||||
|       default: | ||||
|         logger.log('error', `>>npmci node ...<< action >>${action}<< not supported`); | ||||
|         process.exit(1); | ||||
|     } | ||||
|   } else { | ||||
|     logger.log( | ||||
|       'error', | ||||
|       `>>npmci node ...<< cli arguments invalid... Please read the documentation.` | ||||
|     ); | ||||
|     process.exit(1); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Install a specific version of node | ||||
|  * @param versionArg | ||||
|  */ | ||||
| export let install = async versionArg => { | ||||
|   logger.log('info', `now installing node version ${versionArg}`); | ||||
|   let version: string; | ||||
|   if (versionArg === 'stable') { | ||||
|     version = '12'; | ||||
|   } else if (versionArg === 'lts') { | ||||
|     version = '10'; | ||||
|   } else if (versionArg === 'legacy') { | ||||
|     version = '8'; | ||||
|   } else { | ||||
|     version = versionArg; | ||||
|   } | ||||
|   if (await nvmAvailable.promise) { | ||||
|     await bash(`nvm install ${version} && nvm alias default ${version}`); | ||||
|     logger.log('success', `Node version ${version} successfully installed!`); | ||||
|   } else { | ||||
|     logger.log('warn', 'Nvm not in path so staying at installed node version!'); | ||||
|   } | ||||
|   await bash('node -v'); | ||||
|   await bash('npm -v'); | ||||
|   await bash(`npm config set cache ${paths.NpmciCacheDir}  --global `); | ||||
|   // lets look for further config | ||||
|   await npmciConfig.getConfig().then(async configArg => { | ||||
|     logger.log('info', 'Now checking for needed global npm tools...'); | ||||
|     for (const npmTool of configArg.npmGlobalTools) { | ||||
|       logger.log('info', `Checking for global "${npmTool}"`); | ||||
|       const whichOutput: string = await bashNoError(`which ${npmTool}`); | ||||
|       const toolAvailable: boolean = !(/not\sfound/.test(whichOutput) || whichOutput === ''); | ||||
|       if (toolAvailable) { | ||||
|         logger.log('info', `Tool ${npmTool} is available`); | ||||
|       } else { | ||||
|         logger.log('info', `globally installing ${npmTool} from npm`); | ||||
|         await bash(`npm install ${npmTool} -q -g`); | ||||
|       } | ||||
|     } | ||||
|     logger.log('success', 'all global npm tools specified in npmextra.json are now available!'); | ||||
|   }); | ||||
| }; | ||||
| @@ -1,150 +0,0 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import * as configModule from '../npmci.config'; | ||||
| import { bash, bashNoError, nvmAvailable } from '../npmci.bash'; | ||||
|  | ||||
| /** | ||||
|  * handle cli input | ||||
|  * @param argvArg | ||||
|  */ | ||||
| export let handleCli = async argvArg => { | ||||
|   if (argvArg._.length >= 2) { | ||||
|     const action: string = argvArg._[1]; | ||||
|     switch (action) { | ||||
|       case 'install': | ||||
|         await install(); | ||||
|         break; | ||||
|       case 'prepare': | ||||
|         await prepare(); | ||||
|         break; | ||||
|       case 'test': | ||||
|         await test(); | ||||
|         break; | ||||
|       case 'publish': | ||||
|         await publish(); | ||||
|         break; | ||||
|       default: | ||||
|         logger.log('error', `>>npmci npm ...<< action >>${action}<< not supported`); | ||||
|         process.exit(1); | ||||
|     } | ||||
|   } else { | ||||
|     logger.log('info', `>>npmci npm ...<< cli arguments invalid... Please read the documentation.`); | ||||
|     process.exit(1); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * authenticates npm with token from env var | ||||
|  */ | ||||
| const prepare = async () => { | ||||
|   const config = await configModule.getConfig(); | ||||
|   let npmrcFileString: string = ''; | ||||
|   await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TOKEN_NPM*', npmEnvArg => { | ||||
|     const npmRegistryUrl = npmEnvArg.split('|')[0]; | ||||
|     const npmToken = npmEnvArg.split('|')[1]; | ||||
|     npmrcFileString += `//${npmRegistryUrl}/:_authToken="${plugins.smartstring.base64.decode( | ||||
|       npmToken | ||||
|     )}"\n`; | ||||
|   }); | ||||
|   logger.log('info', `setting default npm registry to ${config.npmRegistryUrl}`); | ||||
|   npmrcFileString += `registry=https://${config.npmRegistryUrl}\n`; | ||||
|  | ||||
|   // final check | ||||
|   if (npmrcFileString.length > 0) { | ||||
|     logger.log('info', 'found one or more access tokens'); | ||||
|   } else { | ||||
|     logger.log('error', 'no access token found! Exiting!'); | ||||
|     process.exit(1); | ||||
|   } | ||||
|  | ||||
|   // lets save it to disk | ||||
|   plugins.smartfile.memory.toFsSync(npmrcFileString, '/root/.npmrc'); | ||||
|   return; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * publish a package to npm | ||||
|  */ | ||||
| const publish = async () => { | ||||
|   const buildPublishCommand = async () => { | ||||
|     let npmAccessCliString = ``; | ||||
|     let npmRegistryCliString = ``; | ||||
|     let publishVerdaccioAsWell = false; | ||||
|     const config = await configModule.getConfig(); | ||||
|     const availableRegistries: string[] = []; | ||||
|     await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TOKEN_NPM*', npmEnvArg => { | ||||
|       availableRegistries.push(npmEnvArg.split('|')[0]); | ||||
|     }); | ||||
|  | ||||
|     // -> configure package access level | ||||
|     if (config.npmAccessLevel) { | ||||
|       npmAccessCliString = `--access=${config.npmAccessLevel}`; | ||||
|       if (config.npmAccessLevel === 'public') { | ||||
|         publishVerdaccioAsWell = true; | ||||
|       } | ||||
|     } else { | ||||
|       throw new Error('You need to set a npmAccessLevel!!!'); | ||||
|     } | ||||
|     // -> configure registry url | ||||
|     if (config.npmRegistryUrl) { | ||||
|       npmRegistryCliString = `--registry=https://${config.npmRegistryUrl}`; | ||||
|     } else { | ||||
|       logger.log('error', `no registry url specified. Can't publish!`); | ||||
|       process.exit(1); | ||||
|     } | ||||
|  | ||||
|     let publishCommand = `npm publish ${npmAccessCliString} ${npmRegistryCliString} `; | ||||
|  | ||||
|     // publishEverywhere | ||||
|     if (publishVerdaccioAsWell) { | ||||
|       const verdaccioRegistry = availableRegistries.find(registryString => | ||||
|         registryString.startsWith('verdaccio') | ||||
|       ); | ||||
|       if (verdaccioRegistry) { | ||||
|         logger.log( | ||||
|           'info', | ||||
|           `package is public and verdaccio registry is specified. Also publishing to Verdaccio!` | ||||
|         ); | ||||
|         publishCommand = `${publishCommand} && npm publish ${npmAccessCliString} --registry=https://${verdaccioRegistry}`; | ||||
|       } else { | ||||
|         logger.log( | ||||
|           'error', | ||||
|           `This package should also be published to Verdaccio, however there is no Verdaccio registry data available!` | ||||
|         ); | ||||
|       } | ||||
|     } | ||||
|     return publishCommand; | ||||
|   }; | ||||
|  | ||||
|   // -> preparing | ||||
|   logger.log('info', `now preparing environment:`); | ||||
|   prepare(); | ||||
|   await bash(`npm -v`); | ||||
|  | ||||
|   // -> build it | ||||
|   await bash(`npm install`); | ||||
|   await bash(`npm run build`); | ||||
|  | ||||
|   logger.log('success', `Nice!!! The build for the publication was successfull!`); | ||||
|   logger.log('info', `Lets clean up so we don't publish any packages that don't belong to us:`); | ||||
|   // -> clean up before we publish stuff | ||||
|   await bashNoError(`rm -r ./.npmci_cache`); | ||||
|   await bash(`rm -r ./node_modules`); | ||||
|  | ||||
|   logger.log('success', `Cleaned up!:`); | ||||
|  | ||||
|   // -> publish it | ||||
|   logger.log('info', `now invoking npm to publish the package!`); | ||||
|   await bash(await buildPublishCommand()); | ||||
|   logger.log('success', `Package was successfully published!`); | ||||
| }; | ||||
|  | ||||
| const install = async (): Promise<void> => { | ||||
|   logger.log('info', 'now installing dependencies:'); | ||||
|   await bash('npm install'); | ||||
| }; | ||||
|  | ||||
| export let test = async (): Promise<void> => { | ||||
|   logger.log('info', 'now starting tests:'); | ||||
|   await bash('npm test'); | ||||
| }; | ||||
							
								
								
									
										55
									
								
								ts/npmci.classes.npmci.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								ts/npmci.classes.npmci.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
|  | ||||
| import { CloudlyConnector } from './connector.cloudly/cloudlyconnector'; | ||||
|  | ||||
| import { NpmciInfo } from './npmci.classes.npmciinfo'; | ||||
| import { NpmciCli } from './npmci.classes.npmcicli'; | ||||
| import { NpmciConfig } from './npmci.classes.npmciconfig'; | ||||
|  | ||||
| // mods | ||||
| import { NpmciDockerManager } from './manager.docker'; | ||||
| import { NpmciGitManager } from './manager.git'; | ||||
| import { NpmciNodeJsManager } from './manager.nodejs'; | ||||
| import { NpmciNpmManager } from './manager.npm'; | ||||
| import { NpmciEnv } from './npmci.classes.npmcienv'; | ||||
|  | ||||
| export class Npmci { | ||||
|   public analytics: plugins.smartanalytics.Analytics; | ||||
|   public cloudlyConnector: CloudlyConnector; | ||||
|  | ||||
|   public npmciEnv: NpmciEnv; | ||||
|   public npmciInfo: NpmciInfo; | ||||
|   public npmciConfig: NpmciConfig; | ||||
|   public npmciCli: NpmciCli; | ||||
|  | ||||
|   // managers | ||||
|   public dockerManager: NpmciDockerManager; | ||||
|   public gitManager: NpmciGitManager; | ||||
|   public nodejsManager: NpmciNodeJsManager; | ||||
|   public npmManager: NpmciNpmManager; | ||||
|  | ||||
|   constructor() { | ||||
|     this.analytics = new plugins.smartanalytics.Analytics({ | ||||
|       apiEndPoint: 'https://pubapi.lossless.one/analytics', | ||||
|       projectId: 'gitzone', | ||||
|       appName: 'npmci' | ||||
|     }); | ||||
|     this.cloudlyConnector = new CloudlyConnector(this); | ||||
|     this.npmciEnv = new NpmciEnv(this); | ||||
|     this.npmciInfo = new NpmciInfo(this); | ||||
|     this.npmciCli = new NpmciCli(this); | ||||
|     this.npmciConfig = new NpmciConfig(this); | ||||
|  | ||||
|     // managers | ||||
|     this.dockerManager = new NpmciDockerManager(this); | ||||
|     this.gitManager = new NpmciGitManager(this); | ||||
|     this.nodejsManager = new NpmciNodeJsManager(this); | ||||
|     this.npmManager = new NpmciNpmManager(this); | ||||
|   } | ||||
|  | ||||
|   public async start() { | ||||
|     await this.npmciInfo.printToConsole(); | ||||
|     await this.npmciConfig.init(); | ||||
|     this.npmciCli.startParse(); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										110
									
								
								ts/npmci.classes.npmcicli.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								ts/npmci.classes.npmcicli.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | ||||
| import { logger } from './npmci.logging'; | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as paths from './npmci.paths'; | ||||
| import { Npmci } from './npmci.classes.npmci'; | ||||
|  | ||||
| export class NpmciCli { | ||||
|   public npmciRef: Npmci; | ||||
|   public smartcli: plugins.smartcli.Smartcli; | ||||
|  | ||||
|   constructor(npmciArg: Npmci) { | ||||
|     this.npmciRef = npmciArg; | ||||
|     this.smartcli = new plugins.smartcli.Smartcli(); | ||||
|     this.smartcli.addVersion(this.npmciRef.npmciInfo.projectInfo.version); | ||||
|  | ||||
|     // clean | ||||
|     this.smartcli.addCommand('clean').subscribe( | ||||
|       async argv => { | ||||
|         const modClean = await import('./mod_clean/index'); | ||||
|         await modClean.clean(); | ||||
|       }, | ||||
|       err => { | ||||
|         console.log(err); | ||||
|         process.exit(1); | ||||
|       } | ||||
|     ); | ||||
|  | ||||
|     // command | ||||
|     this.smartcli.addCommand('command').subscribe( | ||||
|       async argv => { | ||||
|         const modCommand = await import('./mod_command/index'); | ||||
|         await modCommand.command(); | ||||
|       }, | ||||
|       err => { | ||||
|         console.log(err); | ||||
|         process.exit(1); | ||||
|       } | ||||
|     ); | ||||
|  | ||||
|     // command | ||||
|     this.smartcli.addCommand('git').subscribe( | ||||
|       async argvArg => { | ||||
|         await this.npmciRef.gitManager.handleCli(argvArg); | ||||
|       }, | ||||
|       err => { | ||||
|         console.log(err); | ||||
|         process.exit(1); | ||||
|       } | ||||
|     ); | ||||
|  | ||||
|     // build | ||||
|     this.smartcli.addCommand('docker').subscribe( | ||||
|       async argvArg => { | ||||
|         await this.npmciRef.dockerManager.handleCli(argvArg); | ||||
|       }, | ||||
|       err => { | ||||
|         console.log(err); | ||||
|         process.exit(1); | ||||
|       } | ||||
|     ); | ||||
|  | ||||
|     // node | ||||
|     this.smartcli.addCommand('node').subscribe( | ||||
|       async argvArg => { | ||||
|         await this.npmciRef.nodejsManager.handleCli(argvArg); | ||||
|       }, | ||||
|       err => { | ||||
|         console.log(err); | ||||
|         process.exit(1); | ||||
|       } | ||||
|     ); | ||||
|  | ||||
|     // npm | ||||
|     this.smartcli.addCommand('npm').subscribe( | ||||
|       async argvArg => { | ||||
|         await this.npmciRef.npmManager.handleCli(argvArg); | ||||
|       }, | ||||
|       err => { | ||||
|         console.log(err); | ||||
|       } | ||||
|     ); | ||||
|  | ||||
|     // trigger | ||||
|     this.smartcli.addCommand('ssh').subscribe( | ||||
|       async argvArg => { | ||||
|         const modSsh = await import('./mod_ssh/index'); | ||||
|         await modSsh.handleCli(argvArg); | ||||
|       }, | ||||
|       err => { | ||||
|         console.log(err); | ||||
|         process.exit(1); | ||||
|       } | ||||
|     ); | ||||
|  | ||||
|     // trigger | ||||
|     this.smartcli.addCommand('trigger').subscribe( | ||||
|       async argv => { | ||||
|         const modTrigger = await import('./mod_trigger/index'); | ||||
|         await modTrigger.trigger(); | ||||
|       }, | ||||
|       err => { | ||||
|         console.log(err); | ||||
|         process.exit(1); | ||||
|       } | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   public startParse = () => { | ||||
|     this.smartcli.startParse(); | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										73
									
								
								ts/npmci.classes.npmciconfig.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								ts/npmci.classes.npmciconfig.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as paths from './npmci.paths'; | ||||
|  | ||||
| import { logger } from './npmci.logging'; | ||||
| import { Npmci } from './npmci.classes.npmci'; | ||||
|  | ||||
| /** | ||||
|  * the main config interface for npmci | ||||
|  */ | ||||
| export interface INpmciOptions { | ||||
|   projectInfo: plugins.projectinfo.ProjectInfo; | ||||
|  | ||||
|   // npm | ||||
|   npmGlobalTools: string[]; | ||||
|   npmAccessLevel?: 'private' | 'public'; | ||||
|   npmRegistryUrl: string; | ||||
|  | ||||
|   // docker | ||||
|   dockerRegistries: string[]; | ||||
|   dockerRegistryRepoMap: { [key: string]: string }; | ||||
|   dockerBuildargEnvMap: { [key: string]: string }; | ||||
|  | ||||
|   // urls | ||||
|   urlCloudly: string; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * a config class for Npmci | ||||
|  */ | ||||
| export class NpmciConfig { | ||||
|   public npmciRef: Npmci; | ||||
|  | ||||
|   public npmciNpmextra: plugins.npmextra.Npmextra; | ||||
|   public kvStorage: plugins.npmextra.KeyValueStore; | ||||
|   public npmciQenv: plugins.qenv.Qenv; | ||||
|  | ||||
|   private configObject: INpmciOptions; | ||||
|  | ||||
|   constructor(npmciRefArg: Npmci) { | ||||
|     this.npmciRef = npmciRefArg; | ||||
|  | ||||
|     this.npmciNpmextra = new plugins.npmextra.Npmextra(paths.cwd); | ||||
|     this.kvStorage = new plugins.npmextra.KeyValueStore( | ||||
|       'custom', | ||||
|       `${this.npmciRef.npmciEnv.repo.user}_${this.npmciRef.npmciEnv.repo.repo}` | ||||
|     ); | ||||
|     this.npmciQenv = new plugins.qenv.Qenv( | ||||
|       paths.NpmciProjectDir, | ||||
|       paths.NpmciProjectNogitDir, | ||||
|       false, | ||||
|       logger | ||||
|     ); | ||||
|  | ||||
|     this.configObject = { | ||||
|       projectInfo: new plugins.projectinfo.ProjectInfo(paths.cwd), | ||||
|       npmGlobalTools: [], | ||||
|       dockerRegistries: [], | ||||
|       dockerRegistryRepoMap: {}, | ||||
|       npmAccessLevel: 'private', | ||||
|       npmRegistryUrl: 'registry.npmjs.org', | ||||
|       dockerBuildargEnvMap: {}, | ||||
|       urlCloudly: this.npmciQenv.getEnvVarOnDemand('NPMCI_URL_CLOUDLY') | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   public async init() { | ||||
|     this.configObject = this.npmciNpmextra.dataFor<INpmciOptions>('npmci', this.configObject); | ||||
|   } | ||||
|  | ||||
|   public getConfig(): INpmciOptions { | ||||
|     return this.configObject; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										18
									
								
								ts/npmci.classes.npmcienv.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								ts/npmci.classes.npmcienv.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import { Npmci } from './npmci.classes.npmci'; | ||||
|  | ||||
| export class NpmciEnv { | ||||
|   public npmciRef: Npmci; | ||||
|  | ||||
|   public repoString: string; | ||||
|   public repo: plugins.smartstring.GitRepo; | ||||
|  | ||||
|   constructor(npmciRefArg: Npmci) { | ||||
|     this.npmciRef = npmciRefArg; | ||||
|     this.repoString = process.env.CI_REPOSITORY_URL; | ||||
|     if (!this.repoString) { | ||||
|       this.repoString = 'https://undefined:undefined@github.com/undefined/undefined.git'; | ||||
|     } | ||||
|     this.repo = new plugins.smartstring.GitRepo(this.repoString); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										17
									
								
								ts/npmci.classes.npmciinfo.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								ts/npmci.classes.npmciinfo.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as paths from './npmci.paths'; | ||||
| import { logger } from './npmci.logging'; | ||||
| import { Npmci } from './npmci.classes.npmci'; | ||||
|  | ||||
| export class NpmciInfo { | ||||
|   public npmciRef: Npmci; | ||||
|   public projectInfo = new plugins.projectinfo.ProjectinfoNpm(paths.NpmciPackageRoot); | ||||
|  | ||||
|   constructor(npmciArg: Npmci) { | ||||
|     this.npmciRef = npmciArg; | ||||
|   } | ||||
|  | ||||
|   public printToConsole() { | ||||
|     logger.log('info', `npmci version: ${this.projectInfo.version}`); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										111
									
								
								ts/npmci.cli.ts
									
									
									
									
									
								
							
							
						
						
									
										111
									
								
								ts/npmci.cli.ts
									
									
									
									
									
								
							| @@ -1,111 +0,0 @@ | ||||
| import { logger } from './npmci.logging'; | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as paths from './npmci.paths'; | ||||
| import * as npmciMonitor from './npmci.monitor'; | ||||
| npmciMonitor.run(); | ||||
|  | ||||
| // Get Info about npmci itself | ||||
| const npmciInfo = new plugins.projectinfo.ProjectinfoNpm(paths.NpmciPackageRoot); | ||||
| logger.log('info', 'npmci version: ' + npmciInfo.version); | ||||
|  | ||||
| import * as NpmciEnv from './npmci.env'; | ||||
|  | ||||
| const npmciSmartcli = new plugins.smartcli.Smartcli(); | ||||
| npmciSmartcli.addVersion(npmciInfo.version); | ||||
|  | ||||
| // clean | ||||
| npmciSmartcli.addCommand('clean').subscribe( | ||||
|   async argv => { | ||||
|     const modClean = await import('./mod_clean/index'); | ||||
|     await modClean.clean(); | ||||
|   }, | ||||
|   err => { | ||||
|     console.log(err); | ||||
|     process.exit(1); | ||||
|   } | ||||
| ); | ||||
|  | ||||
| // command | ||||
| npmciSmartcli.addCommand('command').subscribe( | ||||
|   async argv => { | ||||
|     const modCommand = await import('./mod_command/index'); | ||||
|     await modCommand.command(); | ||||
|   }, | ||||
|   err => { | ||||
|     console.log(err); | ||||
|     process.exit(1); | ||||
|   } | ||||
| ); | ||||
|  | ||||
| // command | ||||
| npmciSmartcli.addCommand('git').subscribe( | ||||
|   async argvArg => { | ||||
|     const modGit = await import('./mod_git/index'); | ||||
|     await modGit.handleCli(argvArg); | ||||
|   }, | ||||
|   err => { | ||||
|     console.log(err); | ||||
|     process.exit(1); | ||||
|   } | ||||
| ); | ||||
|  | ||||
| // build | ||||
| npmciSmartcli.addCommand('docker').subscribe( | ||||
|   async argvArg => { | ||||
|     const modDocker = await import('./mod_docker/index'); | ||||
|     await modDocker.handleCli(argvArg); | ||||
|   }, | ||||
|   err => { | ||||
|     console.log(err); | ||||
|     process.exit(1); | ||||
|   } | ||||
| ); | ||||
|  | ||||
| // node | ||||
| npmciSmartcli.addCommand('node').subscribe( | ||||
|   async argvArg => { | ||||
|     const modNode = await import('./mod_node/index'); | ||||
|     await modNode.handleCli(argvArg); | ||||
|   }, | ||||
|   err => { | ||||
|     console.log(err); | ||||
|     process.exit(1); | ||||
|   } | ||||
| ); | ||||
|  | ||||
| // npm | ||||
| npmciSmartcli.addCommand('npm').subscribe( | ||||
|   async argvArg => { | ||||
|     const modNpm = await import('./mod_npm/index'); | ||||
|     await modNpm.handleCli(argvArg); | ||||
|   }, | ||||
|   err => { | ||||
|     console.log(err); | ||||
|   } | ||||
| ); | ||||
|  | ||||
| // trigger | ||||
| npmciSmartcli.addCommand('ssh').subscribe( | ||||
|   async argvArg => { | ||||
|     const modSsh = await import('./mod_ssh/index'); | ||||
|     await modSsh.handleCli(argvArg); | ||||
|   }, | ||||
|   err => { | ||||
|     console.log(err); | ||||
|     process.exit(1); | ||||
|   } | ||||
| ); | ||||
|  | ||||
| // trigger | ||||
| npmciSmartcli.addCommand('trigger').subscribe( | ||||
|   async argv => { | ||||
|     const modTrigger = await import('./mod_trigger/index'); | ||||
|     await modTrigger.trigger(); | ||||
|   }, | ||||
|   err => { | ||||
|     console.log(err); | ||||
|     process.exit(1); | ||||
|   } | ||||
| ); | ||||
|  | ||||
| npmciSmartcli.startParse(); | ||||
| @@ -1,46 +0,0 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as paths from './npmci.paths'; | ||||
|  | ||||
| import { repo } from './npmci.env'; | ||||
|  | ||||
| import { KeyValueStore } from '@pushrocks/npmextra'; | ||||
|  | ||||
| /** | ||||
|  * the main config interface for npmci | ||||
|  */ | ||||
| export interface INpmciOptions { | ||||
|   projectInfo: plugins.projectinfo.ProjectInfo; | ||||
|  | ||||
|   // npm | ||||
|   npmGlobalTools: string[]; | ||||
|   npmAccessLevel?: 'private' | 'public'; | ||||
|   npmRegistryUrl: string; | ||||
|  | ||||
|   // docker | ||||
|   dockerRegistries: string[]; | ||||
|   dockerRegistryRepoMap: { [key: string]: string }; | ||||
|   dockerBuildargEnvMap: { [key: string]: string }; | ||||
| } | ||||
|  | ||||
| // instantiate a kvStorage for the current directory | ||||
| export let kvStorage = new KeyValueStore('custom', `${repo.user}_${repo.repo}`); | ||||
|  | ||||
| // handle config retrival | ||||
| const npmciNpmextra = new plugins.npmextra.Npmextra(paths.cwd); | ||||
| const defaultConfig: INpmciOptions = { | ||||
|   projectInfo: new plugins.projectinfo.ProjectInfo(paths.cwd), | ||||
|   npmGlobalTools: [], | ||||
|   dockerRegistries: [], | ||||
|   dockerRegistryRepoMap: {}, | ||||
|   npmAccessLevel: 'private', | ||||
|   npmRegistryUrl: 'registry.npmjs.org', | ||||
|   dockerBuildargEnvMap: {} | ||||
| }; | ||||
| export let configObject = npmciNpmextra.dataFor<INpmciOptions>('npmci', defaultConfig); | ||||
|  | ||||
| /** | ||||
|  * gets the npmci portion of the npmextra.json file | ||||
|  */ | ||||
| export let getConfig = async (): Promise<INpmciOptions> => { | ||||
|   return configObject; | ||||
| }; | ||||
| @@ -1,13 +0,0 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as paths from './npmci.paths'; | ||||
| import { GitRepo } from '@pushrocks/smartstring'; | ||||
| import { Dockerfile } from './mod_docker/index'; | ||||
|  | ||||
| /** | ||||
|  * a info instance about the git respoitory at cwd :) | ||||
|  */ | ||||
| let repoString: string = process.env.CI_REPOSITORY_URL; | ||||
| if (!repoString) { | ||||
|   repoString = 'https://undefined:undefined@github.com/undefined/undefined.git'; | ||||
| } | ||||
| export let repo = new GitRepo(repoString); | ||||
| @@ -1,23 +0,0 @@ | ||||
| import { logger } from './npmci.logging'; | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as env from './npmci.env'; | ||||
|  | ||||
| import { Analytics } from '@pushrocks/smartanalytics'; | ||||
|  | ||||
| export let npmciAnalytics = new Analytics({ | ||||
|   apiEndPoint: 'https://pubapi.lossless.one/analytics', | ||||
|   projectId: 'gitzone', | ||||
|   appName: 'npmci' | ||||
| }); | ||||
|  | ||||
| export let run = async () => { | ||||
|   npmciAnalytics | ||||
|     .recordEvent('npmToolExecution', { | ||||
|       host: env.repo.host, | ||||
|       user: env.repo.user, | ||||
|       repo: env.repo.repo | ||||
|     }) | ||||
|     .catch(err => { | ||||
|       logger.log('warn', 'Lossless Analytics API not available...'); | ||||
|     }); | ||||
| }; | ||||
| @@ -1,9 +1,13 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
|  | ||||
| export let cwd = process.cwd(); | ||||
| export const cwd = process.cwd(); | ||||
|  | ||||
| export let NpmciPackageRoot = plugins.path.join(__dirname, '../'); | ||||
| export let NpmciPackageConfig = plugins.path.join(NpmciPackageRoot, './config.json'); | ||||
| export let NpmciProjectDir = cwd; | ||||
| export let NpmciTestDir = plugins.path.join(cwd, './test'); | ||||
| export let NpmciCacheDir = plugins.path.join(cwd, './.npmci_cache'); | ||||
| // package paths | ||||
| export const NpmciPackageRoot = plugins.path.join(__dirname, '../'); | ||||
| export const NpmciPackageConfig = plugins.path.join(NpmciPackageRoot, './config.json'); | ||||
|  | ||||
| // project paths | ||||
| export const NpmciProjectDir = cwd; | ||||
| export const NpmciProjectNogitDir = plugins.path.join(NpmciProjectDir, './.nogit'); | ||||
| export const NpmciTestDir = plugins.path.join(cwd, './test'); | ||||
| export const NpmciCacheDir = plugins.path.join(cwd, './.npmci_cache'); | ||||
|   | ||||
| @@ -3,9 +3,23 @@ import * as path from 'path'; | ||||
|  | ||||
| export { path }; | ||||
|  | ||||
| // @apiglobal | ||||
| import * as typedrequest from '@apiglobal/typedrequest'; | ||||
|  | ||||
| export { | ||||
|   typedrequest | ||||
| }; | ||||
|  | ||||
| // @servezone | ||||
| import * as servezoneInterfaces from '@servezone/servezone-interfaces'; | ||||
|  | ||||
| export { servezoneInterfaces }; | ||||
|  | ||||
| // @pushrocks | ||||
| import * as projectinfo from '@pushrocks/projectinfo'; | ||||
| import * as npmextra from '@pushrocks/npmextra'; | ||||
| import * as projectinfo from '@pushrocks/projectinfo'; | ||||
| import * as qenv from '@pushrocks/qenv'; | ||||
| import * as smartanalytics from '@pushrocks/smartanalytics'; | ||||
| import * as smartdelay from '@pushrocks/smartdelay'; | ||||
| import * as smartfile from '@pushrocks/smartfile'; | ||||
| import * as smartcli from '@pushrocks/smartcli'; | ||||
| @@ -20,8 +34,10 @@ import * as smartssh from '@pushrocks/smartssh'; | ||||
| import * as smartstring from '@pushrocks/smartstring'; | ||||
|  | ||||
| export { | ||||
|   projectinfo, | ||||
|   npmextra, | ||||
|   projectinfo, | ||||
|   qenv, | ||||
|   smartanalytics, | ||||
|   smartdelay, | ||||
|   smartfile, | ||||
|   smartcli, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user