Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ubuntu 17 apt-get installs cmdtest instead of yarn #3189

Closed
vitalymak opened this issue Apr 19, 2017 · 18 comments
Closed

Ubuntu 17 apt-get installs cmdtest instead of yarn #3189

vitalymak opened this issue Apr 19, 2017 · 18 comments

Comments

@vitalymak
Copy link

Freshly installed Ubuntu 17.04 installs http://liw.fi/cmdtest/ instead of yarnpkg/yarn

vit@vit-u17:~$ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
[sudo] password for vit: 
OK
vit@vit-u17:~$ sudo apt-get update && sudo apt-get install yarn
Get:1 http://security.ubuntu.com/ubuntu zesty-security InRelease [89,2 kB]
Get:2 http://security.ubuntu.com/ubuntu zesty-security/main amd64 DEP-11 Metadata [204 B]
Ign:3 http://dl.google.com/linux/chrome/deb stable InRelease   
Get:4 http://dl.google.com/linux/chrome/deb stable Release [1.189 B]
Get:5 http://dl.google.com/linux/chrome/deb stable Release.gpg [916 B]
Get:6 http://dl.google.com/linux/chrome/deb stable/main amd64 Packages [1.459 B]
Hit:7 http://by.archive.ubuntu.com/ubuntu zesty InRelease
Get:8 http://by.archive.ubuntu.com/ubuntu zesty-updates InRelease [89,2 kB]
Hit:9 http://by.archive.ubuntu.com/ubuntu zesty-backports InRelease
Get:10 http://by.archive.ubuntu.com/ubuntu zesty-updates/main amd64 DEP-11 Metadata [208 B]
Fetched 182 kB in 5s (32,9 kB/s)                   
Reading package lists... Done
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Note, selecting 'cmdtest' instead of 'yarn'
The following additional packages will be installed:
  python-chardet python-cliapp python-markdown python-pkg-resources
  python-pygments python-ttystatus python-yaml
Suggested packages:
  libjs-jquery libjs-underscore python-xdg python-markdown-doc
  python-setuptools ttf-bitstream-vera
The following NEW packages will be installed:
  cmdtest python-chardet python-cliapp python-markdown python-pkg-resources
  python-pygments python-ttystatus python-yaml
0 upgraded, 8 newly installed, 0 to remove and 0 not upgraded.
Need to get 1.080 kB of archives.
After this operation, 5.609 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://by.archive.ubuntu.com/ubuntu zesty/main amd64 python-yaml amd64 3.12-1 [115 kB]
Get:2 http://by.archive.ubuntu.com/ubuntu zesty/universe amd64 python-cliapp all 1.20160724-2 [76,8 kB]
Get:3 http://by.archive.ubuntu.com/ubuntu zesty/universe amd64 python-ttystatus all 0.34-1 [13,7 kB]
Get:4 http://by.archive.ubuntu.com/ubuntu zesty/universe amd64 python-markdown all 2.6.8-1 [55,2 kB]
Get:5 http://by.archive.ubuntu.com/ubuntu zesty/universe amd64 cmdtest all 0.27-1 [19,4 kB]
Get:6 http://by.archive.ubuntu.com/ubuntu zesty/main amd64 python-pkg-resources all 33.1.1-1 [127 kB]
Get:7 http://by.archive.ubuntu.com/ubuntu zesty/main amd64 python-chardet all 2.3.0-2 [96,3 kB]
Get:8 http://by.archive.ubuntu.com/ubuntu zesty/main amd64 python-pygments all 2.2.0+dfsg-1 [577 kB]
Fetched 1.080 kB in 3s (325 kB/s)    
Selecting previously unselected package python-yaml.
(Reading database ... 169947 files and directories currently installed.)
Preparing to unpack .../0-python-yaml_3.12-1_amd64.deb ...
Unpacking python-yaml (3.12-1) ...
Selecting previously unselected package python-cliapp.
Preparing to unpack .../1-python-cliapp_1.20160724-2_all.deb ...
Unpacking python-cliapp (1.20160724-2) ...
Selecting previously unselected package python-ttystatus.
Preparing to unpack .../2-python-ttystatus_0.34-1_all.deb ...
Unpacking python-ttystatus (0.34-1) ...
Selecting previously unselected package python-markdown.
Preparing to unpack .../3-python-markdown_2.6.8-1_all.deb ...
Unpacking python-markdown (2.6.8-1) ...
Selecting previously unselected package cmdtest.
Preparing to unpack .../4-cmdtest_0.27-1_all.deb ...
Unpacking cmdtest (0.27-1) ...
Selecting previously unselected package python-pkg-resources.
Preparing to unpack .../5-python-pkg-resources_33.1.1-1_all.deb ...
Unpacking python-pkg-resources (33.1.1-1) ...
Selecting previously unselected package python-chardet.
Preparing to unpack .../6-python-chardet_2.3.0-2_all.deb ...
Unpacking python-chardet (2.3.0-2) ...
Selecting previously unselected package python-pygments.
Preparing to unpack .../7-python-pygments_2.2.0+dfsg-1_all.deb ...
Unpacking python-pygments (2.2.0+dfsg-1) ...
Setting up python-yaml (3.12-1) ...
Setting up python-ttystatus (0.34-1) ...
Setting up python-cliapp (1.20160724-2) ...
Setting up python-pkg-resources (33.1.1-1) ...
Setting up python-pygments (2.2.0+dfsg-1) ...
Processing triggers for man-db (2.7.6.1-2) ...
Setting up python-markdown (2.6.8-1) ...
Setting up python-chardet (2.3.0-2) ...
Setting up cmdtest (0.27-1) ...
vit@vit-u17:~$ yarn --version
0.27
vit@vit-u17:~$ which yarn
/usr/bin/yarn
vit@vit-u17:~$ cat /usr/bin/yarn
#! /usr/bin/python
# Copyright 2013  Lars Wirzenius
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# =*= License: GPL-3+ =*=


import cliapp
import collections
import locale
import logging
import os
import re
import shutil
import sys
import tempfile
import time
import ttystatus

import yarnlib


class YarnRunner(cliapp.Application):

    def add_settings(self):
        self.settings.boolean(
            ['no-act', 'dry-run', 'pretend', 'n'],
            'do not actually run any tests, merely print what would be run')

        self.settings.boolean(
            ['quiet', 'q'],
            'be quiet, avoid progress reporting, only show errors')

        self.settings.boolean(
            ['verbose', 'v'],
            'make progress reporting be more verbose ("wall of text"), '
                'instead of a one-line status info; this is turned '
                'automatically if there is not terminal')

        self.settings.string_list(
            ['shell-library', 's'],
            'include a shell library for the IMPLEMENTS sections to use')

        self.settings.string_list(
            ['run', 'r'],
            'run only SCENARIO (this option can be repeated)',
            metavar='SCENARIO')

        self.settings.string(
            ['tempdir'],
            'use DIR as the temporary directory for tests; '
                'it should be empty or not exist',
            metavar='DIR')

        self.settings.string_list(
            ['env'],
            'add NAME=VALUE to the environment when tests are run',
            metavar='NAME=VALUE')

        self.settings.boolean(
            ['snapshot'],
            'make snapshots of test working directory '
                'after each scenario step; you probably '
                'want to use this with --tempdir')

        self.settings.boolean(
            ['timings'],
            'report wall clock time for each scenario and step')

        self.settings.boolean(
            ['allow-missing-steps'],
            'allow scenarios to reference steps that do not exist, '
            'by warning about them, but otherwise ignoring the scenarios')

        self.settings.boolean(
            ['require-assumptions'],
            'require ASSUMING to always pass')

        self.settings.string(
            ['shell'],
            'run IMPLEMENTS using SHELL',
            metavar='SHELL',
            default='/bin/sh')

        self.settings.string_list(
            ['shell-arg'],
            'use ARG when running shell',
            metavar='ARG',
            default=['-xeu'])

        self.settings.boolean(
            ['cd-datadir'],
            'change to DATADIR when running commands',
            default=False)

        self.settings.boolean(
            ['stop-on-first-fail'],
            "stop if any scenario step fails, don't run more scenarios")

    def stdout(self, msg):
        self._write(sys.stdout, msg)

    def stderr(self, msg):
        self._write(sys.stderr, msg)

    def _write(self, output, msg):
        if isinstance(msg, unicode):
            msg = msg.encode(locale.getpreferredencoding())
        output.write(msg)
        output.flush()

    def info(self, indent, msg):
        if self.settings['verbose']:
            logging.info(msg)
            indent_size = 4
            self.stdout('%*s%s\n' % (indent * indent_size, '', msg))

    def warning(self, msg):
        if self.settings['verbose']:
            logging.warning(msg)
            self.stdout('WARNING: %s\n' % msg)
        elif not self.settings['quiet']:
            self.ts.notify('WARNING: %s' % msg)

    def error(self, msg):
        if self.settings['verbose']:
            logging.info(msg)
            self.stderr('%s\n' % msg)
        elif not self.settings['quiet']:
            self.ts.error(msg)

    def process_args(self, args):
        # Do we have tty? If not, turn on --verbose, unless --quiet.
        if not self.settings['quiet']:
            try:
                open('/dev/tty', 'w')
            except IOError:
                self.settings['verbose'] = True

        self.ts = ttystatus.TerminalStatus(period=0.001)
        if not self.settings['quiet'] and not self.settings['verbose']:
            self.ts.format(
                '%ElapsedTime() %Index(current_step,all_steps): '
                '%String(scenario_name): '
                '%String(step_name)')

        scenarios, implementations = self.parse_scenarios(args)
        self.check_there_are_scenarios(scenarios)
        self.check_for_duplicate_scenario_names(scenarios)
        self.check_for_thens(scenarios)
        scenarios = self.connect_implementations(scenarios, implementations)
        shell_prelude = self.load_shell_libraries()

        self.info(0, 'Found %d scenarios' % len(scenarios))

        all_steps = []
        for scenario in scenarios:
            all_steps.extend(scenario.steps)
        self.ts['all_steps'] = all_steps

        self.scenarios_run = 0
        self.skipped_for_assuming = 0
        self.steps_run = 0
        self.timings = []

        start_time = time.time()
        failed_scenarios = []
        for scenario in self.select_scenarios(scenarios):
            if not self.run_scenario(scenario, shell_prelude):
                failed_scenarios.append(scenario)
                if self.settings['stop-on-first-fail']:
                    break
        duration = time.time() - start_time

        if not self.settings['quiet']:
            self.ts.clear()
            self.ts.finish()

        if failed_scenarios:
            self.stderr('Failed scenarios:\n')
            for scenario in failed_scenarios:
                self.stderr('    - %s\n' % scenario.name)
            raise cliapp.AppException(
                'Test suite FAILED in %s scenarios' % len(failed_scenarios))

        if not self.settings['quiet']:
            self.stdout(
                'Scenario test suite PASS, with %d scenarios '
                '(%d total steps), '
                'in %.1f seconds\n' %
                (self.scenarios_run, self.steps_run, duration))
            if self.skipped_for_assuming:
                self.stdout(
                    'Scenarios SKIPPED due to ASSUMING step failing: %d\n'
                    % self.skipped_for_assuming)

        if self.settings['timings']:
            self.report_timings()

    def parse_scenarios(self, filenames):
        mdparser = yarnlib.MarkdownParser()
        for filename in filenames:
            self.info(0, 'Parsing scenario file %s' % filename)
            blocks = mdparser.parse_file(filename)

        block_parser = yarnlib.BlockParser()
        block_parser.parse_blocks(mdparser.blocks)

        return block_parser.scenarios, block_parser.implementations

    def check_there_are_scenarios(self, scenarios):
        if not scenarios:
            raise cliapp.AppException(
                'There are no scenarios; must have at least one.')

    def check_for_duplicate_scenario_names(self, scenarios):
        counts = collections.Counter()
        for s in scenarios:
            counts[s.name] += 1

        duplicates = [name for name in counts if counts[name] > 1]
        if duplicates:
            duplist = ''.join('  %s\n' % name for name in duplicates)
            raise cliapp.AppException(
                'There are scenarios with duplicate names:\n%s' % duplist)

    def check_for_thens(self, scenarios):
        no_thens = []
        for scenario in scenarios:
            for step in scenario.steps:
                if step.what == 'THEN':
                    break
            else:
                no_thens.append(scenario)

        if no_thens:
            raise cliapp.AppException(
                'Some scenarios have no THENs:\n%s' %
                ''.join('  "%s"\n' % s.name for s in no_thens))

    def connect_implementations(self, scenarios, implementations):
        new_list = []
        for scenario in scenarios:
            missing_step = False
            for step in scenario.steps:
                self.connect_implementation(
                    scenario, step, implementations)
                if step.implementation is None:
                    missing_step = True
            if not missing_step:
                new_list.append(scenario)
        return new_list

    def connect_implementation(self, scenario, step, implementations):
        matching = [i for i in implementations
                    if step.what == i.what and
                       self.implements_matches_step(i, step)]

        if len(matching) == 0:
            if self.settings['allow-missing-steps']:
                self.warning(
                    'Scenario %s has missing step %s %s' %
                    (scenario.name, step.what, step.text))
                return
            raise cliapp.AppException(
                'Scenario "%s", step "%s %s" has no matching '
                'implementation' %
                (scenario.name, step.what, step.text))
        if len(matching) > 1:
            s = '\n'.join(
                'IMPLEMENTS %s %s' % (i.what, i.regexp)
                for i in matching)
            raise cliapp.AppException(
                'Scenario "%s", step "%s %s" has more than one '
                'matching implementations:\n%s' %
                (scenario.name, step.what, step.text, s))

        assert step.implementation is None
        step.implementation = matching[0]

    def load_shell_libraries(self):
        if not self.settings['shell-library']:
            self.info(0, 'No shell libraries defined')
            return ''

        libs = []
        for filename in self.settings['shell-library']:
            self.info(0, 'Loading shell library %s' % filename)
            with open(filename) as f:
                text = f.read()
            libs.append('# Loaded from %s\n\n%s\n\n' % (filename, text))

        return ''.join(libs)

    def select_scenarios(self, scenarios):

        def normalise(s):
            return ' '.join(s.lower().split())

        def matches(a, b):
            return normalise(a) == normalise(b)

        if self.settings['run']:
            result = []
            for name in self.settings['run']:
                for s in scenarios:
                    if matches(s.name, name) and s not in result:
                        result.append(s)
                        break
                else:
                    raise cliapp.AppException(
                        'Requested scenario %s does not exist' %
                        name)
            return result

        return scenarios

    def run_scenario(self, scenario, shell_prelude):
        self.start_scenario_timing(scenario.name)
        started = time.time()

        self.info(0, 'Running scenario %s' % scenario.name)
        self.ts['scenario_name'] = scenario.name.encode('utf-8')
        self.ts.flush()
        self.scenarios_run += 1

        if self.settings['no-act']:
            self.info(0, 'Pretending everything went OK')
            for step in scenario.steps:
                self.ts['current_step'] = step
                self.ts.flush()
            self.remember_scenario_timing(time.time() - started)
            return True

        if self.settings['tempdir']:
            tempdir = os.path.abspath(self.settings['tempdir'])
            if not os.path.exists(tempdir):
                os.mkdir(tempdir)
        else:
            tempdir = tempfile.mkdtemp()

        os.mkdir(self.scenario_dir(tempdir, scenario))
        datadir = self.datadir(tempdir, scenario)
        os.mkdir(datadir)
        self.info(1, 'DATADIR is %s' % datadir)
        homedir = self.homedir(datadir)
        os.mkdir(homedir)
        self.info(1, 'HOME for tests is %s' % homedir)

        assuming = [s for s in scenario.steps if s.what == 'ASSUMING']
        cleanup = [s for s in scenario.steps if s.what == 'FINALLY']
        normal = [s for s in scenario.steps if s not in assuming + cleanup]

        ok = True
        step_number = 0

        for step in assuming:
            exit = self.run_step(datadir, scenario, step, shell_prelude, False)
            step_number += 1
            self.snapshot_datadir(
                tempdir, datadir, scenario, step_number, step)
            if self.settings['require-assumptions'] and exit != 0:
                ok = False
                break
            elif exit != 0:
                self.ts.notify(
                    'Skipping "%s" because "%s %s" failed' %
                    (scenario.name, step.what, step.text))
                self.skipped_for_assuming += 1
                break
        else:
            for step in normal:
                exit = self.run_step(
                    datadir, scenario, step, shell_prelude, True)
                step_number += 1
                self.snapshot_datadir(
                    tempdir, datadir, scenario, step_number, step)
                if exit != 0:
                    ok = False
                    break

            for step in cleanup:
                exit = self.run_step(
                    datadir, scenario, step, shell_prelude, True)
                step_number += 1
                self.snapshot_datadir(
                    tempdir, datadir, scenario, step_number, step)
                if exit != 0:
                    ok = False
                    break

        if not self.settings['snapshot']:
            shutil.rmtree(tempdir, ignore_errors=True)

        self.remember_scenario_timing(time.time() - started)
        return ok

    def homedir(self, datadir):
        return os.path.join(datadir, 'HOME')

    def clean_env(self):
        '''Return a clean environment for running tests.'''

        whitelisted = [
            'PATH',
        ]

        hardcoded = {
            'TERM': 'dumb',
            'SHELL': '/bin/sh',
            'LC_ALL': 'C',
            'USER': 'tomjon',
            'USERNAME': 'tomjon',
            'LOGNAME': 'tomjon',
        }

        env = {}

        for key in whitelisted:
            if key in os.environ:
                env[key] = os.environ[key]

        for key in hardcoded:
            env[key] = hardcoded[key]

        for option_arg in self.settings['env']:
            if '=' not in option_arg:
                raise cliapp.AppException(
                    '--env argument must contain "=" '
                    'to separate environment variable name and value')
            key, value = option_arg.split('=', 1)
            env[key] = value

        return env

    def run_step(self, datadir, scenario, step, shell_prelude, report_error):
        started = time.time()

        self.info(1, 'Running step "%s %s"' % (step.what, step.text))
        self.ts['current_step'] = step
        self.ts['step_name'] = '%s %s' % (step.what, step.text.encode('utf8'))
        self.ts.flush()
        self.steps_run += 1

        m = self.implements_matches_step(step.implementation, step)
        assert m is not None
        env = self.clean_env()
        env['DATADIR'] = datadir
        env['SRCDIR'] = os.getcwd()
        env['HOME'] = self.homedir(datadir)
        for i, match in enumerate(m.groups('')):
            env['MATCH_%d' % (i+1)] = match.encode('utf-8')
        self.add_srcdir_to_pythonpath(env, env['SRCDIR'])

        if self.settings['cd-datadir']:
            cwd = datadir
        else:
            cwd = '.'

        fd, shell_script = tempfile.mkstemp()
        os.close(fd)
        with open(shell_script, 'w') as f:
            f.write(shell_prelude)
            f.write(step.implementation.shell)
            f.flush()
        shell = self.settings['shell']
        shell_args = [x for x in self.settings['shell-arg'] if x]
        logging.debug('shell: %r', shell)
        logging.debug('shell_args: %r', shell_args)
        logging.debug('shell_script: %r', shell_script)
        exit, stdout, stderr = cliapp.runcmd_unchecked(
            [shell] + shell_args + [shell_script],
            env=env, cwd=cwd)
        os.remove(shell_script)

        logging.debug('Exit code: %d' % exit)
        if stdout:
            logging.debug('Standard output:\n%s' % self.indent(stdout))
        else:
            logging.debug('Standard output: empty')
        if stderr:
            logging.debug('Standard error:\n%s' % self.indent(stderr))
        else:
            logging.debug('Standard error: empty')

        if exit != 0 and report_error:
            self.error('ERROR: In scenario "%s"' % scenario.name)
            self.error('step "%s %s" failed,' % (step.what, step.text))
            self.error('with exit code %d:' % exit)
            self.error('Standard output from shell command:\n%s' %
                       self.indent(stdout))
            self.error('Standard error from shell command:\n%s' %
                       self.indent(stderr))

        self.remember_step_timing(
            '%s %s' % (step.what, step.text), time.time() - started)

        return exit

    def add_srcdir_to_pythonpath(self, env, srcdir):
        # Special handling of PYTHONPATH. Add $SRCDIR to it so that
        # Python IMPLEMENTS can use it. But only if --shell=python is
        # used. This is a bit of magic that hopefully won't surprise
        # users too much.

        if self.settings['shell'] == 'python':
            pythonpath = env.get('PYTHONPATH', None)
            if pythonpath:
                pythonpath += ':' + srcdir
            else:
                pythonpath = srcdir
            env['PYTHONPATH'] = pythonpath

    def scenario_dir(self, tempdir, scenario):
        return os.path.join(tempdir, self.nice(scenario.name))

    def datadir(self, tempdir, scenario):
        sd = self.scenario_dir(tempdir, scenario)
        return os.path.join(sd, 'datadir')

    def snapshot_dir(self, tempdir, scenario, step, step_number):
        sd = self.scenario_dir(tempdir, scenario)
        base = '%03d-%s-%s' % (step_number, step.what, self.nice(step.text))
        return os.path.join(sd, base)

    def snapshot_datadir(self, tempdir, datadir, scenario, step_number, step):
        if self.settings['snapshot']:
            snapshot = self.snapshot_dir(tempdir, scenario, step, step_number)
            exit, out, err = cliapp.runcmd_unchecked(
                ['cp', '-ax', datadir, snapshot])
            if exit != 0:
                logging.warning('Snapshot copy failed:\n%s\n%s' % (out, err))

    def nice(self, name):
        # Quote a scenario or step name so it forms a nice filename.
        nice_chars = "abcdefghijklmnopqrstuvwxyz"
        nice_chars += nice_chars.upper()
        nice_chars += "0123456789-."

        nice = []
        for c in name:
            if c in nice_chars:
                nice.append(c)
            elif not nice or nice[-1] != '_':
                nice.append('_')
        nice = ''.join(nice)
        return nice

    def implements_matches_step(self, implements, step):
        '''Return re.Match if implements matches the step.

        Otherwise, return None.

        '''

        m = re.match(implements.regexp, step.text, re.I)
        if m and m.end() != len(step.text):
            return None
        return m

    def indent(self, s):
        return ''.join('    %s\n' % line for line in s.splitlines())

    def start_scenario_timing(self, scenario_name):
        self.timings.append((scenario_name, None, []))

    def remember_scenario_timing(self, duration):
        scenario_name, _, step_tuples = self.timings[-1]
        self.timings[-1] = (scenario_name, duration, step_tuples)

    def remember_step_timing(self, step_name, step_duration):
        scenario_name, scenario_duration, step_tuples = self.timings[-1]
        step_tuples = step_tuples + [(step_name, step_duration)]
        self.timings[-1] = (scenario_name, scenario_duration, step_tuples)

    def report_timings(self):
        for scenario_name, scenario_duration, step_tuples in self.timings:
            self.stdout('%5.1f %s' % (scenario_duration, scenario_name))
            for step_name, step_duration in step_tuples:
                self.stdout('  %5.1f %s' % (step_duration, step_name))


YarnRunner(version=yarnlib.__version__).run()
@vitalymak
Copy link
Author

That was actually my fault. I didn't add package repository properly.

@pekeler
Copy link

pekeler commented May 30, 2017

I just ran into the same problem. For some reason, echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list didn't get pasted correctly. Also needed to sudo apt-get remove cmdtest to get it working.

@dsblank
Copy link

dsblank commented Jun 3, 2017

Also note that after adding the yarn package, you need to sudo apt update before attempting to install it again.

@tspesh
Copy link

tspesh commented Jul 12, 2017

@pekeler and @dsblank thanks for the help here!

@JSONRice
Copy link

@vitalymak this is an abomination. I ran into the same issue and this resolved it:

sudo apt-get remove cmdinstall;sudo apt update;sudo apt-get install yarn

@aperkaz
Copy link

aperkaz commented Dec 18, 2017

Thanks @jasonwr for the tip, I was getting issues in Ubuntu 17.04, now its working like a charm 🙂

@JSONRice
Copy link

JSONRice commented Jan 3, 2018 via email

@GaneshPandiyan
Copy link

GaneshPandiyan commented Mar 8, 2018

I also using ubuntu 17.10 use below code to install yarn
sudo apt-get remove cmdtest; sudo apt update; sudo apt-get install yarn

@samsammurphy
Copy link

I also just ran into this issue.

@sumudu-Jayasinghe
Copy link

sumudu-Jayasinghe commented Apr 26, 2018

Remove cmdtest
sudo apt-get purge cmdtest

install yarn manually

cd /opt
wget https://yarnpkg.com/latest.tar.gz
tar zvxf latest.tar.gz
Yarn is now in /opt/yarn-[version]/

Add this to your profile: export PATH="$PATH:/opt/yarn-[version]/bin" (the path may vary depending on where you extracted Yarn to)

@jacobq
Copy link

jacobq commented Jun 1, 2018

In case it's helpful, I ran into this because I didn't notice that the apt repository for yarn wasn't getting used due to:

Reading package lists... Done 
E: The method driver /usr/lib/apt/methods/https could not be found.
N: Is the package apt-transport-https installed?
E: Failed to fetch https://dl.yarnpkg.com/debian/dists/stable/InRelease  
E: Some index files failed to download. They have been ignored, or old ones used instead.

Running sudo apt-get install apt-transport-https; sudo apt-get update; sudo apt-get install --no-install-recommends yarn did the trick.

@ghost
Copy link

ghost commented Jun 26, 2018

https://stackoverflow.com/questions/46013544/yarn-install-command-error-no-such-file-or-directory-install

This worked for me

@tatsujb
Copy link

tatsujb commented Mar 30, 2020

guys the apt-get install instead of apt install hacks no longer works even if you add --no-install-recommends.
now cmdtest installs no matter what you do.
I don't see how this can happen.

cmdtest is called cmdtest yarn is called yarn those are completely different names and completely unrelated packages with completely uncomparable popularity. yarn is in the default repos we shouldn't have to be resorting to an external repo to get it installed!!

jgrund added a commit to whamcloud/integrated-manager-for-lustre that referenced this issue Apr 7, 2020
The iml-gui docker image has started hitting
yarnpkg/yarn#3189.

Make sure we update after adding the yarn source to avoid this.

Signed-off-by: Joe Grund <jgrund@whamcloud.io>
jgrund added a commit to whamcloud/integrated-manager-for-lustre that referenced this issue Apr 7, 2020
The iml-gui docker image has started hitting
yarnpkg/yarn#3189.

Make sure we update after adding the yarn source to avoid this.

Signed-off-by: Joe Grund <jgrund@whamcloud.io>
@AkashicSeer
Copy link

This truly, truly sucks. I may have to switch entire operating systems just to be able to run an app that uses javascript YARN are you shitting me? Nothing I do will let me run yarn commands on ubuntu. I've tried installing it every way I can find on the internet. I've removed cmdtest, I've even tried installing npm then using it to install yarn and still no go on using any, none of yarn any command. I have about had it with Ubuntu and it's quirky bullshit.
baby seriously

@glenfish
Copy link

sudo apt remove cmdtest
sudo apt remove yarn
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update
sudo apt-get install yarn

This worked for me after trying everything else i could find on many posts and sites

@Amr-Ibra
Copy link

Amr-Ibra commented May 22, 2021

A little of research will tell you that the cmdtest package in Debian (and Ubuntu) has a tool called yarn, and it has been there since 2012, so they own the name before yarnpkg.

In Debian testing (and Ubuntu 20.10), you can install a native yarnpkg package (version 1.22.10) by doing:
sudo apt install yarnpkg

And the binary command is yarnpkg, in order not to conflict with yarn from cmdtest.
But it works best if you have the native nodejs package installed in Debian.

@fabpico
Copy link

fabpico commented Jul 28, 2021

Happened also on Ubuntu 20.04.1. Commands cmdtest and cmdinstall weren't even available, but sudo apt-get install yarn also did Note, selecting 'cmdtest' instead of 'yarn'.

But then I could install yarn with #3189 (comment) .

@shiv-gt
Copy link

shiv-gt commented Feb 17, 2024

bro #3189 (comment) worked for me can't believe wasted so much time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests