Compare commits

...

50 Commits

Author SHA1 Message Date
d53e8fec6d v3.1.3 2026-02-03 22:58:28 +00:00
00fef1ae06 fix(mod_update): try private registry (verdaccio.lossless.digital) first when fetching package versions; fall back to public npm; handle unknown latest versions gracefully in output 2026-02-03 22:58:28 +00:00
4c1608cf94 v3.1.2 2026-02-03 22:48:01 +00:00
e0c4cf2983 fix(scripts): make test script output verbose by using --verbose instead of --web 2026-02-03 22:48:01 +00:00
e3eb0af434 v3.1.1 2026-02-03 22:47:30 +00:00
8d25d28b54 fix(tools): no changes detected 2026-02-03 22:47:30 +00:00
4237e49f14 v3.1.0 2026-02-03 22:47:08 +00:00
019f7e2d88 feat(cli): add update command to check and update globally installed @git.zone packages 2026-02-03 22:47:08 +00:00
abaeb7be6c v3.0.0 2026-02-03 17:12:26 +00:00
ab714377ba BREAKING CHANGE(tools): replace install functionality with a minimal placeholder CLI; remove installer, logging, path utilities, and related assets 2026-02-03 17:12:26 +00:00
450b3ba379 2.0.23 2026-02-03 16:59:33 +00:00
0daae0bd07 fix(core): update 2026-02-03 16:59:32 +00:00
826f3a6c63 2.0.22 2020-10-05 10:33:44 +00:00
c1a4671ce1 fix(core): update 2020-10-05 10:33:43 +00:00
73a6d5bc31 2.0.21 2020-10-05 10:33:09 +00:00
e15a569391 fix(core): update 2020-10-05 10:33:08 +00:00
74809bd8d4 2.0.20 2020-10-04 23:02:27 +00:00
5b852d9602 fix(core): update 2020-10-04 23:02:26 +00:00
f68254eea7 2.0.19 2020-10-04 23:01:39 +00:00
5935c67f2e fix(core): update 2020-10-04 23:01:39 +00:00
98f5353744 2.0.18 2019-08-27 18:46:03 +02:00
1372a2bb7e fix(core): update 2019-08-27 18:46:03 +02:00
fa16aaa2c1 2.0.17 2019-08-27 18:27:43 +02:00
c3892096b6 fix(core): update 2019-08-27 18:27:43 +02:00
4e6646b133 2.0.16 2019-08-27 17:04:44 +02:00
da6739be6a fix(core): update 2019-08-27 17:04:43 +02:00
f72217250d 2.0.15 2019-08-26 19:29:15 +02:00
4c36174b0d fix(core): update 2019-08-26 19:29:15 +02:00
5f34bc8042 2.0.14 2019-08-26 19:27:11 +02:00
6d354a10d0 fix(core): update 2019-08-26 19:27:10 +02:00
8208ba2970 2.0.13 2019-08-26 18:09:27 +02:00
3c2b51d47e fix(core): update 2019-08-26 18:09:27 +02:00
12fab84daa 2.0.12 2019-08-23 03:55:32 +02:00
4b5b683fff fix(core): update 2019-08-23 03:55:31 +02:00
ec1958d882 2.0.11 2019-08-23 00:21:14 +02:00
1f59cd4ba1 fix(core): update 2019-08-23 00:21:13 +02:00
74c0d537cc 2.0.10 2019-06-19 14:40:59 +02:00
c4706e96cb fix(core): update 2019-06-19 14:40:59 +02:00
628b86cf3d 2.0.9 2019-06-19 14:24:09 +02:00
d0c6ebb0df fix(core): update 2019-06-19 14:24:08 +02:00
dd8c30e7cf 2.0.8 2019-06-19 13:59:38 +02:00
8f861d86c9 fix(core): update 2019-06-19 13:59:37 +02:00
fe2581b533 2.0.7 2019-06-19 13:49:57 +02:00
db906cea1a fix(core): update 2019-06-19 13:49:57 +02:00
9c1dca9ace 2.0.6 2019-06-19 13:20:07 +02:00
c620549476 fix(core): update 2019-06-19 13:20:07 +02:00
90697584d7 2.0.5 2019-06-19 13:12:11 +02:00
1252fa8f97 fix(core): update 2019-06-19 13:12:10 +02:00
cdbc9823f1 2.0.4 2019-06-17 10:27:34 +02:00
9d7023e739 fix(core): update 2019-06-17 10:27:33 +02:00
30 changed files with 19247 additions and 1026 deletions

11
.gitignore vendored
View File

@@ -3,7 +3,6 @@
# artifacts
coverage/
public/
pages/
# installs
node_modules/
@@ -15,8 +14,10 @@ node_modules/
# builds
dist/
dist_web/
dist_serve/
dist_ts_web/
dist_*/
# custom
# AI
.claude/
.serena/
#------# custom

View File

@@ -1,117 +0,0 @@
# gitzone ci_default
image: hosttoday/ht-docker-node:npmci
cache:
paths:
- .npmci_cache/
key: "$CI_BUILD_STAGE"
stages:
- security
- test
- release
- metadata
# ====================
# security stage
# ====================
mirror:
stage: security
script:
- npmci git mirror
tags:
- docker
- notpriv
snyk:
stage: security
script:
- npmci npm prepare
- npmci command npm install -g snyk
- npmci command npm install --ignore-scripts
- npmci command snyk test
tags:
- docker
- notpriv
# ====================
# test stage
# ====================
testLTS:
stage: test
script:
- npmci npm prepare
- npmci node install lts
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
testSTABLE:
stage: test
script:
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
release:
stage: release
script:
- npmci node install stable
- npmci npm publish
only:
- tags
tags:
- docker
- notpriv
# ====================
# metadata stage
# ====================
codequality:
stage: metadata
allow_failure: true
script:
- npmci command npm install -g tslint typescript
- npmci npm install
- npmci command "tslint -c tslint.json ./ts/**/*.ts"
tags:
- docker
- priv
trigger:
stage: metadata
script:
- npmci trigger
only:
- tags
tags:
- docker
- notpriv
pages:
image: hosttoday/ht-docker-node:npmci
stage: metadata
script:
- npmci command npm install -g @gitzone/tsdoc
- npmci npm prepare
- npmci npm install
- npmci command tsdoc
tags:
- docker
- notpriv
only:
- tags
artifacts:
expire_in: 1 week
paths:
- public
allow_failure: true

22
.snyk
View File

@@ -1,22 +0,0 @@
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
version: v1.12.0
# ignores vulnerabilities until expiry date; change duration by modifying expiry date
ignore:
'npm:lodash:20180130':
- smartenv > beautylog > cli-table2 > lodash:
reason: None given
expires: '2018-07-07T20:45:00.571Z'
- smartenv > smartenv > beautylog > cli-table2 > lodash:
reason: None given
expires: '2018-07-07T20:45:00.571Z'
- smartenv > smartparam > beautylog > cli-table2 > lodash:
reason: None given
expires: '2018-07-07T20:45:00.571Z'
- smartenv > smartparam > beautylog > smartenv > beautylog > cli-table2 > lodash:
reason: None given
expires: '2018-07-07T20:45:00.571Z'
'npm:shelljs:20140723':
- smartshell > shelljs:
reason: None given
expires: '2018-07-07T20:45:00.571Z'
patch: {}

29
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,29 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "current file",
"type": "node",
"request": "launch",
"args": [
"${relativeFile}"
],
"runtimeArgs": ["-r", "@git.zone/tsrun"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart"
},
{
"name": "test.ts",
"type": "node",
"request": "launch",
"args": [
"test/test.ts"
],
"runtimeArgs": ["-r", "@git.zone/tsrun"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart"
}
]
}

26
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,26 @@
{
"json.schemas": [
{
"fileMatch": ["/npmextra.json"],
"schema": {
"type": "object",
"properties": {
"npmci": {
"type": "object",
"description": "settings for npmci"
},
"gitzone": {
"type": "object",
"description": "settings for gitzone",
"properties": {
"projectType": {
"type": "string",
"enum": ["website", "element", "service", "npm", "wcc"]
}
}
}
}
}
}
]
}

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2016 Lossless GmbH
Copyright (c) 2016 Task Venture Capital GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,28 +0,0 @@
# @gitzone/tools
setup your environment with the most important tools and update them easily.
## Availabililty and Links
* [npmjs.org (npm package)](https://www.npmjs.com/package/@gitzone/tools)
* [gitlab.com (source)](https://gitlab.com/gitzone/tools)
* [github.com (source mirror)](https://github.com/gitzone/tools)
* [docs (typedoc)](https://gitzone.gitlab.io/tools/)
## Status for master
[![build status](https://gitlab.com/gitzone/tools/badges/master/build.svg)](https://gitlab.com/gitzone/tools/commits/master)
[![coverage report](https://gitlab.com/gitzone/tools/badges/master/coverage.svg)](https://gitlab.com/gitzone/tools/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/@gitzone/tools.svg)](https://www.npmjs.com/package/@gitzone/tools)
[![Known Vulnerabilities](https://snyk.io/test/npm/@gitzone/tools/badge.svg)](https://snyk.io/test/npm/@gitzone/tools)
[![TypeScript](https://img.shields.io/badge/TypeScript->=%203.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-prettier-ff69b4.svg)](https://prettier.io/)
## Usage
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)
[![repo-footer](https://gitzone.gitlab.io/assets/repo-footer.svg)](https://maintainedby.lossless.com)

122
changelog.md Normal file
View File

@@ -0,0 +1,122 @@
# Changelog
## 2026-02-03 - 3.1.3 - fix(mod_update)
try private registry (verdaccio.lossless.digital) first when fetching package versions; fall back to public npm; handle unknown latest versions gracefully in output
- getLatestVersion now attempts a direct API request to https://verdaccio.lossless.digital/<encoded-package> and parses dist-tags.latest
- Falls back to npm view when the private registry request fails
- Scoped package names are URL-encoded (replaces '/' with '%2f') before querying the private registry
- Packages with no resolvable latest version are included with latestVersion set to 'unknown' and displayed as '? Version unknown'
- needsUpdate is set to false when latest version is unknown
## 2026-02-03 - 3.1.2 - fix(scripts)
make test script output verbose by using --verbose instead of --web
- package.json: change npm "test" script from "(tstest test/ --web)" to "(tstest test/ --verbose)" to enable verbose test output
## 2026-02-03 - 3.1.1 - fix(tools)
no changes detected
- No files were modified in this diff
- No code or documentation changes to include in a commit message
## 2026-02-03 - 3.1.0 - feat(cli)
add update command to check and update globally installed @git.zone packages
- Adds a new mod_update module and PackageManagerUtil to detect installed @git.zone packages and fetch latest versions
- Supports npm, yarn and pnpm: detection, listing, version comparison and executing updates
- Interactive confirmation via @push.rocks/smartinteract with a -y flag to skip prompt
- Uses @push.rocks/smartshell to run shell commands for listing and updating packages
- Wires the new 'update' command into the CLI (tools.cli) and updates CLI version to 3.0.0
- Adds CLI helper files (cli.child.js, adjusts cli.js and cli.ts.js) to run TypeScript CLI via tsrun/runPath
- Updates package.json to include new dependencies and npmextra.json with release registries and @git.zone/cli metadata
- Updates .gitignore to exclude local AI tool dirs (.claude, .serena)
## 2026-02-03 - 3.0.0 - BREAKING CHANGE(tools)
replace install functionality with a minimal placeholder CLI; remove installer, logging, path utilities, and related assets
- Removed installer implementation (ts/tools.install.ts) and package library asset (assets/package_library.json).
- Removed logging and path utilities (ts/tools.logging.ts, ts/tools.paths.ts) and simplified plugins (ts/tools.plugins.ts) to only export smartcli.
- Reworked CLI (ts/tools.cli.ts) to a placeholder standard command that prints messages instead of running installs; internal CLI version set to 2.0.22.
- Module export/behavior changed: ts/index.ts now exports runCli and no longer auto-runs; tests updated to expect runCli.
- package.json updated: description changed, several dependencies removed (e.g. @push.rocks/smartlog, @push.rocks/smartshell), @types/node bumped to ^22.0.0, and assets removed from packaged files list.
- Removed project policy and metadata files: .snyk deleted and readme.md added with usage and legal information.
## 2026-02-03 - 2.0.22 - core
Core maintenance release.
- fix(core): update — minor core fixes and maintenance improvements.
## 2026-02-03 - 2.0.23 - release tag
Release tag only — no recorded changelog details.
- 2.0.23: release tag with no additional commit message.
## 2020-10-05 - 2.0.3 - 2.0.21 - core (maintenance)
Series of maintenance releases containing repeated small core fixes.
- Multiple commits "fix(core): update" applied across 2.0.3 through 2.0.21 addressing minor bugs and stability improvements.
- These releases are maintenance-focused; no user-facing feature additions recorded.
## 2019-06-17 - 2.0.2 - core
Maintenance update to core.
- fix(core): update — continued minor fixes and upkeep.
## 2018-06-07 - 2.0.0 - 2.0.1 - policy/package fixes
Initial 2.0.x releases with policy and package fixes.
- 2.0.0: fix(snyk policy): update — update to Snyk policy.
- 2.0.1: fix(package.json): fix private property — corrected package.json property.
- 2.0.2: release tag (later maintenance continued in subsequent 2.0.x).
## 2018-06-07 - 1.0.9 - core (feature)
New core scope added.
- feat(core): new tools scope — introduces a "tools" scope in core.
## 2017-06-04 - 1.0.8 - release tag
Release tag only — no recorded changelog details.
- 1.0.8: release tag with no additional commit message.
## 2017-06-04 - 1.0.7 - cli
CLI update.
- update cli — improvements/updates to the command-line interface.
## 2017-05-28 - 1.0.6 / 1.0.5 - docs & CLI
Documentation and CLI additions.
- 1.0.6: update README — documentation updates.
- 1.0.5: add cli.js — adds CLI entry point.
## 2017-05-28 - 1.0.4 - maintenance and cleanups
Collection of maintenance, cleanup, and packaging updates for 1.0.4 over several commits.
- update / cleanup — general code cleanups.
- Update packageLibrary.json — package metadata adjusted.
- added cli.js, added .npmignore — packaging and CLI support added.
- Consolidated multiple 1.0.4 changes across 20162017 into this release.
## 2016-03-03 - 1.0.3 - tests
Test fix.
- fix test.ts — test suite correction.
## 2016-03-03 - 1.0.2 - CI
Continuous integration fix.
- fix Travis — adjusts CI configuration.
## 2016-03-02 - 1.0.1 - install/tests
Installer and tests improvements.
- now installing things correctly — fixes installation behavior.
- create test / update — test additions and miscellaneous updates.
## 2016-03-02 - 1.0.0 - initial release
Project initial structure and first release.
- add structure / set up initial structure / cleanup — initial project layout and housekeeping.
- initial (2016-02-29 and 2016-02-24) — first commits establishing the repository.

4
cli.child.ts Normal file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env node
process.env.CLI_CALL = 'true';
import * as cliTool from './ts/index.js';
cliTool.runCli();

3
cli.js
View File

@@ -1,3 +1,4 @@
#!/usr/bin/env node
process.env.CLI_CALL = 'true';
require('./dist/index');
const cliTool = await import('./dist_ts/index.js');
cliTool.runCli();

View File

@@ -1,4 +1,5 @@
#!/usr/bin/env node
process.env.CLI_CALL = 'true';
require('@gitzone/tsrun');
require('./ts/index');
import * as tsrun from '@git.zone/tsrun';
tsrun.runPath('./cli.child.js', import.meta.url);

View File

@@ -2,20 +2,28 @@
"npmts": {
"cli": true
},
"npmci": {
"globalNpmTools": [
"npmts"
],
"npmAccessLevel": "public"
},
"gitzone": {
"@git.zone/cli": {
"projectType": "npm",
"module": {
"githost": "gitlab.com",
"gitscope": "gitzone",
"gitrepo": "tools",
"shortDescription": "setup your environment with the most important tools and update them easily.",
"npmPackagename": "@gitzone/tools",
"license": "MIT"
}
"npmPackagename": "@git.zone/tools",
"license": "MIT",
"description": "manage git.zone tools"
},
"release": {
"registries": [
"https://verdaccio.lossless.digital",
"https://registry.npmjs.org"
],
"accessLevel": "public"
}
},
"@ship.zone/szci": {
"globalNpmTools": [
"npmts"
]
}
}

10881
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,14 @@
{
"name": "@gitzone/tools",
"version": "2.0.3",
"name": "@git.zone/tools",
"version": "3.1.3",
"private": false,
"description": "setup your environment with the most important tools and update them easily.",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"type": "module",
"description": "A CLI tool placeholder for development utilities.",
"main": "dist_ts/index.js",
"typings": "dist_ts/index.d.ts",
"scripts": {
"test": "tstest test/",
"build": "tsbuild"
"test": "(tstest test/ --verbose)",
"build": "(tsbuild --web)"
},
"bin": {
"gtools": "cli.js"
@@ -29,29 +30,28 @@
},
"homepage": "https://github.com/GitZoneTools/npmg#readme",
"devDependencies": {
"@gitzone/tstest": "^1.0.24",
"@pushrocks/tapbundle": "^3.0.9",
"tslint": "^5.17.0",
"tslint-config-prettier": "^1.18.0"
"@git.zone/tsbuild": "^4.1.2",
"@git.zone/tstest": "^3.1.8"
},
"dependencies": {
"@gitzone/tsrun": "^1.2.6",
"@pushrocks/smartcli": "^3.0.7",
"@pushrocks/smartenv": "^4.0.6",
"@pushrocks/smartfile": "^7.0.2",
"@pushrocks/smartlog": "^2.0.19",
"@pushrocks/smartlog-destination-local": "^8.0.2",
"@pushrocks/smartshell": "^2.0.23",
"@types/node": "^12.0.8"
"@git.zone/tsrun": "^2.0.1",
"@push.rocks/smartcli": "^4.0.20",
"@push.rocks/smartinteract": "^2.0.16",
"@push.rocks/smartshell": "^3.3.0",
"@types/node": "^22.0.0"
},
"files": [
"ts/*",
"ts_web/*",
"dist/*",
"dist_web/*",
"assets/*",
"ts/**/*",
"ts_web/**/*",
"dist/**/*",
"dist_*/**/*",
"dist_ts/**/*",
"dist_ts_web/**/*",
"cli.js",
"npmextra.json",
"readme.md"
],
"browserslist": [
"last 1 chrome versions"
]
}

View File

@@ -1,12 +0,0 @@
{
"default":[
"@gitzone_private/gitzone",
"typescript",
"tslint",
"@gitzone/tsrun",
"@gitzone/tsdocker",
"snyk",
"npm-check"
]
}

8365
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

42
readme.md Normal file
View File

@@ -0,0 +1,42 @@
# @git.zone/tools 🛠️
A CLI tool placeholder for development utilities.
## Issue Reporting and Security
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
## Installation 📦
```bash
npm install -g @git.zone/tools
```
## Usage 🚀
```bash
gtools
```
Currently a placeholder CLI with no commands implemented yet.
## License and Legal Information
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file.
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
### Trademarks
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
### Company Information
Task Venture Capital GmbH
Registered at District Court Bremen HRB 35230 HB, Germany
For any legal inquiries or further information, please contact us via email at hello@task.vc.
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.

9
test/test.node.ts Normal file
View File

@@ -0,0 +1,9 @@
import { expect, tap } from '@git.zone/tstest/tapbundle';
import * as tools from '../ts/index.js';
tap.test('should export runCli function', async () => {
expect(typeof tools.runCli).toEqual('function');
});
export default tap.start();

View File

@@ -1,12 +0,0 @@
import { expect, tap } from '@pushrocks/tapbundle';
import * as npmgInstall from '../ts/tools.install';
import * as smartenv from '@pushrocks/smartenv';
let environment = new smartenv.Smartenv();
tap.test("should install default list globally when parsed 'default' as argument", async () => {
await npmgInstall.install('default');
});
tap.start();

8
ts/00_commitinfo_data.ts Normal file
View File

@@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @push.rocks/commitinfo
*/
export const commitinfo = {
name: '@git.zone/tools',
version: '3.1.3',
description: 'A CLI tool placeholder for development utilities.'
}

View File

@@ -1,2 +1,7 @@
import plugins = require('./tools.plugins');
import * as cli from './tools.cli';
import * as cli from './tools.cli.js';
export const runCli = async () => {
await cli.run();
};
runCli();

View File

@@ -0,0 +1,213 @@
import * as plugins from './mod.plugins.js';
export type TPackageManager = 'npm' | 'yarn' | 'pnpm';
export interface IInstalledPackage {
name: string;
version: string;
packageManager: TPackageManager;
}
export interface IPackageUpdateInfo {
name: string;
currentVersion: string;
latestVersion: string;
packageManager: TPackageManager;
needsUpdate: boolean;
}
export class PackageManagerUtil {
private shell = new plugins.smartshell.Smartshell({
executor: 'bash',
});
/**
* Check if a package manager is available on the system
*/
public async isAvailable(pm: TPackageManager): Promise<boolean> {
try {
const result = await this.shell.execSilent(`which ${pm} >/dev/null 2>&1 && echo "found"`);
return result.exitCode === 0 && result.stdout.includes('found');
} catch {
return false;
}
}
/**
* Get all globally installed @git.zone packages for a package manager
*/
public async getInstalledPackages(pm: TPackageManager): Promise<IInstalledPackage[]> {
const packages: IInstalledPackage[] = [];
try {
let result;
switch (pm) {
case 'npm':
result = await this.shell.execSilent('npm list -g --depth=0 --json 2>/dev/null || true');
break;
case 'yarn':
result = await this.shell.execSilent('yarn global list --depth=0 --json 2>/dev/null || true');
break;
case 'pnpm':
result = await this.shell.execSilent('pnpm list -g --depth=0 --json 2>/dev/null || true');
break;
}
const output = result.stdout.trim();
if (!output) {
return packages;
}
if (pm === 'npm') {
try {
const data = JSON.parse(output);
const deps = data.dependencies || {};
for (const [name, info] of Object.entries(deps)) {
if (name.startsWith('@git.zone/')) {
packages.push({
name,
version: (info as any).version || 'unknown',
packageManager: pm,
});
}
}
} catch {
// JSON parse failed
}
} else if (pm === 'pnpm') {
// pnpm returns an array of objects
try {
const data = JSON.parse(output);
// Handle array format from pnpm
const dataArray = Array.isArray(data) ? data : [data];
for (const item of dataArray) {
const deps = item.dependencies || {};
for (const [name, info] of Object.entries(deps)) {
if (name.startsWith('@git.zone/')) {
packages.push({
name,
version: (info as any).version || 'unknown',
packageManager: pm,
});
}
}
}
} catch {
// JSON parse failed
}
} else if (pm === 'yarn') {
// Yarn global list --json outputs multiple JSON lines
const lines = output.split('\n').filter(l => l.trim());
for (const line of lines) {
try {
const data = JSON.parse(line);
if (data.type === 'tree' && data.data && data.data.trees) {
for (const tree of data.data.trees) {
const name = tree.name?.split('@')[0] || '';
if (name.startsWith('@git.zone/')) {
const version = tree.name?.split('@').pop() || 'unknown';
packages.push({
name,
version,
packageManager: pm,
});
}
}
}
} catch {
// Skip invalid JSON lines
}
}
}
} catch {
// Command failed, return empty array
}
return packages;
}
/**
* Get the latest version of a package from npm registry
* Tries private registry (verdaccio.lossless.digital) first via API, then falls back to public npm
*/
public async getLatestVersion(packageName: string): Promise<string | null> {
// URL-encode the package name for scoped packages (@scope/name -> @scope%2fname)
const encodedName = packageName.replace('/', '%2f');
// Try private registry first via direct API call (npm view doesn't work reliably)
try {
const result = await this.shell.execSilent(
`curl -sf "https://verdaccio.lossless.digital/${encodedName}" 2>/dev/null`
);
if (result.exitCode === 0 && result.stdout.trim()) {
const data = JSON.parse(result.stdout.trim());
if (data['dist-tags']?.latest) {
return data['dist-tags'].latest;
}
}
} catch {
// Continue to public registry
}
// Fall back to public npm
try {
const result = await this.shell.execSilent(`npm view ${packageName} version 2>/dev/null`);
if (result.exitCode === 0 && result.stdout.trim()) {
return result.stdout.trim();
}
} catch {
// Command failed
}
return null;
}
/**
* Execute an update for a package using the specified package manager
*/
public async executeUpdate(pm: TPackageManager, packageName: string): Promise<boolean> {
let command: string;
switch (pm) {
case 'npm':
command = `npm install -g ${packageName}@latest`;
break;
case 'yarn':
command = `yarn global add ${packageName}@latest`;
break;
case 'pnpm':
command = `pnpm add -g ${packageName}@latest`;
break;
}
console.log(` Updating ${packageName} via ${pm}...`);
try {
const result = await this.shell.exec(command);
return result.exitCode === 0;
} catch {
return false;
}
}
/**
* Compare two semver versions
* Returns true if latest > current
*/
public isNewerVersion(current: string, latest: string): boolean {
const cleanVersion = (v: string) => v.replace(/^[^\d]*/, '');
const currentClean = cleanVersion(current);
const latestClean = cleanVersion(latest);
const currentParts = currentClean.split('.').map(n => parseInt(n, 10) || 0);
const latestParts = latestClean.split('.').map(n => parseInt(n, 10) || 0);
for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {
const curr = currentParts[i] || 0;
const lat = latestParts[i] || 0;
if (lat > curr) return true;
if (lat < curr) return false;
}
return false;
}
}

137
ts/mod_update/index.ts Normal file
View File

@@ -0,0 +1,137 @@
import * as plugins from './mod.plugins.js';
import { PackageManagerUtil, type TPackageManager, type IPackageUpdateInfo } from './classes.packagemanager.js';
const GITZONE_PACKAGES = [
'@git.zone/cli',
'@git.zone/tsdoc',
'@git.zone/tsbuild',
'@git.zone/tstest',
'@git.zone/tspublish',
'@git.zone/tsbundle',
'@git.zone/tsdocker',
'@git.zone/tsview',
'@git.zone/tswatch',
];
export interface IUpdateOptions {
yes?: boolean;
}
export const run = async (options: IUpdateOptions = {}): Promise<void> => {
const pmUtil = new PackageManagerUtil();
console.log('Scanning for installed @git.zone packages...\n');
// Check which package managers are available
const availablePMs: TPackageManager[] = [];
for (const pm of ['npm', 'yarn', 'pnpm'] as TPackageManager[]) {
if (await pmUtil.isAvailable(pm)) {
availablePMs.push(pm);
}
}
if (availablePMs.length === 0) {
console.log('No package managers found (npm, yarn, pnpm).');
return;
}
console.log(`Found package managers: ${availablePMs.join(', ')}\n`);
// Collect all installed @git.zone packages from all package managers
const allPackages: IPackageUpdateInfo[] = [];
for (const pm of availablePMs) {
const installed = await pmUtil.getInstalledPackages(pm);
for (const pkg of installed) {
// Only include packages from our predefined list
if (GITZONE_PACKAGES.includes(pkg.name)) {
const latestVersion = await pmUtil.getLatestVersion(pkg.name);
allPackages.push({
name: pkg.name,
currentVersion: pkg.version,
latestVersion: latestVersion || 'unknown',
packageManager: pm,
needsUpdate: latestVersion ? pmUtil.isNewerVersion(pkg.version, latestVersion) : false,
});
}
}
}
if (allPackages.length === 0) {
console.log('No @git.zone packages found installed globally.');
return;
}
// Display package table
console.log('Installed @git.zone packages:\n');
console.log(' Package Current Latest PM Status');
console.log(' ─────────────────────────────────────────────────────────────────────');
for (const pkg of allPackages) {
const name = pkg.name.padEnd(28);
const current = pkg.currentVersion.padEnd(12);
const latest = pkg.latestVersion.padEnd(12);
const pm = pkg.packageManager.padEnd(8);
const status = pkg.latestVersion === 'unknown'
? '? Version unknown'
: pkg.needsUpdate
? '⬆️ Update available'
: '✓ Up to date';
console.log(` ${name}${current}${latest}${pm}${status}`);
}
console.log('');
// Filter packages that need updates
const packagesToUpdate = allPackages.filter(p => p.needsUpdate);
if (packagesToUpdate.length === 0) {
console.log('All packages are up to date!');
return;
}
console.log(`Found ${packagesToUpdate.length} package(s) with available updates.\n`);
// Ask for confirmation unless -y flag is provided
let shouldUpdate = options.yes === true;
if (!shouldUpdate) {
const smartinteractInstance = new plugins.smartinteract.SmartInteract();
const answer = await smartinteractInstance.askQuestion({
type: 'confirm',
name: 'confirmUpdate',
message: 'Do you want to update these packages?',
default: true,
});
shouldUpdate = answer.value === true;
}
if (!shouldUpdate) {
console.log('Update cancelled.');
return;
}
// Execute updates
console.log('\nUpdating packages...\n');
let successCount = 0;
let failCount = 0;
for (const pkg of packagesToUpdate) {
const success = await pmUtil.executeUpdate(pkg.packageManager, pkg.name);
if (success) {
console.log(`${pkg.name} updated successfully`);
successCount++;
} else {
console.log(`${pkg.name} update failed`);
failCount++;
}
}
console.log('');
if (failCount === 0) {
console.log(`All ${successCount} package(s) updated successfully!`);
} else {
console.log(`Updated ${successCount} package(s), ${failCount} failed.`);
}
};

View File

@@ -0,0 +1,4 @@
import * as smartinteract from '@push.rocks/smartinteract';
import * as smartshell from '@push.rocks/smartshell';
export { smartinteract, smartshell };

View File

@@ -1,11 +1,23 @@
import * as plugins from './tools.plugins';
import * as toolsInstall from './tools.install';
import * as plugins from './tools.plugins.js';
import * as modUpdate from './mod_update/index.js';
export const run = async () => {
const toolsCli = new plugins.smartcli.Smartcli();
toolsCli.addCommand('install').subscribe(async argvArg => {
toolsInstall.install('default');
toolsCli.standardCommand().subscribe(async (argvArg) => {
console.log('@git.zone/tools - CLI utility for managing @git.zone packages\n');
console.log('Commands:');
console.log(' update Check and update globally installed @git.zone packages');
console.log(' update -y Update without confirmation prompt');
console.log('');
console.log('Use "gtools <command> --help" for more information about a command.');
});
toolsCli.addVersion('no version set');
toolsCli.addCommand('update').subscribe(async (argvArg) => {
const yesFlag = argvArg.y === true || argvArg.yes === true;
await modUpdate.run({ yes: yesFlag });
});
toolsCli.addVersion('3.0.0');
toolsCli.startParse();
};

View File

@@ -1,38 +0,0 @@
import plugins = require('./tools.plugins');
import paths = require('./tools.paths');
import { logger } from './tools.logging';
const installExec = async (packageNames: string[]) => {
const smartshellInstance = new plugins.smartshell.Smartshell({
executor: 'bash'
});
let installString = '';
for (const packageName of packageNames) {
logger.log('info', `Found ${packageName}!`);
installString = installString + `${packageName} `;
}
// lets remove old packages
const uninstallCommand = `npm uninstall -g ${installString}`;
const installCommand = `npm install -g ${installString}`;
logger.log('info', `uninstalling old packages with "${uninstallCommand}"`);
await smartshellInstance.exec(uninstallCommand);
logger.log('info', `installing tools with ${installCommand}`);
await smartshellInstance.exec(installCommand);
logger.log('ok', `installed tools successfully!`);
};
const packageLibrary = plugins.smartfile.fs.toObjectSync(
plugins.path.join(paths.packageBase, 'package_library.json')
);
export const install = async (packageSetArg: string) => {
switch (packageSetArg) {
case 'default':
await installExec(packageLibrary.default);
break;
default:
logger.log('warn', 'no set has been specified');
break;
}
};

View File

@@ -1,15 +0,0 @@
import * as plugins from './tools.plugins';
export const logger = new plugins.smartlog.Smartlog({
logContext: {
company: 'Some Company',
companyunit: 'Some CompanyUnit',
containerName: 'Some Containername',
environment: 'local',
runtime: 'node',
zone: 'gitzone'
},
minimumLogLevel: 'silly'
});
logger.addLogDestination(new plugins.smartlogDestinationLocal.DestinationLocal());

View File

@@ -1,3 +0,0 @@
import plugins = require('./tools.plugins');
export let packageBase = plugins.path.join('__dirname', '../');

View File

@@ -1,11 +1,6 @@
// node native
import * as path from 'path';
// push.rocks scope
import * as smartcli from '@push.rocks/smartcli';
import * as smartinteract from '@push.rocks/smartinteract';
import * as smartshell from '@push.rocks/smartshell';
// pushrocks scope
import * as smartlog from '@pushrocks/smartlog';
import * as smartlogDestinationLocal from '@pushrocks/smartlog-destination-local';
import * as smartcli from '@pushrocks/smartcli';
import * as smartfile from '@pushrocks/smartfile';
import * as smartshell from '@pushrocks/smartshell';
export { smartlog, smartlogDestinationLocal, path, smartcli, smartfile, smartshell };
export { smartcli, smartinteract, smartshell };

View File

@@ -1,17 +0,0 @@
{
"extends": ["tslint:latest", "tslint-config-prettier"],
"rules": {
"semicolon": [true, "always"],
"no-console": false,
"ordered-imports": false,
"object-literal-sort-keys": false,
"member-ordering": {
"options":{
"order": [
"static-method"
]
}
}
},
"defaultSeverity": "warning"
}