Chalk: colors not showing up after spawning child process

Created on 15 Jan 2020  路  7Comments  路  Source: chalk/chalk

environment

Edition - Windows 10 Pro
Version - 1909
OS build - 18363.535

Using Git Bash

details

so I am creating a library to push code to git using some helpful prompts. Those prompts contains some colors too.

Every thing is working perfectly & colors are showing up as they should
until I used a child process (with {stdio: "inherit"}). Child process works perfectly while logging to my stdout.

The actual issue comes after this, no colors are shown & their corresponding codes are displayed now.


check the last line in the above push-code commit control flow. Rather than green color for Successfully commit to git , it is printing its code.

Here is my source-code for debugging (not included the bin entry point since it is not relevant & only tranferring control flow to this file) -

const prompts = require("prompts");
const chalk = require("chalk");
const spawn = require('await-spawn');

/**
 * default commit flow
 * @return {Promise<{}>}
 */
module.exports = async function () {

    // to make sure you wish to commit
    let response = await prompts({
        type: "confirm",
        name: "confirm",
        message: "Sure you wish to commit ?",
    });

    if (response.confirm) {

        const commit = {};

        // select type of commit
        response = await prompts({
            type: "select",
            name: "type",
            message: "Type of commit ?",
            choices: [
                {title: "Improvements", value: "Code Improvements"},
                {title: "Bug Fixes", value: "Bug Fixes"},
                {title: "New Code", value: "New Code"}
            ],
            initial: 0
        });

        commit.type = response.type;

        // ask user for commit message & description
        try {

            // don't worry about message & describe
            // they are working perfectly & returning string
            // not including them to make this code concise
            commit.message = await message();
            commit.describe = await description();


            // running commands
            console.log("\n\n" + chalk.blue("Adding files to git ..."));
            await spawnIO('git', 'add', '.');
            console.log(chalk.green("Successfully added files to git"));

            // committing files
            console.log("\n\n" + chalk.blue("Committing to git ..."));
            await spawnIO('git', 'commit', '-S', '-m', `${commit.type} : ${commit.message}`, '-m', `${commit.describe}`, '--no-verify');
            console.log(chalk.green("Successfully committed to git"));

            return true;

        } catch (e) {
            return Promise.reject(e)
        }

    } else {
        return Promise.reject("Commit cancelled by user")
    }
};

/**
 * spawn a new process with inherited stdio
 * @return {Promise<boolean>}
 */
async function spawnIO(...args) {
    const cmd = args[0];
    args.shift();

    try {
        await spawn(cmd, args, {stdio: 'inherit'});
        return true;
    } catch (e) {
        return Promise.reject("failed to execute the command")
    }
};

note that if I include more flow after the commit step , then no lines are showing the color anymore after this (only their corresponding codes)

weird thing

if the child-process doesn't write to stdout then then next line properly show the the chalk colors like in git add . command in above code & image.

more weird thing

everything is completely working perfectly when using VS-code inbuilt terminal with bash support.

Most helpful comment

I got it working by adding FORCE_COLOR '1' to the environment variables of the forked process:

import { fork } from 'child_process';

const process = fork(
  this.processPath,
  {
    env: { ...process.env, FORCE_COLOR: '1' },
  },
);

All 7 comments

Just a quick question before I investigate: You mentioned you're using Git Bash - are you using just the plain ol' git bash (stock installation) or are you using a modified MinGW environment/a different terminal emulator (e.g. cmdr or mintty, etc.)?

stock git bash installed using Git for Windows

any updates ?

I am also affected by this.

If I run a nodejs programm with chalk without a redirect of the STOUT all is working fine.
When I pipe the STOUT into i.e. the linux command "tee" I lose my color of chalc, while i.e "ololog" stays in color.

As workaround I am starting now my program using "script". Please find more here :
https://stackoverflow.com/questions/27397865/how-to-write-stdout-to-file-with-colors

I got it working by adding FORCE_COLOR '1' to the environment variables of the forked process:

import { fork } from 'child_process';

const process = fork(
  this.processPath,
  {
    env: { ...process.env, FORCE_COLOR: '1' },
  },
);

There are two issues here, neither of which are chalk's fault:

  • The issue in the OP describes a case where the terminal emulator is not honoring escape sequences. Git bash is notorious for this; I recommend using the Windows Terminal downloadable from the windows store.
  • The issue some of the responses are facing are codes not being emitted at all, which is due to the stdio not being inherited properly.

Chalk doesn't concern itself with how stdio is linked up so this is an issue to investigate yourself - we can't provide support here since it's not directly related to chalk.

I got it working by adding FORCE_COLOR '1' to the environment variables of the forked process:

import { fork } from 'child_process';

const process = fork(
  this.processPath,
  {
    env: { ...process.env, FORCE_COLOR: '1' },
  },
);

Wow, I know this is closed, but this worked wonderfully for me! I am using child_process.spawn but still works great! Thanks

Was this page helpful?
0 / 5 - 0 ratings

Related issues

erquhart picture erquhart  路  6Comments

langpavel picture langpavel  路  8Comments

roblg picture roblg  路  7Comments

mfour-merickson picture mfour-merickson  路  8Comments

fearphage picture fearphage  路  7Comments