<commit_before>//----------------------------------------------------------------------
//
// This source file is part of the furipota project.
//
// Licensed under MIT. See LICENCE for full licence information.
// See CONTRIBUTORS for the list of contributors to the project.
//
//----------------------------------------------------------------------


const program = require('commander');
const path = require('path');
const { FuripotaVM } = require('./vm');
const { typeMatches } = require('./vm/types');
const { show } = require('./vm/primitives');
const { inspect } = require('util');
const package = require('../package.json');


const vm = new FuripotaVM();


function showError(error) {
  if (error.isFuripotaError) {
    console.error(error.message);
  } else {
    console.error(error.stack);
  }
}


program.version(package.version);

program.command('run <expression>')
  .option('-f, --file <file>', 'A file providing build definitions (default: build.frp)', 'build.frp')
  .description(`Runs the provided pipeline to completion.`)
  .action(async (expr, options) => {
    try {
      const fullPath = path.resolve(process.cwd(), options.file);
      const module = vm.loadModule(fullPath, 'furipota');
      const ast = vm.parseExpression(expr);
      const context = vm.context(module, module.environment);
      const stream = vm.evaluate(ast, context);

      if (typeMatches('Stream', stream)) {
        stream.subscribe({
          Value: ()  => {},
          Error: (e) => { console.error('Error:', e) },
          Close: ()  => {}
        });
        await stream.run();
      } else {
        console.log(inspect(show(context, stream), false, 5, true));
      }
    } catch (error) {
      showError(error);
      process.exit(1);
    }
  });

program.command('list')
  .option('-f, --file <file>', 'A file providing build definitions (default: build.frp)', 'build.frp')
  .description(`Lists available commands.`)
  .action(async (options) => {
    try {
      const fullPath = path.resolve(process.cwd(), options.file);
      const module = vm.loadModule(fullPath, 'furipota');

      console.log('');
      console.log('Available commands:');
      console.log('-------------------');
      console.log('');

      const bindings = module.exportedBindings;
      const keys = Object.keys(bindings);
      const size = Math.max(...keys.map(x => x.length)) + 6;<commit_msg>Fixes the exit status in case of error<commit_after>//----------------------------------------------------------------------
//
// This source file is part of the furipota project.
//
// Licensed under MIT. See LICENCE for full licence information.
// See CONTRIBUTORS for the list of contributors to the project.
//
//----------------------------------------------------------------------


const program = require('commander');
const path = require('path');
const { FuripotaVM } = require('./vm');
const { typeMatches } = require('./vm/types');
const { show } = require('./vm/primitives');
const { inspect } = require('util');
const package = require('../package.json');
const Maybe = require('folktale/maybe');


const vm = new FuripotaVM();


function showError(error) {
  if (error.isFuripotaError) {
    console.error(error.message);
  } else if (error instanceof Error) {
    console.error(error.stack);
  } else {
    console.error(error);
  }
}


function die(expr, error) {
  console.error(`\n\n${'-'.repeat(3)}`);
  console.error(`There was a problem trying to execute ${JSON.stringify(expr)}.\n`);
  showError(error);
  process.exit(1);
}


program.version(package.version);

program.command('run <expression>')
  .option('-f, --file <file>', 'A file providing build definitions (default: build.frp)', 'build.frp')
  .description(`Runs the provided pipeline to completion.`)
  .action(async (expr, options) => {
    try {
      const fullPath = path.resolve(process.cwd(), options.file);
      const module = vm.loadModule(fullPath, 'furipota');
      const ast = vm.parseExpression(expr);
      const context = vm.context(module, module.environment);
      const stream = vm.evaluate(ast, context);

      if (typeMatches('Stream', stream)) {
        stream.subscribe({
          Value: ()  => { },
          Error: (e) => { 
            die(expr, e);
          },
          Close: ()  => { }
        });
        await stream.run();
      } else {
        console.log(inspect(show(context, stream), false, 5, true));
      }
    } catch (error) {
      die(expr, error);
    }
  });

program.command('list')
  .option('-f, --file <file>', 'A file providing build definitions (default: build.frp)', 'build.frp')
  .description(`Lists available commands.`)
  .action(async (options) => {
    try {
      const fullPath = path.resolve(process.cwd(), options.file);
      const module = vm.loadModule(fullPath, 'furipota');

      console.log('');
      console.log('Available commands:');
      console.log('-------------------');
      console.log('');

      const bindings = module.exportedBindings;
      const keys = Object.keys(bindings);
      const size = Math.max(...keys.map(x => x.length)) + 6;
{'fraction_non_alphanumeric': 0.22100528065714845, 'fraction_numerical': 0.0013690592607079992, 'mean_word_length': 2.3889993373094764, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1592883', 'n_tokens_mistral': 1480, 'n_tokens_neox': 1450, 'n_words': 365}