Skip to content
This repository
Browse code

Fix #472 Adds support for os/cpu fields in package.json

See docs/cli/json.md for details.
  • Loading branch information...
commit af50a3ca8e55e1706d3c5989393e3aca5370464d 1 parent 7c36d0e
regality regality authored isaacs committed
32 doc/cli/json.md
Source Rendered
@@ -428,7 +428,7 @@ node that your stuff works on:
428 428 { "engines" : { "node" : ">=0.1.27 <0.1.30" } }
429 429
430 430 And, like with dependencies, if you don't specify the version (or if you
431   -specify "*" as the version), then any version of node will do.
  431 +specify "\*" as the version), then any version of node will do.
432 432
433 433 If you specify an "engines" field, then npm will require that "node" be
434 434 somewhere on that list. If "engines" is omitted, then npm will just assume
@@ -439,6 +439,36 @@ are capable of properly installing your program. For example:
439 439
440 440 { "engines" : { "npm" : "~1.0.20" } }
441 441
  442 +## os
  443 +
  444 +You can specify which operating systems your
  445 +module will run on:
  446 +
  447 + "os" : [ "darwin", "linux" ]
  448 +
  449 +You can also blacklist instead of whitelist operating systems,
  450 +just prepend the blacklisted os with a '!':
  451 +
  452 + "os" : [ "!win32" ]
  453 +
  454 +The host operating system is determined by `process.platform`
  455 +
  456 +It is allowed to both blacklist, and whitelist, although there isn't any
  457 +good reason to do this.
  458 +
  459 +## cpu
  460 +
  461 +If your code only runs on certain cpu architectures,
  462 +you can specify which ones.
  463 +
  464 + "cpu" : [ "x64", "ia32" ]
  465 +
  466 +Like the `os` option, you can also blacklist architectures:
  467 +
  468 + "cpu" : [ "!arm", "!mips" ]
  469 +
  470 +The host architecture is determined by `process.arch`
  471 +
442 472 ## preferGlobal
443 473
444 474 If your package is primarily a command-line application that should be
53 lib/install.js
@@ -620,6 +620,7 @@ function installOne_ (target, where, context, cb) {
620 620
621 621 chain
622 622 ( [ [checkEngine, target]
  623 + , [checkPlatform, target]
623 624 , [checkCycle, target, context.ancestors]
624 625 , [checkGit, targetFolder]
625 626 , [write, target, targetFolder, context] ]
@@ -648,6 +649,58 @@ function checkEngine (target, cb) {
648 649 return cb()
649 650 }
650 651
  652 +function checkPlatform (target, cb) {
  653 + var platform = process.platform
  654 + , arch = process.arch
  655 + , osOk = true
  656 + , cpuOk = true
  657 + , force = npm.config.get("force")
  658 +
  659 + if (force) {
  660 + return cb()
  661 + }
  662 +
  663 + if (target.os) {
  664 + osOk = checkList(platform, target.os)
  665 + }
  666 + if (target.cpu) {
  667 + cpuOk = checkList(arch, target.cpu)
  668 + }
  669 + if (!osOk || !cpuOk) {
  670 + var er = new Error("Unsupported")
  671 + er.errno = npm.EBADPLATFORM
  672 + er.os = target.os || ['any']
  673 + er.cpu = target.cpu || ['any']
  674 + er.pkgid = target._id
  675 + return cb(er)
  676 + }
  677 + return cb()
  678 +}
  679 +
  680 +function checkList (value, list) {
  681 + var tmp
  682 + , match = false
  683 + , blc = 0
  684 + if (typeof list === "string") {
  685 + list = [list]
  686 + }
  687 + if (list.length === 1 && list[0] === "any") {
  688 + return true;
  689 + }
  690 + for (var i = 0; i < list.length; ++i) {
  691 + tmp = list[i]
  692 + if (tmp[0] === '!') {
  693 + tmp = tmp.slice(1)
  694 + if (tmp === value) {
  695 + return false;
  696 + }
  697 + ++blc
  698 + } else {
  699 + match = match || tmp === value
  700 + }
  701 + }
  702 + return match || blc === list.length
  703 +}
651 704
652 705 function checkCycle (target, ancestors, cb) {
653 706 // there are some very rare and pathological edge-cases where
1  lib/npm.js
@@ -38,6 +38,7 @@ npm.EJSONPARSE = {}
38 38 npm.EISGIT = {}
39 39 npm.ECYCLE = {}
40 40 npm.ENOTSUP = {}
  41 +npm.EBADPLATFORM = {}
41 42
42 43 // HACK for windows
43 44 if (process.platform === "win32") {
11 lib/utils/error-handler.js
@@ -159,6 +159,17 @@ function errorHandler (er) {
159 159 ].join("\n"))
160 160 break
161 161
  162 + case npm.EBADPLATFORM:
  163 + er.code = "EBADPLATFORM"
  164 + log.error([er.message
  165 + ,"Not compatible with your operating system or architecture: "+er.pkgid
  166 + ,"Valid OS: "+er.os.join(",")
  167 + ,"Valid Arch: "+er.cpu.join(",")
  168 + ,"Actual OS: "+process.platform
  169 + ,"Actual Arch: "+process.arch
  170 + ].join("\n"))
  171 + break
  172 +
162 173 case "EEXIST":
163 174 case constants.EEXIST:
164 175 log.error([er.message
5 test/packages/npm-test-platform-all/package.json
... ... @@ -0,0 +1,5 @@
  1 +{"name":"npm-test-platform"
  2 +,"version":"9.9.9-9"
  3 +,"homepage":"http://www.zombo.com/",
  4 +,"os":["darwin","linux","win32","solaris","haiku","sunos","freebsd","openbsd","netbsd"]
  5 +,"cpu":["arm","mips","ia32","x64","sparc"]}
5 test/packages/npm-test-platform/package.json
... ... @@ -0,0 +1,5 @@
  1 +{"name":"npm-test-platform"
  2 +,"version":"9.9.9-9"
  3 +,"homepage":"http://www.youtube.com/watch?v=dQw4w9WgXcQ"
  4 +,"os":["!this_is_not_a_real_os", "!neither_is_this"]
  5 +,"cpu":["!this_is_not_a_real_cpu","!this_isnt_either"]}

0 comments on commit af50a3c

Please sign in to comment.
Something went wrong with that request. Please try again.