Hagith
2/22/2017 - 3:21 PM

vue-gettext-cli.js

const spawn = require('child_process').spawn;
const glob = require('glob');
const fs = require('fs');
const path = require('path');
const which = require('which');
const availableLanguages = require('./available');

try {
  which.sync('xgettext');
  which.sync('msgmerge');
  which.sync('msginit');
  which.sync('msgattrib');
} catch (e) {
  console.error(e);
  process.exit(-1);
}

const cwd = './src';
const localePath = `${cwd}/locale`;
const template = `${localePath}/dictionary.pot`;
const translations = `${localePath}/translations.json`;
const locales = Object.keys(availableLanguages);
const sourcePath = `${cwd}/javascript/**`;

function spawnPromise(cmd, args) {
  return new Promise((resolve, reject) => {
    const proc = spawn(cmd, args, {
      shell: true,
      stdio: 'inherit',
    });

    proc.on('error', e => reject(e));
    proc.on('close', (code) => {
      if (code === 0) {
        resolve();
      } else {
        reject(new Error(`process exited with code ${code}`));
      }
    });
  });
}

function extract(files) {
  const args = [`--output ${template}`].concat(files);
  return spawnPromise('gettext-extract', args).then(() => {
    const sources = glob.sync(`${sourcePath}/*.{js,vue}`);
    return spawnPromise('xgettext', [
      '--language=JavaScript',
      '--keyword=npgettext:1c,2,3',
      '--from-code=utf-8',
      '--join-existing',
      '--no-wrap',
      '--omit-header',
      `--output ${template}`,
    ].concat(sources));
  });
}

function compile(files) {
  const args = [`--output ${translations}`].concat(files);
  return spawnPromise('gettext-compile', args);
}

function updateTranslation(locale) {
  const poFile = `${localePath}/${locale}/app.po`;
  if (!fs.existsSync(path.dirname(poFile))) {
    fs.mkdirSync(path.dirname(poFile));
  }

  let cmd;
  let args;
  if (fs.existsSync(poFile)) {
    cmd = 'msgmerge';
    args = [
      `--lang=${locale}`,
      `--update ${poFile}`,
      '--backup=off',
      template,
    ];
  } else {
    cmd = 'msginit';
    args = [
      '--no-translator',
      `--locale=${locale}`,
      `--input=${template}`,
      `--output-file=${poFile}`,
    ];
  }

  return spawnPromise(cmd, args)
    .then(() => spawnPromise('msgattrib', [
      '--no-wrap',
      '--no-obsolete',
      `-o ${poFile}`,
      `${poFile}`,
    ]))
    .then(() => poFile);
}

function generate() {
  return Promise
    .all(locales.map(locale => updateTranslation(locale)))
    .then(poFiles => compile(poFiles));
}

glob(`${sourcePath}/*.{vue,html}`, (e, files) => {
  if (e) {
    console.error(e);
    return;
  }

  extract(files)
    .then(generate)
    .then(() => console.log('DONE!'));
});