• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rokucommunity / ropm / #901

17 May 2024 06:41PM UTC coverage: 90.608%. Remained the same
#901

push

TwitchBronBron
0.10.24

515 of 611 branches covered (84.29%)

Branch coverage included in aggregate %.

633 of 656 relevant lines covered (96.49%)

67.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.84
/src/commands/InstallCommand.ts
1
import type { RopmPackageJson } from '../util';
2
import { util } from '../util';
1✔
3
import * as path from 'path';
1✔
4
import * as childProcess from 'child_process';
1✔
5
import * as fsExtra from 'fs-extra';
1✔
6
import { InitCommand } from './InitCommand';
1✔
7
import { CleanCommand } from './CleanCommand';
1✔
8
import { ModuleManager } from '../prefixer/ModuleManager';
1✔
9

10
export class InstallCommand {
1✔
11
    constructor(
12
        public args: InstallCommandArgs
25✔
13
    ) {
14

15
    }
16

17
    private hostPackageJson?: RopmPackageJson;
18

19
    private moduleManager = new ModuleManager();
25✔
20

21
    private get hostRootDir() {
22
        const packageJsonRootDir = this.args.rootDir ?? this.hostPackageJson?.ropm?.rootDir;
20!
23
        if (packageJsonRootDir) {
20✔
24
            return path.resolve(this.cwd, packageJsonRootDir);
4✔
25
        } else {
26
            return this.cwd;
16✔
27
        }
28
    }
29

30
    private get cwd() {
31
        if (this.args?.cwd) {
177!
32
            return path.resolve(process.cwd(), this.args?.cwd);
177!
33
        } else {
34
            return process.cwd();
×
35
        }
36
    }
37

38
    public async run(runNpmInstall = true): Promise<void> {
21✔
39
        await this.loadHostPackageJson();
21✔
40
        await this.deleteAllRokuModulesFolders();
21✔
41
        if (runNpmInstall) {
21!
42
            await this.npmInstall();
21✔
43
        }
44
        await this.processModules();
21✔
45
    }
46

47
    /**
48
     * Deletes every roku_modules folder found in the hostRootDir
49
     */
50
    private async deleteAllRokuModulesFolders() {
51
        const cleanCommand = new CleanCommand({
21✔
52
            cwd: this.cwd
53
        });
54
        await cleanCommand.run();
21✔
55
    }
56

57
    /**
58
     * A "host" is the project we are currently operating upon. This method
59
     * finds the package.json file for the current host
60
     */
61
    private async loadHostPackageJson() {
62
        //if the host doesn't currently have a package.json
63
        if (await fsExtra.pathExists(path.resolve(this.cwd, 'package.json')) === false) {
21!
64
            console.log('Creating package.json');
×
65
            //init package.json for the host
66
            await new InitCommand({ cwd: this.cwd, force: true, promptForRootDir: true }).run();
×
67
        }
68
        this.hostPackageJson = await util.getPackageJson(this.cwd);
21✔
69
    }
70

71
    private async npmInstall() {
72
        if (await fsExtra.pathExists(this.cwd) === false) {
21!
73
            throw new Error(`"${this.cwd}" does not exist`);
×
74
        }
75
        await util.spawnNpmAsync([
21✔
76
            'i',
77
            ...(this.args.packages ?? [])
63✔
78
        ], {
79
            cwd: this.cwd
80
        });
81
    }
82

83
    /**
84
     * Copy all modules to roku_modules
85
     */
86
    private async processModules() {
87
        const modulePaths = this.getProdDependencies();
21✔
88

89
        //remove the host module from the list (it should always be the first entry)
90
        const hostModulePath = modulePaths.splice(0, 1)[0];
20✔
91
        this.moduleManager.hostDependencies = await util.getModuleDependencies(hostModulePath);
20✔
92

93
        this.moduleManager.hostRootDir = this.hostRootDir;
20✔
94
        this.moduleManager.noprefixNpmAliases = this.hostPackageJson?.ropm?.noprefix ?? [];
20!
95

96
        //copy all of them at once, wait for them all to complete
97
        for (const modulePath of modulePaths) {
20✔
98
            this.moduleManager.addModule(modulePath);
20✔
99
        }
100

101
        await this.moduleManager.process();
20✔
102
    }
103

104
    /**
105
     * Get the list of prod dependencies from npm.
106
     * This is run sync because it should run as fast as possible
107
     * and won't be run in ~parallel.
108
     */
109
    public getProdDependencies() {
110
        if (fsExtra.pathExistsSync(this.cwd) === false) {
26!
111
            throw new Error(`"${this.cwd}" does not exist`);
×
112
        }
113
        let stdout: string;
114
        try {
26✔
115
            stdout = childProcess.execSync('npm ls --parseable --prod --depth=Infinity', {
26✔
116
                cwd: this.cwd
117
            }).toString();
118
        } catch (e) {
119
            stdout = (e as any).stdout.toString();
1✔
120
            const stderr: string = (e as any).stderr.toString();
1✔
121
            //sometimes the unit tests absorb stderr...so as long as we have stdout, assume it's valid (and ignore the stderr)
122
            if (stderr.includes('npm ERR! extraneous:')) {
1!
123
                //ignore errors
124
            } else {
125
                throw new Error('Failed to compute prod dependencies: ' +  (e as any).message);
1✔
126
            }
127
        }
128

129
        return stdout.trim().split(/\r?\n/);
25✔
130
    }
131
}
132

133
export interface InstallCommandArgs {
134
    /**
135
     * The current working directory for the command.
136
     */
137
    cwd?: string;
138
    /**
139
     * The list of packages that should be installed
140
     */
141
    packages?: string[];
142
    /**
143
     * Dependencies installation location.
144
     * By default the setting from package.json is imported out-of-the-box, but if rootDir is passed here,
145
     * it will override the value from package.json.
146
     */
147
    rootDir?: string;
148
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc