Repository navigation
Expand file tree
/
Copy pathsync.js
More file actions
executable file
·229 lines (205 loc) · 7.07 KB
/
Copy pathsync.js
File metadata and controls
executable file
·229 lines (205 loc) · 7.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#!/usr/bin/env node
'use strict';
const path = require('path');
const chokidar = require('chokidar');
const meow = require('meow');
const cli = meow(`
Usage
$ ./sync.js --url www.yoursite.com --browsersync
Options
--url www.yoursite.com The site you're working with [Required]
--sass Auto compile SASS files
For more infomation, see: http://sass-lang.com/
--browsersync Enables BrowserSync for live reload and multi device sync
For more infomation, see: https://www.browsersync.io/
--ftpall Upload ALL files on change via FTP
(not needed if using an FTP editor plugin)
--help Show this help infomation
Examples
$ ./sync.js --url www.somesite.com --browsersync
$ ./sync.js --browsersync --sass
$ ./sync.js --sass
`);
// no flags / options given? show help
if (Object.keys(cli.flags).length < 1) {
console.log('No options given...');
console.log(cli.help);
process.exit(1);
}
// make sure we have a url to work with
if ( ! cli.flags.sass && ! cli.flags.ftpall && cli.flags.browsersync && ! cli.flags.url) {
console.log('Please pass the --url www.yoursite.com option');
process.exit(1);
}
if (cli.flags.sass) {
var sass = require('node-sass');
}
if (cli.flags.browsersync) {
var browserSync = require('browser-sync').create();
}
if (cli.flags.sass || cli.flags.ftpall) {
var fs = require('fs');
var ftpClient = require('ftp');
var ftpConnection = new ftpClient();
// collect FTP details
var ftpConfig = null;
try {
// try in current folder
ftpConfig = fs.readFileSync('.remote-sync.json');
}
catch (e) {
// else try in above folder
try {
ftpConfig = fs.readFileSync('../.remote-sync.json');
}
catch (e) {
console.log('Please setup .remote-sync.json config file');
process.exit(1);
}
}
ftpConfig = JSON.parse(ftpConfig);
if ( ! ftpConfig) {
console.log('Remote-sync config file is not valid JSON');
process.exit(1);
}
// root target? (well we still just want to sync this folder, so take this folders name instead)
if (ftpConfig.target == '/') {
ftpConfig.target = '/' + path.basename(__dirname);
}
}
// sass compile to css function
function renderSassToCss() {
// render the site.scss file
sass.render({
file: 'css/site.scss',
outputStyle: 'expanded'
}, (err, result) => {
if (err) {
console.log('SASS', err.formatted);
// read in the current file contents and add this error to the top
let errorString = "/* !!! SASS ERROR !!! */ \n\
body:before { \n\
content: \"SASS "+ err.formatted.replace(/"/g, '\\"').replace(/\n/g, '\\A') + "\"; \n\
background: #FFF; color: #000; padding: 1em; font-size: 1.6em; \n\
position: fixed; top: 0; left: 0; right: 0; z-index: 9999; \n\
white-space: pre; font-family: monospace; \n\
} \n\
";
fs.readFile('css/site-sass-out.css.twig', 'utf8', function (err,data) {
if (err) {
console.log('Error appending sass error text to css file');
} else {
writeCssToFile(data + errorString);
}
});
} else {
// No errors during the compilation, write this result on the disk
// console.log(result.css.toString());
writeCssToFile(result.css);
}
});
}
// write css file function
function writeCssToFile(css) {
let outputFile = 'css/site-sass-out.css.twig';
fs.writeFile(outputFile, css, (err) => {
if (err) {
console.log('File Saving Error:', err);
} else {
ftpUploadFile(outputFile);
}
});
}
// ftp upload file function
function ftpUploadFile(path) {
ftpConnection.put(path, ftpConfig.target + '/' + path, (err) => {
if (err) {
console.log('FTP Error:', err);
}
else {
console.log('=> uploaded File:', path);
// reload in browsersync ;)
if (cli.flags.browsersync) {
browserSync.reload();
}
}
})
}
// await connection before watching / compiling any files
let ftpConnected = false;
if (cli.flags.sass || cli.flags.ftpall) {
ftpConnection.on('ready', () => {
// we're connected :D
ftpConnected = true;
// initial sass compile (incase of changes before this was run)
renderSassToCss();
// let the user know it's all setup and ready
console.log('Connected & watching for sass file changes to upload.');
});
// ftpConnection.on('greeting', (msg) => {
// console.log('FTP greeting: ', msg);
// });
ftpConnection.on('error', (err) => {
console.log('FTP Error: ', err);
});
ftpConnection.on('close', () => {
console.log('FTP connection closed');
process.exit(1);
});
ftpConnection.on('end', () => {
console.log('FTP connection ended');
process.exit(1);
});
// connect to FTP
ftpConnection.connect({
host: ftpConfig.hostname,
user: ftpConfig.username,
password: ftpConfig.password,
port: ftpConfig.port || 21
});
console.log('Connecting to FTP account... Ctrl+c to close cleanly, and again to force exit.');
// cleanly close ftp on process exit (Ctrl+c)
let isClosing = false;
process.on('SIGINT', function() {
ftpConnection.end();
if (isClosing) { // on double Ctrl+c, really exit
process.exit(1);
}
isClosing = true;
});
}
// begin watching directories
chokidar.watch('**/*', {
ignored: /[\/\\]\./,
persistent: true,
ignoreInitial: true // don't fire on existing files, only changes from now onwards
}).on('all', (event, path) => {
// console.log(event, path);
console.log('=> '+ event +' detected: ' + path);
if (ftpConnected && cli.flags.sass && path.includes('.scss')) {
renderSassToCss();
} else if (ftpConnected && cli.flags.ftpall) {
ftpUploadFile(path);
} else if (cli.flags.browsersync) {
browserSync.reload();
}
});
if (cli.flags.browsersync) {
let browserSyncInstance = browserSync.init({
proxy: "http://" + (cli.flags.url ? cli.flags.url : ftpConfig.hostname),
tunnel: true,
socket: {
domain: browserSync.instance.utils.devIp[0] + ':3000' // get the host ip
},
open: false,
logLevel: 'silent' // silent to stop browsersync saying where its live (as we're hacking to use http url instead of https)
});
// get the url, but force it to http instead of https
browserSyncInstance.events.on('service:running', function (bs) {
let url = bs.urls.tunnel.replace('https://', 'http://');
console.log('----------------------------------------------');
console.log('BrowserSync live site: \x1b[35m%s\x1b[0m', url);
console.log('BrowserSync admin UI: \x1b[35m%s\x1b[0m', bs.urls.ui);
console.log('----------------------------------------------');
});
}