Skip to content

Commit 6b02555

Browse files
committed
feat: cmd-view
1 parent 1fe5393 commit 6b02555

File tree

7 files changed

+291
-5
lines changed

7 files changed

+291
-5
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ Search packages
6565
openupm search <keyword>
6666
```
6767

68+
View package information
69+
```
70+
openupm view <pkg>
71+
```
72+
6873
### Command options
6974

7075
The cli assumes current working directory (cwd) is the root of an Unity project (the parent of `Assets` folder). However you can specify the cwd.

lib/cli.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const program = require("commander");
22
const add = require("./cmd-add");
33
const remove = require("./cmd-remove");
44
const search = require("./cmd-search");
5+
const view = require("./cmd-view");
56
const log = require("./logger");
67
require("pkginfo")(module);
78

@@ -44,6 +45,15 @@ program
4445
if (retCode) process.exit(retCode);
4546
});
4647

48+
program
49+
.command("view <pkg>")
50+
.alias("v")
51+
.description("view package information")
52+
.action(async function(pkg, options) {
53+
const retCode = await view(pkg, options);
54+
if (retCode) process.exit(retCode);
55+
});
56+
4757
// prompt for invalid command
4858
program.on("command:*", function() {
4959
log.error(`invalid command: ${program.args.join(" ")}

lib/cmd-remove.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ const _remove = async function(pkg) {
3030
// parse name
3131
let { name, version } = parseName(pkg);
3232
if (version) {
33-
log.error(
34-
"remove command doesn't support name@version, using name instead"
35-
);
33+
log.error("command doesn't support name@version, using name instead");
3634
return { code: 1, dirty };
3735
}
3836
// load manifest

lib/cmd-view.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
const log = require("./logger");
2+
const {
3+
env,
4+
getPackageInfo,
5+
getLatestVersion,
6+
parseEnv,
7+
parseName
8+
} = require("./core");
9+
10+
const view = async function(pkg, options) {
11+
// parse env
12+
if (!parseEnv(options, { checkPath: false })) return 1;
13+
// parse name
14+
let { name, version } = parseName(pkg);
15+
if (version) {
16+
log.error("command doesn't support name@version, using name instead");
17+
return 1;
18+
}
19+
// verify name
20+
let pkgInfo = await getPackageInfo(name);
21+
if (!pkgInfo && env.upstream)
22+
pkgInfo = await getPackageInfo(name, env.upstreamRegistry);
23+
if (!pkgInfo) {
24+
log.error(`package not found: ${name}`);
25+
return 1;
26+
}
27+
// print info
28+
printInfo(pkgInfo);
29+
return 0;
30+
};
31+
32+
const printInfo = function(pkg) {
33+
// log.info(pkg);
34+
log.info();
35+
const versionCount = Object.keys(pkg.versions).length;
36+
const ver = getLatestVersion(pkg);
37+
const verInfo = pkg.versions[ver];
38+
const license = verInfo.license || "proprietary or unlicensed";
39+
const displayName = verInfo.displayName;
40+
const description = verInfo.description || pkg.description;
41+
const keywords = verInfo.keywords || pkg.keywords;
42+
const homepage = verInfo.homepage;
43+
const dist = verInfo.dist;
44+
const dependencies = verInfo.dependencies;
45+
const time = (pkg.time.modified || "").split("T")[0];
46+
47+
log.info(`${pkg.name}@${ver} | ${license} | versions: ${versionCount}`);
48+
log.info();
49+
if (displayName) log.info(`display name: ${displayName}`);
50+
if (description) log.info(`description: ${description}`);
51+
if (description && description.includes("\n")) log.info();
52+
if (homepage) log.info(`homepage: ${homepage}`);
53+
if (keywords) log.info(`keywords: ${keywords.join(", ")}`);
54+
55+
if (dist) {
56+
log.info();
57+
log.info("dist");
58+
log.info(`.tarball: ${dist.tarball}`);
59+
if (dist.shasum) log.info(`.shasum: ${dist.shasum}`);
60+
if (dist.integrity) log.info(`.integrity: ${dist.integrity}`);
61+
}
62+
63+
if (dependencies && Object.keys(dependencies).length > 0) {
64+
log.info();
65+
log.info("dependencies");
66+
Object.keys(dependencies)
67+
.sort()
68+
.forEach(n => log.info(`${n} ${dependencies[n]}`));
69+
// log.info(dependencies);
70+
}
71+
72+
log.info();
73+
log.info(`published at ${time}`);
74+
};
75+
76+
module.exports = view;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "openupm-cli",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"preferGlobal": true,
55
"description": "openupm command line interface",
66
"main": "index.js",

test/test-cmd-remove.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ describe("cmd-remove.js", function() {
8484
manifest.should.be.deepEqual(defaultManifest);
8585
stderr
8686
.captured()
87-
.includes("remove command doesn't support name@version")
87+
.includes("doesn't support name@version, using name instead")
8888
.should.be.ok();
8989
});
9090
it("remove pkg-not-exist", async function() {

test/test-cmd-view.js

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
/* eslint-disable no-unused-vars */
2+
/* eslint-disable no-undef */
3+
const assert = require("assert");
4+
const nock = require("nock");
5+
const should = require("should");
6+
const { parseEnv, loadManifest } = require("../lib/core");
7+
const view = require("../lib/cmd-view");
8+
const {
9+
getWorkDir,
10+
createWorkDir,
11+
removeWorkDir,
12+
captureStream,
13+
nockUp,
14+
nockDown
15+
} = require("./utils");
16+
17+
describe("cmd-view.js", function() {
18+
const options = {
19+
parent: {
20+
registry: "http://example.com",
21+
upstream: false,
22+
chdir: getWorkDir("test-openupm-cli")
23+
}
24+
};
25+
const upstreamOptions = {
26+
parent: {
27+
registry: "http://example.com",
28+
chdir: getWorkDir("test-openupm-cli")
29+
}
30+
};
31+
describe("view", function() {
32+
let stdout;
33+
let stderr;
34+
const remotePkgInfoA = {
35+
name: "com.example.package-a",
36+
versions: {
37+
"1.0.0": {
38+
name: "com.example.package-a",
39+
displayName: "Package A",
40+
author: {
41+
name: "batman"
42+
},
43+
version: "1.0.0",
44+
unity: "2018.4",
45+
description: "A demo package",
46+
keywords: [""],
47+
category: "Unity",
48+
dependencies: {
49+
"com.example.package-a": "^1.0.0"
50+
},
51+
gitHead: "5c141ecfac59c389090a07540f44c8ac5d07a729",
52+
readmeFilename: "README.md",
53+
54+
_nodeVersion: "12.13.1",
55+
_npmVersion: "6.12.1",
56+
dist: {
57+
integrity:
58+
"sha512-MAh44bur7HGyfbCXH9WKfaUNS67aRMfO0VAbLkr+jwseb1hJue/I1pKsC7PKksuBYh4oqoo9Jov1cBcvjVgjmA==",
59+
shasum: "516957cac4249f95cafab0290335def7d9703db7",
60+
tarball:
61+
"https://cdn.example.com/com.example.package-a/com.example.package-a-1.0.0.tgz"
62+
},
63+
contributors: []
64+
}
65+
},
66+
time: {
67+
modified: "2019-11-28T18:51:58.123Z",
68+
created: "2019-11-28T18:51:58.123Z",
69+
"1.0.0": "2019-11-28T18:51:58.123Z"
70+
},
71+
users: {},
72+
"dist-tags": {
73+
latest: "1.0.0"
74+
},
75+
_rev: "3-418f950115c32bd0",
76+
_id: "com.example.package-a",
77+
readme: "A demo package",
78+
_attachments: {}
79+
};
80+
const remotePkgInfoUp = {
81+
name: "com.example.package-up",
82+
versions: {
83+
"1.0.0": {
84+
name: "com.example.package-up",
85+
displayName: "Package A",
86+
author: {
87+
name: "batman"
88+
},
89+
version: "1.0.0",
90+
unity: "2018.4",
91+
description: "A demo package",
92+
keywords: [""],
93+
category: "Unity",
94+
dependencies: {
95+
"com.example.package-up": "^1.0.0"
96+
},
97+
gitHead: "5c141ecfac59c389090a07540f44c8ac5d07a729",
98+
readmeFilename: "README.md",
99+
100+
_nodeVersion: "12.13.1",
101+
_npmVersion: "6.12.1",
102+
dist: {
103+
integrity:
104+
"sha512-MAh44bur7HGyfbCXH9WKfaUNS67aRMfO0VAbLkr+jwseb1hJue/I1pKsC7PKksuBYh4oqoo9Jov1cBcvjVgjmA==",
105+
shasum: "516957cac4249f95cafab0290335def7d9703db7",
106+
tarball:
107+
"https://cdn.example.com/com.example.package-up/com.example.package-up-1.0.0.tgz"
108+
},
109+
contributors: []
110+
}
111+
},
112+
time: {
113+
modified: "2019-11-28T18:51:58.123Z",
114+
created: "2019-11-28T18:51:58.123Z",
115+
"1.0.0": "2019-11-28T18:51:58.123Z"
116+
},
117+
users: {},
118+
"dist-tags": {
119+
latest: "1.0.0"
120+
},
121+
_rev: "3-418f950115c32bd0",
122+
_id: "com.example.package-up",
123+
readme: "A demo package",
124+
_attachments: {}
125+
};
126+
beforeEach(function() {
127+
removeWorkDir("test-openupm-cli");
128+
createWorkDir("test-openupm-cli", { manifest: true });
129+
nockUp();
130+
nock("http://example.com")
131+
.get("/com.example.package-a")
132+
.reply(200, remotePkgInfoA, { "Content-Type": "application/json" });
133+
nock("http://example.com")
134+
.get("/pkg-not-exist")
135+
.reply(404);
136+
nock("http://example.com")
137+
.get("/com.example.package-up")
138+
.reply(404);
139+
nock("https://api.bintray.com")
140+
.get("/npm/unity/unity/com.example.package-up")
141+
.reply(200, remotePkgInfoUp, {
142+
"Content-Type": "application/json"
143+
});
144+
nock("https://api.bintray.com")
145+
.get("/npm/unity/unity/pkg-not-exist")
146+
.reply(404);
147+
stdout = captureStream(process.stdout);
148+
stderr = captureStream(process.stderr);
149+
});
150+
afterEach(function() {
151+
removeWorkDir("test-openupm-cli");
152+
nockDown();
153+
stdout.unhook();
154+
stderr.unhook();
155+
});
156+
it("view pkg", async function() {
157+
const retCode = await view("com.example.package-a", options);
158+
retCode.should.equal(0);
159+
stdout
160+
.captured()
161+
.includes("[email protected]")
162+
.should.be.ok();
163+
});
164+
it("view [email protected]", async function() {
165+
const retCode = await view("[email protected]", options);
166+
retCode.should.equal(1);
167+
stderr
168+
.captured()
169+
.includes("doesn't support name@version, using name instead")
170+
.should.be.ok();
171+
});
172+
it("view pkg-not-exist", async function() {
173+
const retCode = await view("pkg-not-exist", options);
174+
retCode.should.equal(1);
175+
stderr
176+
.captured()
177+
.includes("package not found")
178+
.should.be.ok();
179+
});
180+
it("view pkg from upstream", async function() {
181+
const retCode = await view("com.example.package-up", upstreamOptions);
182+
retCode.should.equal(0);
183+
stdout
184+
.captured()
185+
.includes("[email protected]")
186+
.should.be.ok();
187+
});
188+
it("view pkg-not-exist from upstream", async function() {
189+
const retCode = await view("pkg-not-exist", upstreamOptions);
190+
retCode.should.equal(1);
191+
stderr
192+
.captured()
193+
.includes("package not found")
194+
.should.be.ok();
195+
});
196+
});
197+
});

0 commit comments

Comments
 (0)