Completed
Push — master ( 1f2ffc...cd17ec )
by Thomas
30s
created

Kit.js ➔ ... ➔ util.downloadHelper   A

Complexity

Conditions 1
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 9
rs 9.6666
1
'use strict'
2
3
const util = require('../util')
4
const output = require('../output')
5
const helpers = require('../run-helpers')
6
7
const fs = require('fs')
8
const os = require('os')
9
const path = require('path')
10
const https = require('https')
11
const name = require('git-user-name')
12
const email = require('git-user-email')
13
const child = require('child_process')
14
const unzip = require('unzip-stream')
15
const rimraf = require('rimraf')
16
const jsonfile = require('jsonfile')
17
18
var Kit = {}
19
20
function extractZip (response, zipName, containerPath, callback) {
21
  var tmpdir = os.tmpdir()
22
  return response
23
    .pipe(unzip.Extract({
24
      path: tmpdir
25
    }))
26
    .on('error', function (err) {
27
      callback(err)
28
    })
29
    .on('close', function () {
30
      setTimeout(function () {
31
        try {
32
          // At this point, there is a good possibility that all files got
33
          // extracted to a subdirectory, which we should correct
34
          var zipPath = path.join(tmpdir, zipName)
35
          if (fs.existsSync(zipPath)) {
36
            fs.renameSync(zipPath, path.resolve(containerPath))
37
          } else {
38
            callback(new Error('Error extracting zip file'))
39
          }
40
          // Calling back home
41
          callback(null)
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
42
        } catch (e) {
43
          return callback(e)
44
        }
45
      }, 500)
46
    })
47
}
48
49
function downloadZip (zipUrl, zipName, containerPath, callback) {
50
  https.get(zipUrl, function (response) {
51
    if (response.statusCode >= 200 && response.statusCode < 300) {
52
      return extractZip(response, zipName, containerPath, callback)
53
    }
54
    if (response.headers.location) {
55
      return downloadZip(response.headers.location, zipName, containerPath, callback)
56
    }
57
58
    callback(new Error(response.statusCode + ' ' + response.statusMessage))
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
59
  }).on('error', function (err) {
60
    callback(err)
61
  })
62
}
63
64
function postProcess (slug) {
65
  // Remove stock files
66
  try { fs.unlinkSync(path.join(slug, 'LICENSE.md')) } catch (e) {}
67
  try { fs.unlinkSync(path.join(slug, 'LICENSE')) } catch (e) {}
68
  try { fs.unlinkSync(path.join(slug, 'README')) } catch (e) {}
69
  try { rimraf.sync(path.join(slug, '.git')) } catch (e) {}
70
71
  // Write readme.md
72
  fs.writeFileSync(path.join(slug, 'README.md'), '# ' +
73
    util.boxNameDisplay(slug) + '\n\nA Incluable app for ' + util.boxNameDisplay(slug) + '.', 'utf8')
74
75
  // Download IDE helper
76
  var ideSpinner = output.wait('Downloading code completion helper')
77
  util.downloadHelper(function () {
78
    ideSpinner(true)
79
80
    // Git init
81
    var gitSpinner = output.wait('Initializing local Git repository')
82
    child.exec('cd "' + slug + '" && git init', function (err) {
83
      gitSpinner(err ? err : true)
84
    })
85
  }, slug)
86
}
87
88
Kit.download = function (kitName, targetPath, callback) {
89
  var containerPath = path.resolve(targetPath)
90
  var zipUrl = 'https://github.com/includable-modules/starter-' + kitName + '/archive/master.zip'
91
92
  downloadZip(zipUrl, 'starter-' + kitName + '-master', containerPath, callback)
93
}
94
95
Kit.create = function (kitName, slug) {
96
  // Get slug
97
  var userName = (util.getSystemUsername() || 'user').toLowerCase()
98
  if (slug.match(/^[a-z0-9-]+\/[a-z0-9-]+$/)) {
99
    userName = slug.split('/')[0]
100
    slug = slug.split('/')[1]
101
  }
102
  if (!slug.match(/^[a-z0-9-]+$/)) {
103
    output.err('Module name should only contain lowercase letters, numbers and dashes.')
104
    return
105
  }
106
107
  // Check if directory doesn't already exist
108
  var stopSpinner = output.wait('Downloading template \'' + kitName + '\'')
109
  if (fs.existsSync(slug)) {
110
    stopSpinner('Directory \'' + slug + '\' already exists!')
111
    return
112
  }
113
114
  try {
115
    Kit.download(kitName, slug, function (err) {
116
      if (err) {
117
        stopSpinner(err)
118
        return
119
      }
120
      stopSpinner(true)
121
122
      // Write module.json
123
      var json = util.moduleJSON(slug, userName, name({
124
        type: 'global'
125
      }), email({
126
        type: 'global'
127
      }), jsonfile.readFileSync(path.join(slug, 'module.json')))
128
      fs.writeFileSync(path.join(slug, 'module.json'), JSON.stringify(json, null, 3), 'utf8')
129
      fs.writeFileSync(path.join(slug, 'composer.json'), JSON.stringify({
130
        'require': {}
131
      }, null, 3), 'utf8')
132
133
      // Scripts
134
      helpers.startChildProcess('post-create', function () {
135
        postProcess(slug)
136
      }, slug)
137
    })
138
  } catch (e) {
139
    stopSpinner(e)
140
  }
141
}
142
143
module.exports = Kit
144