Skip to content

Commit 19afa51

Browse files
Sebastian McKenziebestander
authored andcommitted
add license command (#144)
1 parent 105b6b9 commit 19afa51

File tree

7 files changed

+130
-12
lines changed

7 files changed

+130
-12
lines changed

src/cli/commands/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ export { ls };
1818
import * as why from "./why.js";
1919
export { why };
2020

21+
import * as licenses from "./licenses.js";
22+
export { licenses };
23+
2124
import * as uninstall from "./uninstall.js";
2225
export { uninstall };
2326

src/cli/commands/install.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,12 @@ export class Install {
8080

8181
async fetchRequestFromCwd(excludePatterns?: Array<string> = []): Promise<[
8282
DependencyRequestPatterns,
83-
Array<string>
83+
Array<string>,
84+
Object
8485
]> {
8586
let patterns = [];
8687
let deps = [];
88+
let manifest = {};
8789

8890
// exclude package names that are in install args
8991
let excludeNames = [];
@@ -107,6 +109,7 @@ export class Install {
107109

108110
let json = await fs.readJson(loc);
109111
Object.assign(this.resolutions, json.resolutions);
112+
Object.assign(manifest, json);
110113

111114
let pushDeps = (depType, { hint, ignore, optional }) => {
112115
let depMap = json[depType];
@@ -134,7 +137,7 @@ export class Install {
134137
}
135138
}
136139

137-
return [deps, patterns];
140+
return [deps, patterns, manifest];
138141
}
139142

140143
async init(): Promise<void> {

src/cli/commands/licenses.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/**
2+
* Copyright (c) 2016-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*
9+
* @flow
10+
*/
11+
12+
import type { Reporter } from "../../reporters/index.js";
13+
import type Config from "../../config.js";
14+
import { MessageError } from "../../errors.js";
15+
import { Install } from "./install.js";
16+
import Lockfile from "../../lockfile/index.js";
17+
18+
export function hasWrapper(flags: Object, args: Array<string>): boolean {
19+
return args[0] != "generate-disclaimer";
20+
}
21+
22+
export function setFlags(commander: Object) {
23+
commander.usage("licenses [ls | generate-disclaimer]");
24+
}
25+
26+
export async function run(
27+
config: Config,
28+
reporter: Reporter,
29+
flags: Object,
30+
args: Array<string>
31+
): Promise<void> {
32+
// validate subcommand
33+
let cmd = args[0];
34+
if (args.length !== 1 || (cmd !== "generate-disclaimer" && cmd !== "ls")) {
35+
throw new MessageError(
36+
"Invalid subcommand, use `kpm licenses generate-disclaimer` or `kpm licenses ls`"
37+
);
38+
}
39+
40+
let lockfile = await Lockfile.fromDirectory(config.cwd, reporter, {
41+
silent: true,
42+
strictIfPresent: true
43+
});
44+
45+
let install = new Install("ls", flags, args, config, reporter, lockfile);
46+
47+
let [depRequests,, manifest] = await install.fetchRequestFromCwd();
48+
await install.resolver.init(depRequests);
49+
50+
if (cmd === "generate-disclaimer") {
51+
console.log(
52+
"THE FOLLOWING SETS FORTH ATTRIBUTION NOTICES FOR THIRD PARTY SOFTWARE THAT MAY BE CONTAINED " +
53+
`IN PORTIONS OF THE ${String(manifest.name).toUpperCase().replace(/-/g, " ")} PRODUCT.`
54+
);
55+
console.log();
56+
57+
// get manifests and sort them by package name
58+
let manifests = install.resolver.getManifests();
59+
manifests = manifests.sort((a, b) => {
60+
if (!a.name && !b.name) return 0;
61+
if (!a.name) return 1;
62+
if (!b.name) return -1;
63+
return a.name.localeCompare(b.name);
64+
});
65+
66+
for (let { name, license, licenseText, repository } of manifests) {
67+
console.log("-----");
68+
console.log();
69+
70+
let heading = [];
71+
heading.push(`The following software may be included in this product: ${name}.`);
72+
73+
let url = repository && repository.url;
74+
if (url) {
75+
heading.push(`A copy of the source code may be downloaded from ${url}.`);
76+
}
77+
78+
heading.push("This software contains the following license and notice below:");
79+
80+
console.log(heading.join(" "));
81+
console.log();
82+
83+
if (licenseText) {
84+
console.log(licenseText.trim());
85+
} else {
86+
// what do we do here? base it on `license`?
87+
license;
88+
}
89+
90+
console.log();
91+
}
92+
}
93+
}

src/cli/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ let config = new Config(reporter, {
9595
});
9696

9797
// print header
98-
reporter.header(commandName, pkg);
98+
let outputWrapper = true;
99+
if (command.hasWrapper) outputWrapper = command.hasWrapper(commander, commander.args);
100+
if (outputWrapper) reporter.header(commandName, pkg);
99101

100102
//
101103
if (commander.yes) {
@@ -120,7 +122,7 @@ if (command.requireLockfile && !fs.existsSync(path.join(config.cwd, constants.LO
120122
const run = () => {
121123
return command.run(config, reporter, commander, commander.args).then(function () {
122124
reporter.close();
123-
reporter.footer(false);
125+
if (outputWrapper) reporter.footer(false);
124126
});
125127
};
126128

src/types.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,21 @@ export type Manifest = {
4848
name: string,
4949
version: string,
5050

51+
license?: string,
52+
licenseText?: string,
53+
54+
readme?: string,
55+
readmeFilename?: string,
56+
57+
repository?: {
58+
type: "git",
59+
url: string
60+
},
61+
62+
bugs?: {
63+
url: string
64+
},
65+
5166
// the package reference that we pass around as a minimal way to refer to it
5267
reference?: ?PackageReference,
5368

src/util/normalise-manifest/fix.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,16 @@ export default async function (info: Object, moduleLoc: string): Promise<void> {
168168

169169
// infer license file
170170
// TODO: show that this were inferred and may not be accurate
171-
if (!info.license) {
172-
let licenseFile = _.find(files, (filename) => {
173-
let lower = filename.toLowerCase();
174-
return lower === "license" || lower.indexOf("license.") === 0;
175-
});
171+
let licenseFile = _.find(files, (filename) => {
172+
let lower = filename.toLowerCase();
173+
return lower === "license" || lower.indexOf("license.") === 0;
174+
});
175+
176+
if (licenseFile) {
177+
let licenseContent = await fs.readFile(path.join(moduleLoc, licenseFile));
178+
info.licenseText = licenseContent;
176179

177-
if (licenseFile) {
178-
let licenseContent = await fs.readFile(path.join(moduleLoc, licenseFile));
180+
if (!info.license) {
179181
info.license = inferLicense(licenseContent) || inferLicense(info.readme);
180182
}
181183
}

src/util/normalise-manifest/infer-license.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export default function (license: string): ?string {
2121
for (let licenseName in REGEXES) {
2222
for (let regex of REGEXES[licenseName]) {
2323
if (regex.test(license)) {
24-
return licenseName;
24+
return `${licenseName}*`;
2525
}
2626
}
2727
}

0 commit comments

Comments
 (0)