UNPKG

7.37 kBJavaScriptView Raw
1//
2// Copyright (c) Microsoft and contributors. All rights reserved.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17var _ = require('underscore');
18var fs = require('fs');
19var path = require('path');
20var read = require('read');
21var wrap = require('wordwrap').hard(0, 75);
22var util = require('util');
23var Constants = require('./constants');
24var userHome = require('user-home');
25
26exports.camelcase = function (flag) {
27 return flag.split('-').reduce(function (str, word) {
28 return str + word[0].toUpperCase() + word.slice(1);
29 });
30};
31
32exports.ignoreCaseEquals = function (a, b) {
33 return a === b ||
34 (a !== null && a !== undefined &&
35 b !== null && b !== undefined &&
36 (a.toLowerCase() === b.toLowerCase())) === true;
37};
38
39exports.azureDir = function () {
40 if (!process.env.AZURE_CONFIG_DIR && !userHome) {
41 throw new Error('No Azure_CONFIG_DIR or HOME path is available');
42 }
43 var dir = process.env.AZURE_CONFIG_DIR ||
44 path.join(userHome, '.azure');
45 if (!exports.pathExistsSync(dir)) {
46 fs.mkdirSync(dir, 502); // 0766
47 }
48
49 return dir;
50};
51
52exports.stringStartsWith = function (text, prefix, ignoreCase) {
53 if (_.isNull(prefix)) {
54 return true;
55 }
56
57 if (ignoreCase) {
58 return text.toLowerCase().substr(0, prefix.toLowerCase().length) === prefix.toLowerCase();
59 } else {
60 return text.substr(0, prefix.length) === prefix;
61 }
62};
63
64exports.pathExistsSync = fs.existsSync ? fs.existsSync : path.existsSync;
65
66/**
67 * Read azure cli config
68 */
69exports.readConfig = function () {
70 var azureConfigPath = path.join(exports.azureDir(), 'config.json');
71
72 var cfg = {};
73
74 if (exports.pathExistsSync(azureConfigPath)) {
75 try {
76 cfg = JSON.parse(fs.readFileSync(azureConfigPath));
77 } catch (err) {
78 cfg = {};
79 }
80 }
81
82 return cfg;
83};
84
85exports.writeConfig = function (cfg) {
86 var azurePath = exports.azureDir();
87 var azureConfigPath = path.join(exports.azureDir(), 'config.json');
88
89 if (!exports.pathExistsSync(azurePath)) {
90 fs.mkdirSync(azurePath, 502); //0766
91 }
92
93 fs.writeFileSync(azureConfigPath, JSON.stringify(cfg, null, 2));
94};
95
96exports.getMode = function () {
97 var config = exports.readConfig();
98 return config.mode ? config.mode : Constants.API_VERSIONS.ARM;
99};
100
101exports.getFiles = function (scanPath, recursively) {
102 var results = [];
103
104 var list = fs.readdirSync(scanPath);
105
106 var pending = list.length;
107 if (!pending) {
108 return results;
109 }
110
111 for (var i = 0; i < list.length; i++) {
112 var file = list[i];
113
114 file = scanPath + '/' + file;
115
116 var stat = fs.statSync(file);
117 if (stat && stat.isDirectory()) {
118 if (recursively) {
119 var res = exports.getFiles(file);
120 results = results.concat(res);
121 }
122 } else {
123 results.push(file);
124 }
125 }
126
127 return results;
128};
129
130exports.readTelemetry = function () {
131 var azureTelemetryPath = path.join(exports.azureDir(), Constants.TELEMETRY);
132
133 var telemetry = {};
134
135 if (exports.pathExistsSync(azureTelemetryPath)) {
136 try {
137 telemetry = JSON.parse(fs.readFileSync(azureTelemetryPath));
138 } catch (err) {
139 telemetry = {};
140 }
141 }
142
143 return telemetry;
144};
145
146exports.writeTelemetry = function (telemetry) {
147 var azurePath = exports.azureDir();
148 var azureTelemetryPath = path.join(exports.azureDir(), Constants.TELEMETRY);
149
150 if (!exports.pathExistsSync(azurePath)) {
151 fs.mkdirSync(azurePath, 502); //0766
152 }
153
154 fs.writeFileSync(azureTelemetryPath, JSON.stringify(telemetry, null, 2));
155};
156
157/**
158 * Determines whether telemtry is enabled or not. If this is the first time, that this decision
159 * needs to be made, then it prompts the user for data collection. It will timeout in 60 seconds
160 * with default response being 'n' i.e. telemetry is disabled.
161 *
162 * @returns {function} callback(err, result)
163 *
164 * {null} err - Always null.
165 *
166 * {boolean} result - true if telemetry is enabled, false otherwise.
167 */
168exports.isTelemetryEnabled = function (callback) {
169 var telemetryInfo = exports.readTelemetry();
170 var outcome = false;
171 if (telemetryInfo.telemetry !== null && telemetryInfo.telemetry !== undefined && typeof telemetryInfo.telemetry === 'boolean') {
172 return callback(null, telemetryInfo.telemetry);
173 } else if (process.argv[2] && process.argv[2].toLowerCase() === 'telemetry') {
174 return callback(null, outcome);
175 } else {
176 // we've determined that this is not a telemetry command and we do not have user's telemetry preference.
177 // we proceed to read out the telemetry prompt and get user preference. But, before that check if we're
178 // in non interactive mode. If so, do not prompt, assume default response of 'no'.
179 // This behavior is intended to make scripting scenarios better. E.g: running azure cli on a CI server.
180 if (process.env['AZURE_NON_INTERACTIVE_MODE']) {
181 return callback(null, outcome);
182 }
183
184 var telemetryPromptText = wrap('\nMicrosoft Azure CLI would like to collect data about how users use CLI commands and some problems they encounter. ' +
185 'Microsoft uses this information to improve our CLI commands. Participation is voluntary and when you choose to participate your device ' +
186 'automatically sends information to Microsoft about how you use Azure CLI. ' +
187 '\n\nIf you choose to participate, you can stop at any time later by using Azure CLI as follows: ' +
188 '\n1. Use the azure telemetry command to turn the feature Off. ' +
189 '\nTo disable data collection, execute: azure telemetry --disable' +
190 '\n\nIf you choose to not participate, you can enable at any time later by using Azure CLI as follows: ' +
191 '\n1. Use the azure telemetry command to turn the feature On. ' +
192 '\nTo enable data collection, execute: azure telemetry --enable' +
193 '\n\nSelect y to enable data collection :(y/n) ');
194
195 var telemetryOptions = {
196 prompt : telemetryPromptText,
197 timeout : 30000,
198 edit : false,
199 silent : false
200 };
201
202 read(telemetryOptions, function(err, result) {
203 if ((err && err.message === 'timed out') || (result && result.match(/^no?$/i))) {
204 exports.writeTelemetry({telemetry: false});
205 console.log('\nYou choose not to participate in Microsoft Azure CLI data collection.\n\n');
206 } else if (result && result.match(/^y?(es)?$/i)) {
207 exports.writeTelemetry({telemetry: true});
208 outcome = true;
209 console.log('\nYou choose to participate in Microsoft Azure CLI data collection.\n\n');
210 } else {
211 exports.writeTelemetry({telemetry: false});
212 console.log(wrap(util.format('\nYou provided \'%s\' which is an invalid input. This translates ' +
213 'to you choosing not to participate in Microsoft Azure CLI data collection.\n\n', result)));
214 }
215 return callback(null, outcome);
216 });
217 }
218};
\No newline at end of file