nodeca / argparse

CLI arguments parser for node.js. JS port of python's argparse module.
Other
491 stars 73 forks source link

How to make a custom Action? #165

Closed lonnywong closed 2 years ago

lonnywong commented 2 years ago

How to make a custom Action?

const argparse = require("argparse");

class BufferSizeParser extends argparse.Action {
  private minSize: string;
  private maxSize: string;

  constructor(options) {
    const minSize = options.min_size;
    const maxSize = options.max_size;
    delete options.min_size;
    delete options.max_size;
    if (typeof options.default === "string") {
      options.default = BufferSizeParser.parseSize(options.default);
    }
    super(options);
    this.minSize = minSize;
    this.maxSize = maxSize;
  }

  private static parseSize(value: string) {
    const match = /^(\d+)(k|m|g|kb|mb|gb)?$/i.exec(value);
    if (!match) {
      throw new TypeError("invalid size");
    }
    const sizeValue = parseInt(match[1]);
    const unitSuffix = match[2]?.toLowerCase();
    if (!unitSuffix) {
      return sizeValue;
    }
    if (unitSuffix == "k" || unitSuffix == "kb") {
      return sizeValue * 1024;
    }
    if (unitSuffix == "m" || unitSuffix == "mb") {
      return sizeValue * 1024 * 1024;
    }
    if (unitSuffix == "g" || unitSuffix == "gb") {
      return sizeValue * 1024 * 1024 * 1024;
    }
    return undefined;
  }

  call(parser, namespace, values /* , option_string = undefined */) {
    const bufSize = BufferSizeParser.parseSize(values);
    if (this.minSize && bufSize < BufferSizeParser.parseSize(this.minSize)) {
      throw new TypeError(`less than ${this.minSize}`);
    }
    if (this.maxSize && bufSize > BufferSizeParser.parseSize(this.maxSize)) {
      throw new TypeError(`greater than ${this.maxSize}`);
    }
    namespace[this.dest] = bufSize;
  }
}

const parser = new argparse.ArgumentParser({
  description: "Argparse example",
  formatter_class: argparse.RawTextHelpFormatter,
});

parser.add_argument("-B", "--bufsize", {
  min_size: "1K",
  max_size: "100M",
  default: "1M",
  action: BufferSizeParser,
  metavar: "N",
  help: "buffer chunk size ( 1K <= N <= 100M ). (default: 1M)",
});

console.dir(parser.parse_args());

The error:

/***/node_modules/argparse/argparse.js:2793
                    throw err
                    ^

Error: .call() not defined
    at Action.call (/***/node_modules/argparse/argparse.js:1290:15)
puzrin commented 2 years ago

I can not find problem at first glance, but take a look at https://github.com/lvgl/lv_font_conv/blob/master/lib/cli.js, may be that can help.

lonnywong commented 2 years ago

@puzrin Thanks.

It must be a rollup issue.


var argparse = {exports: {}};

(function (module) {

// Copyright (C) 2010-2020 Python Software Foundation.
// Copyright (C) 2020 argparse.js authors

/////////// The argparse.js source ///////////

// end
}(argparse));

var BufferSizeParser = /** @class */ (function (_super) {
    __extends(BufferSizeParser, _super);
    function BufferSizeParser(options) {
        var _this = this;
        var minSize = options.min_size;
        var maxSize = options.max_size;
        delete options.min_size;
        delete options.max_size;
        if (typeof options["default"] === "string") {
            options["default"] = BufferSizeParser.parseSize(options["default"]);
        }
        _this = _super.call(this, options) || this;
        _this.minSize = minSize;
        _this.maxSize = maxSize;
        return _this;
    }
    BufferSizeParser.parseSize = function (value) {
        var _a;
        var match = /^(\d+)(k|m|g|kb|mb|gb)?$/i.exec(value);
        if (!match) {
            throw new TypeError("invalid size");
        }
        var sizeValue = parseInt(match[1]);
        var unitSuffix = (_a = match[2]) === null || _a === void 0 ? void 0 : _a.toLowerCase();
        if (!unitSuffix) {
            return sizeValue;
        }
        if (unitSuffix == "k" || unitSuffix == "kb") {
            return sizeValue * 1024;
        }
        if (unitSuffix == "m" || unitSuffix == "mb") {
            return sizeValue * 1024 * 1024;
        }
        if (unitSuffix == "g" || unitSuffix == "gb") {
            return sizeValue * 1024 * 1024 * 1024;
        }
        return undefined;
    };
    BufferSizeParser.prototype.call = function (parser, namespace, values /* , option_string = undefined */) {
        var bufSize = BufferSizeParser.parseSize(values);
        if (this.minSize && bufSize < BufferSizeParser.parseSize(this.minSize)) {
            throw new TypeError("less than ".concat(this.minSize));
        }
        if (this.maxSize && bufSize > BufferSizeParser.parseSize(this.maxSize)) {
            throw new TypeError("greater than ".concat(this.maxSize));
        }
        // @ts-ignore
        namespace[this.dest] = bufSize;
    };
    return BufferSizeParser;
}(argparse.exports.Action));

var parser = new argparse.exports.ArgumentParser({
    description: "Argparse example",
    formatter_class: argparse.exports.RawTextHelpFormatter
});

parser.add_argument("-B", "--bufsize", {
    min_size: "1K",
    max_size: "100M",
    "default": "1M",
    action: BufferSizeParser,
    metavar: "N",
    help: "buffer chunk size ( 1K <= N <= 100M ). (default: 1M)"
});

console.dir(parser.parse_args());
puzrin commented 2 years ago

Closing?

lonnywong commented 2 years ago

Is there something incompatible with rollup ?

export default [ { input: "src/trz.ts", output: { file: "lib/trz.js", format: "cjs", sourcemap: true, }, plugins: [typescript(), commonjs()], }, ];

lonnywong commented 2 years ago

I change TypeScript to CommonJS, and it works.