PhpStorm. Лайфхак: keep-alive automatic upload на коленке

от автора

Многие сталкивались с проблемой Automatic Upload в PhpStorm (сюда можно вписать другую IDE с подобной проблемой) при работе на удаленном сервере. Называть ее «проблемой» тоже можно с натяжкой, но тема жива: PhpStorm при заливке измененных файлов каждый раз поднимает новое подключение, что занимает достаточно ощутимое время (у меня уж точно: хостинг-провайдер Hetzner), поэтому приходится ждать несколько секунд прежде чем изменения зальются.

Под катом я расскажу как на коленке набросал скрипт keep-alive подключения с Automatic Upload проекта.

В тексте будет много кода и мало комметариев. Связано это с тем что комментировать там и нечего: для новичков разобраться в NodeJS помогут гайды и статьи (но в это в любом случае JavaScript), а для бывалых код-ревью скажет больше чем я.

Сам скрипт написан на NodeJS — он достаточно прост и всегда находится под рукой, поэтому выбор был очевиден. Подключение я использую SFTP. Итак что нам нужно:

  • Мониторинг файлов на изменение
  • Upload измененных файлов на удаленный сервер

Я решил не углубляться в идеальные для этого библиотеки — не хотелось тратить на эту задачу достаточно много времени. Беглый просмотр интернетов навел меня на 2 простеньких модуля:

  • chokidar — мониторинг файлов
  • ssh2 — ссш-коннект к серверу

Описывать как их устанавливать и как работает NodeJS не буду — гайдов полно на том же хабре.

Файлик я назвал незамысловато deploy.js. Первые строки выглядят просто:

var fs = require('fs'); var Connection = require('ssh2'); var Сhokidar = require('chokidar'); var c = new Connection(); 

Итак, библиотеки подключили. Первым делом надо подключиться к серверу:

c.connect({         host: 'habrahabr.ru',         port: 1500, 	username: 'habr', 	password: 'habrapassword' }); 

Как у большинства модулей у ssh2 есть события. Выведем их в лог:

c.on('connect', function() { 	console.log('Connection :: connect'); }); c.on('error', function(err) { 	console.log('Connection :: error :: ' + err); }); c.on('end', function() { 	console.log('Connection :: end'); }); c.on('close', function(had_error) { 	console.log('Connection :: close'); }); 

Ну и конечно то с чем мы и будем работать:

c.on('ready', function() {         .... }) 

В этом модуле есть достаточно полезная фича — sftp: достаточно удобный и простой менеджер для работы с файлами:

c.sftp(function(err,sftp){ 		if(!err){ 			console.log('sftp start'); 		}else{ 			console.log('sftp err',err); 		} 	}); 

Когда подключение поднято — пришло время внедрить мониторинг файлов:

			var watcher = chokidar.watch(local_path, 				{ignored: // функция отвечающая за игнорирование файлов. я добавил сюда пути папки SVN и самого PhpStorm 					function(path){ 						if(path.indexOf(".idea") >= 0 || path.indexOf(".svn") >= 0 || path == (local_path+'/dpl')){ 							return true; 						} 					}, 					ignoreInitial:true // параметр отчающий за игнорирование файлов при инициализации скрипта. Если false - будет литься весь проект при каждом запуске 				}); 

У вотчера есть события add, change, unlink , которые и отрабатывают при манипуляции с файлами. Дело осталось за малым: заставить модуль ssh2 дублировать изменения проекта по sftp:

			watcher 				.on('add', function(path,meta) {  					console.log('upload added',path.replace(local_path,deploy_path));  					sftp.fastPut(path,path.replace(local_path,deploy_path),{},function(err){ 						if(err){ 							console.log('sftp upload err',err); 						} 					}); 				}) 				.on('change', function(path) {  					console.log('upload changed',path.replace(local_path,deploy_path));  					sftp.fastPut(path,path.replace(local_path,deploy_path),{},function(err){ 						if(err){ 							console.log('sftp change err',err); 						} 					}); 				}) 				.on('unlink', function(path) { 					console.log('remove file',path.replace(local_path,deploy_path));  					sftp.unlink(path.replace(local_path,deploy_path),function(err){ 						if(err){ 							console.log('sftp remove err',err); 						} 					}); 				}) 				.on('error', function(error) {console.error('Error happened', error);}) 

Готово! Файлы заливаются быстрее чем мы табаемся в браузер! По поводу нагрузки — скрипт кушает ЦП примерно как скайп (MacBook Air mid 2012), так что вполне терпимо.

Чтобы не дублировать на каждый проект по деплоеру я набросал легкий Bash скрипт, который бросаю в корень проекта, он уже и запускает наш скрипт.

#!/bin/bash  DEPLOY_PATH="/deploy/path"  DEPLOYER_PATH="/path/to/deploy.js"  SOURCE="${BASH_SOURCE[0]}" while [ -h "$SOURCE" ]; do    TARGET="$(readlink "$SOURCE")"   if [[ $SOURCE == /* ]]; then     echo "SOURCE '$SOURCE' is an absolute symlink to '$TARGET'"     SOURCE="$TARGET"   else     DIR="$( dirname "$SOURCE" )"     echo "SOURCE '$SOURCE' is a relative symlink to '$TARGET' (relative to '$DIR')"     SOURCE="$DIR/$TARGET"   fi done  RDIR="$( dirname "$SOURCE" )" DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" if [ "$DIR" != "$RDIR" ]; then   echo "local_path is '$DIR'" fi  node $DEPLOYER_PATH local_path=$DIR deploy_path=$DEPLOY_PATH 

Ну и в этом случае конечно надо получить параметры в deploy.js

var local_path; var deploy_path;  process.argv.forEach(function (val, index, array) { 	var item_arr = val.split('='); 	if(item_arr.length > 1){ 		switch(item_arr[0]){ 			case 'local_path': 				local_path = item_arr[1]; 				break; 			case 'deploy_path': 				deploy_path = item_arr[1]; 				break; 		} 	} }); 

Скрипт прост и подходит для многих других задач. Например можно перезапускать NodeJS приложение на удаленном сервера после заливки файла, или дублировать картинки с окружения разработчика на общий dev сервер.

Прикладываю файл скрипта.

Скрипт был написан примерно за час, поэтому в нем могут быть глупости и банальные ошибки, поэтому прошу не судить строго. Смысл поста — не предоставить идеально работающий код а навести на мысли о возможном решении. Долгие часы я шарился в интернетах в поисках плагинов или хаков, но ничего не нашел. Идея пришла сама собой, с выходом нового PhpStorm, когда увидел поддержку консоли в IDE.

Спасибо за внимание и конструктивную критику!

ссылка на оригинал статьи http://habrahabr.ru/company/rangg/blog/202728/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *