UNPKG

3.54 kBPlain TextView Raw
1#!/usr/bin/env node
2
3"use strict";
4
5var semver = require('semver')
6var program = require('commander')
7var path = require('path')
8var fs = require('fs')
9var tar = require('tar')
10var zlib = require('zlib')
11var fstream = require('fstream')
12var Packer = require('fstream-npm')
13var debug = require('debug')('mosaic:publish')
14var mosaic = require('../lib/mosaic')
15
16
17program.option('-f, --force', 'Force a re-publish')
18program.parse(process.argv)
19
20
21var args = program.args
22var cwd = process.cwd()
23var dpath = cwd
24
25if (args[0]) dpath = path.join(cwd, args[0])
26
27var fpath = path.join(dpath, 'package.json')
28
29if (!fs.existsSync(fpath)) mosaic.fatal('没找到 package.json')
30
31var mo = require(fpath)
32
33
34if (isValid(mo)) {
35 mosaic.log('publish', mo.name)
36 process.stdin.resume()
37 publish(dpath)
38}
39
40
41function publish(dpath){
42 new Packer({ path: dpath, type: 'Directory', isDirectory: true })
43 .pipe(tar.Pack())
44 .pipe(zlib.Gzip())
45 .pipe(fstream.Writer('package.tgz'))
46 .on('close', afterTar)
47}
48
49function afterTar(err) {
50 if (err) return mosaic.fatal(err)
51
52 var url = [mo.name, mo.version].join('\/')
53 var req = mosaic.agent()
54 .get(mosaic.remote(url))
55 .on('error', function(err) {
56 console.trace(err)
57 cleanup()
58 })
59 .end(function(res) {
60 if (res.statusCode === 200 && res.text && res.text.indexOf('统一登录中心') >= 0) {
61 // In superagent, res.req is the instance returned by http.request,
62 // which is not an instance of the request wrap by superagent and
63 // does not provide .url property.
64 //
65 // For code brevity, let's simply set it.
66 res.req.url = req.url
67 mosaic.login(res).done(function() { afterTar() })
68 }
69 else if (res.statusCode === 200) {
70 if (program.force) {
71 postTar(url)
72 }
73 else {
74 mosaic.log('mosaic', url + ' exists. use --force to re-publish')
75 process.exit(0)
76 }
77 }
78 else if (res.statusCode === 404) {
79 postTar(url)
80 }
81 })
82}
83
84function postTar(url) {
85 var req = mosaic.agent()
86 .put(mosaic.remote(url))
87
88 if (program.force) req.query({ force: '' })
89
90 req
91 .attach('tarball', 'package.tgz')
92 .buffer(false)
93 .on('response', function(res) {
94 res.text = ''
95 res.on('data', function(chunk) {
96 res.text += chunk
97 process.stdout.write(chunk)
98 })
99 res.on('end', function() {
100 var status = res.statusCode
101
102 if (status === 201) {
103 var lines = res.text.split('\n')
104 var data = JSON.parse(lines[lines.length - 1])
105
106 process.stdout.write('\n\n')
107 for (var p in data) {
108 mosaic.log(p, data[p])
109 }
110 }
111 else {
112 mosaic.error('Wrong status code returned ' + res.statusCode)
113 mosaic.error(res.text)
114 }
115 cleanup()
116 })
117 })
118 .on('error', function(err) {
119 cleanup()
120 console.trace(err)
121 })
122 .end()
123}
124
125function isValid(mo){
126 var name = mo.name
127 var version = mo.version
128 var valid = true
129
130 function fail(msg) {
131 valid = false
132 mosaic.error(msg)
133 }
134
135 if (!name) fail('未填写名称')
136 if (!version) fail('未填写版本')
137
138 if (!/^(mosaics|mo)\/\w+$/.test(name) && !/^\w+(?:\.\w+)+\/\w+$/.test(name)) fail('名称不符合 命名空间/组件名 规范')
139 if (!semver.valid(version)) fail('版本 ' + version + ' 不合规范')
140
141 return valid
142}
143
144function cleanup() {
145 if (fs.existsSync('package.tgz')) fs.unlinkSync('package.tgz')
146 process.exit()
147}