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

[cli] New outdated command #4171

Merged
merged 16 commits into from Feb 6, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 9 additions & 7 deletions cli/src/cli.js
Expand Up @@ -2,16 +2,17 @@
// @flow

import yargs from 'yargs';
import {fs, path} from './lib/node.js';
import {fs, path} from './lib/node';

import * as Install from './commands/install.js';
import * as Install from './commands/install';
import * as CreateDef from './commands/create-def';
import * as CreateStub from './commands/create-stub.js';
import * as RunTests from './commands/runTests.js';
import * as Search from './commands/search.js';
import * as Update from './commands/update.js';
import * as CreateStub from './commands/create-stub';
import * as Outdated from './commands/outdated';
import * as RunTests from './commands/runTests';
import * as Search from './commands/search';
import * as Update from './commands/update';
import * as UpdateCache from './commands/update-cache';
import * as ValidateDefs from './commands/validateDefs.js';
import * as ValidateDefs from './commands/validateDefs';

import type {Argv} from 'yargs';
import typeof Yargs from 'yargs';
Expand All @@ -30,6 +31,7 @@ export function runCLI() {
CreateDef,
CreateStub,
Install,
Outdated,
RunTests,
Search,
Update,
Expand Down
2 changes: 1 addition & 1 deletion cli/src/commands/install.js
Expand Up @@ -63,7 +63,7 @@ export type Args = {
packageDir?: mixed, // string
ignoreDeps?: mixed, // Array<string>
rootDir?: mixed, // string,
useCacheUntil?: mixed, // seconds
useCacheUntil?: mixed, // number (milliseconds)
explicitLibDefs: mixed, // Array<string>
...
};
Expand Down
130 changes: 130 additions & 0 deletions cli/src/commands/outdated.js
@@ -0,0 +1,130 @@
// @flow
import path from 'path';
import typeof Yargs from 'yargs';
import {table} from 'table';

import {findFlowRoot} from '../lib/flowProjectUtils';
import {
getCacheNpmLibDefs,
getInstalledNpmLibDefs,
} from '../lib/npm/npmLibDefs';

export const name = 'outdated [explicitLibDefs...]';
export const description =
'Update the flow-typed cache and print any outdated libdefs in current project';

export function setup(yargs: Yargs): Yargs {
return yargs
.usage(`$0 ${name}`)
.options({
useCacheUntil: {
alias: 'u',
describe: 'Use cache until specified time in milliseconds',
type: 'number',
},
libdefDir: {
alias: 'l',
describe: 'Scan currently installed libdefs from a custom directory',
type: 'string',
demandOption: false,
},
rootDir: {
alias: 'r',
describe: 'Directory of .flowconfig relative to node_modules',
type: 'string',
},
})
.example('$0 outdated', '')
.help('h')
.alias('h', 'help');
}

type Args = {
useCacheUntil?: mixed, // number (milliseconds)
libdefDir?: mixed, // string
rootDir?: mixed, // string,
...
};

/**
* 1. Update and pull the cache
* 2. Compare current installed with what's in the cache
* 3. Create a list to print out
*/
export async function run({
useCacheUntil,
libdefDir,
rootDir,
}: Args): Promise<number> {
const cwd =
typeof rootDir === 'string' ? path.resolve(rootDir) : process.cwd();
const flowProjectRoot = await findFlowRoot(cwd);
if (flowProjectRoot === null) {
console.error(
'Error: Unable to find a flow project in the current dir or any of ' +
"it's parent dirs!\n" +
'Please run this command from within a Flow project.',
);
return 1;
}

const cachedLibDefs = await getCacheNpmLibDefs(Number(useCacheUntil), true);
const installedLibDefs = await getInstalledNpmLibDefs(
flowProjectRoot,
libdefDir ? String(libdefDir) : undefined,
);

const outdatedList: Array<{
name: string,
message: string,
}> = [];

cachedLibDefs.forEach(cachedDef => {
installedLibDefs.forEach(installedDef => {
if (
installedDef.kind === 'Stub' &&
installedDef.name === cachedDef.name
) {
// a previously stubbed libdef has now been typed
outdatedList.push({
name: installedDef.name,
message:
'A new libdef has been published to the registry replacing your stub',
});
return;
}
if (
installedDef.kind === 'LibDef' &&
installedDef.libDef.name === cachedDef.name
) {
// Need to find the range to only check on libdefs that match
// JSON.stringify(installedDef.libDef.flowVersion) ===
// JSON.stringify(cachedDef.flowVersion)
// But if we don't find one in range it could have been changed mid way
// and we should add that to the outdated list

// need to somehow compare the two defs and if there's a difference
// we assume they're outdated
outdatedList.push({
name: installedDef.libDef.name,
message:
'This libdef is outdated you can update it with `flow-typed update`',
});
return;
}
});
});

if (outdatedList.length > 0) {
console.log(
table([
['Name', 'Details'],
...outdatedList.map(o => [o.name, o.message]),
]),
);
} else {
console.log('All your lib defs are up to date!');
}

return 0;
}