PageRenderTime 49ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/utils/npm-registry-client/publish.js

https://github.com/FesterCluck/npm
JavaScript | 106 lines | 88 code | 9 blank | 9 comment | 21 complexity | 622cc9a71dc78e8131ef7dc1829fcb75 MD5 | raw file
  1. module.exports = publish
  2. var request = require("./request")
  3. , GET = request.GET
  4. , PUT = request.PUT
  5. , DELETE = request.DELETE
  6. , reg = request.reg
  7. , upload = request.upload
  8. , log = require("../log")
  9. , path = require("path")
  10. , npm = require("../../../npm")
  11. , url = require("url")
  12. function publish (data, cb) {
  13. // add the dist-url to the data, pointing at the tarball.
  14. // if the {name} isn't there, then create it.
  15. // if the {version} is already there, then fail.
  16. // then:
  17. // PUT the data to {config.registry}/{data.name}/{data.version}
  18. var registry = reg()
  19. if (registry instanceof Error) return cb(registry)
  20. var fullData =
  21. { _id : data.name
  22. , name : data.name
  23. , description : data.description
  24. , "dist-tags" : {}
  25. , versions : {}
  26. , maintainers :
  27. [ { name : npm.config.get("username")
  28. , email : npm.config.get("email")
  29. }
  30. ]
  31. }
  32. data._id = data.name+"@"+data.version
  33. var attURI = encodeURIComponent(data.name)
  34. + "/-/"
  35. + encodeURIComponent(data.name)
  36. + "-"
  37. + encodeURIComponent(data.version)
  38. + ".tgz"
  39. data.dist = data.dist || {}
  40. data.dist.tarball = url.resolve(registry, attURI)
  41. .replace(/^https:\/\//, 'http://')
  42. // first try to just PUT the whole fullData, and this will fail if it's
  43. // already there, because it'll be lacking a _rev, so couch'll bounce it.
  44. PUT(encodeURIComponent(data.name), fullData, function (er, parsed, json, response) {
  45. // get the rev and then upload the attachment
  46. // a 409 is expected here, if this is a new version of an existing package.
  47. if (er
  48. && !(response && response.statusCode === 409)
  49. && !( parsed
  50. && parsed.reason === "must supply latest _rev to update existing package"
  51. )
  52. ) {
  53. return log.er(cb, "Failed PUT response "+(response && response.statusCode))(er)
  54. }
  55. var dataURI = encodeURIComponent(data.name)+"/"+encodeURIComponent(data.version)
  56. var tag = data.tag || npm.config.get("tag")
  57. if (npm.config.get("pre")) dataURI += "/-pre/true"
  58. else if (tag) dataURI += "/-tag/" + tag
  59. else dataURI += "/-tag/latest"
  60. PUT(dataURI, data, function (er) {
  61. if (er) {
  62. if (er.message.indexOf("conflict Document update conflict.") === 0) {
  63. var e = new Error("publish fail")
  64. e.errno = npm.EPUBLISHCONFLICT
  65. e.pkgid = data._id
  66. return cb(e)
  67. }
  68. return log.er(cb, "Error sending version data")(er)
  69. }
  70. GET(encodeURIComponent(data.name), function (er, d) {
  71. if (er) return cb(er)
  72. var rev = d && ("-rev/"+d._rev)
  73. , tarball = path.join(npm.cache, data.name, data.version, "package.tgz")
  74. log.verbose(tarball, "tarball")
  75. attURI += "/" + rev
  76. upload(attURI, tarball, function (er) {
  77. log("uploaded", "publish")
  78. if (er) log.error("Couldn't send tarball", "publish fail")
  79. rollbackFailure(data, cb)(er)
  80. })
  81. })
  82. })
  83. })
  84. }
  85. function rollbackFailure (data, cb) { return function (er) {
  86. if (!er) return cb()
  87. npm.ROLLBACK = true
  88. log.error(er, "publish failed")
  89. log("rollback", "publish failed")
  90. npm.commands.unpublish([data.name+"@"+data.version], function (er_) {
  91. if (er_) {
  92. log.error(er_, "rollback failed")
  93. log.error("Invalid data in registry! Please report this.", "rollback failed")
  94. } else log("rolled back", "publish failed")
  95. cb(er)
  96. })
  97. }}