Grav blog.ayokitagelut.com
getopt-like CLI Options in node.js
Parsing CLI options with getopt-ish configuration
#!/usr/bin/env node
function argvAddValue(ret, id, val) {
if (ret[id] === undefined) {
ret[id] = val;
return;
}
if (!Array.isArray(ret[id])) ret[id] = [ ret[id] ];
ret[id].push(val);
}
function argvParser(options, argv) {
if (!argv) argv = process.argv;
const { length } = argv;
const sym = Symbol.for('input');
const ret = {};
for(let idx = 2, needValue = false; idx < length; idx++){
const arg = argv[idx];
if(arg[0] !== '\-') {
if (ret[sym] === undefined) ret[sym] = [];
if (!needValue) ret[sym].push(arg);
continue;
}
for(const key of options){
let token = key;
needValue = Boolean(token.match(/(:$)/));
if (needValue) token = token.replace(/:$/, '');
const argIsLongOpt = Boolean(arg.match(/^\-\-/));
const baseToken = `(^` + token.replace(/\-/g, '\\-');
const regexp = argIsLongOpt
? new RegExp(baseToken + '(?:=|\$))')
: new RegExp(baseToken + ')');
const hasMatch = arg.match(regexp);
if (!hasMatch) continue;
// take long options name or first char of the token
const id = token.match(/(?:^|\|)\-\-(.*?)(?:=|$)/)?.[1] ?? arg[1];
if (!needValue) {
argvAddValue(ret, id, true);
break;
}
// no longer necessary, revert now
needValue = false;
if (argIsLongOpt) {
const afterEq = arg.match(/=(.*$)/);
if (afterEq) {
const value = afterEq[1];
argvAddValue(ret, id, value);
break;
}
}
if (!argIsLongOpt && arg.length > 2) {
const value = arg.replace(hasMatch[1], '');
argvAddValue(ret, id, value);
break;
}
const value = argv[++idx];
argvAddValue(ret, id, value);
}
}
return ret;
}
/* ***************************** EXAMPLE ************************************ */
const parsed = argvParser([
'-c', // short opt switch
'-b:', // short opt with value
'--long', // long opt switch
'--long-arg:', // long opt with option
'-v|--verbose', // short and long opt switch
'-e|--example:', // short and long opt with value
]);
console.log(parsed);
console.table(parsed);
console.table(parsed[Symbol.for('input')]);
/*******************************************************************************
* INPUT:
* ./argvParser.js \
* file1 \
* -v \
* -bIPv4 \
* --long \
* --long-arg arg1 \
* --long-arg=arg2 \
* -e example \
* file2
*
* OUTPUT:
* {
* verbose: true,
* b: 'IPv4',
* long: true,
* 'long-arg': [ 'arg1', 'arg2' ],
* example: 'example',
* [Symbol(input)]: [ 'file1', 'file2' ]
* }
* ┌──────────┬────────┬────────┬───────────┐
* │ (index) │ 0 │ 1 │ Values │
* ├──────────┼────────┼────────┼───────────┤
* │ verbose │ │ │ true │
* │ b │ │ │ 'IPv4' │
* │ long │ │ │ true │
* │ long-arg │ 'arg1' │ 'arg2' │ │
* │ example │ │ │ 'example' │
* └──────────┴────────┴────────┴───────────┘
* ┌─────────┬─────────┐
* │ (index) │ Values │
* ├─────────┼─────────┤
* │ 0 │ 'file1' │
* │ 1 │ 'file2' │
* └─────────┴─────────┘
* */
Integrate vpckg and cmake-js
I missed how easy to install system wide library using apt, pkg, or brew. Something that missing in Windows. Fortunately, vcpkg exists. Unfortunately, it's not as easy as the other system wide package manager.
I successfully setup vcpkg to install system wide libraries, with these steps:
NOTE: Visual Studio must be already installed.
-
Don't use Developer PowerShell from Visual Studio installation. Just use the general PowerShell.
Developer PowerShell from Visual Studio will use embedded
vcpkgwhich doesn't support system wide installation. -
Install
vcpkggit clone https://github.com/microsoft/vcpkg "<path-to-vcpkg>" cd "<path-to-vcpkg>" .\bootstrap-vcpkg.bat .\vcpkg integrate install -
Edit User Profile to set environment variables
You can edit the User profile in PowerShell with this command
notepad $profile.CurrentUserCurrentHostthen add these lines at the end of file
# set vcpkg environment variable and path $env:VCPKG_ROOT="<path-to-vcpkg>" $env:Path += ";$env:VCPKG_ROOT" # to set MSVC environment variables for x86_amd64 platform. # This step assumes you installed Visual Studio 2022 Community edition for x86_64 platform & "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64restart or open new PowerShell session.
to set environment variables for current session, you can reload the profile with this command
. $PROFILE -
Edit your
CMakeLists.txtPut these lines before the first
project()if (WIN32) if (NOT DEFINED ENV{VCPKG_ROOT}) message(FATAL_ERROR "$ENV{VCPKG_ROOT}: Env VCPKG_ROOT needs to be set!") endif () set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake") endif ()at this step, Env variable
VCPKG_ROOTmust've been set as this is the necessary condition for our cmake to work. -
Now, you can install system wide libraries with
vcpkgand usefind_package,find_path, andfind_libraryinCMakeLists.txtExample:
-
Install
openssl,libssh2, andzlibvcpkg install openssl libssh2 zlib -
use installed libs in
CMakeLists.txtfind_package(OpenSSL REQUIRED) target_link_libraries("${PROJECT_NAME}" PRIVATE OpenSSL::SSL OpenSSL::Crypto) find_package(ZLIB REQUIRED) target_link_libraries("${PROJECT_NAME}" PRIVATE ZLIB::ZLIB) find_library(LIBSSH2_LIBRARY NAMES ssh2 libssh2) find_path(LIBSSH2_INCLUDE_DIR NAMES libssh2.h) target_link_libraries("${PROJECT_NAME}" PRIVATE "${LIBSSH2_LIBRARY}") target_include_directories("${PROJECT_NAME}" PRIVATE "${LIBSSH2_INCLUDE_DIR}")
-
SDDM greeter black screen after upgrade to Kubuntu 25.10
SDDM greeter always gives No Signal after upgrading from 25.04 to 25.10
At first, I think it's nvidia driver issue. So, I changed these files below:
-
/ets/default/grubGRUB_CMDLINE_LINUX_DEFAULT="quiet nvidia_drm.modeset=1 nvidia_drm.fb_dev=1 resume=UUID=3fd0f470-9846-4bf7-a286-390f9c99b275" -
/etc/modprobe.d/nvidia-graphics-drivers-kms.confoptions nvidia_drm modeset=1 options nvidia_drm fbdev=1both number 1 and 2, cause I think it was nvida driver 580 has problem with wayland
-
/etc/modprobe.d/blacklist.confblacklist nouveau options nouveau modeset=0cause I thought the nouveau driver also runs when nvidia driver is already running.
NOTE: After number 3, I ran
sudo update-initramfs -u sudo update-grub
Nothing works. The SDDM still gave me No Signal
Then I found strange things, I typed my password during black screen then I was able to go into desktop.
Turns out, SDDM greeter runs on X11 and I don't have xorg installed. The steps are as follows,
-
Install
xorgsudo apt install xorg -y -
Populate
/etc/X11/xorg.confwithnvidia-xconfigsudo nvidia-xconfig
Just like that, and the greeter was able to display on the next reboot.
Welp, it's weird because previously on Kubuntu 25.04 everything went well. Perhaps during upgrade process via do-release-upgrade, somehow xorg was uninstalled
UPDATE
It's indeed that xorg was removed by 25.10. But it's said that it's only for gnome, and even though I use KDE it's still got removed.