3
3
namespace Ajaxray \ServerSync \Commands ;
4
4
5
5
use Illuminate \Console \Command ;
6
- use Illuminate \Support \Facades \DB ;
7
- use Illuminate \Support \Facades \Storage ;
8
6
use Illuminate \Support \Facades \Config ;
9
7
use Illuminate \Support \Facades \App ;
10
8
use Symfony \Component \Process \Process ;
@@ -15,6 +13,7 @@ class SyncPullCommand extends Command
15
13
{--host= : Production server hostname or IP}
16
14
{--user= : SSH username for production server}
17
15
{--path= : Path to production installation}
16
+ {--remote=production : Remote server configuration to use (e.g., production, staging)}
18
17
{--skip-db : Skip database sync}
19
18
{--skip-files : Skip files sync}
20
19
{--delete : Remove files that don \'t exist in production}
@@ -24,22 +23,28 @@ class SyncPullCommand extends Command
24
23
25
24
protected $ description = 'Pull and sync database and files from production to local environment ' ;
26
25
27
- protected string $ prodHost ;
28
- protected string $ prodUser ;
29
- protected string $ prodPath ;
26
+ protected string $ remoteHost ;
27
+ protected string $ remoteUser ;
28
+ protected string $ remotePath ;
30
29
31
30
public function handle ()
32
- {
31
+ {
33
32
if (App::environment ('production ' ) && !$ this ->option ('force ' )) {
34
33
$ this ->error ('This command cannot be run in production environment. Use --force to override. ' );
35
34
return 1 ;
36
35
}
37
36
38
- $ this ->prodHost = $ this ->option ('host ' ) ?: Config::get ('server-sync.production.host ' );
39
- $ this ->prodUser = $ this ->option ('user ' ) ?: Config::get ('server-sync.production.user ' );
40
- $ this ->prodPath = $ this ->option ('path ' ) ?: Config::get ('server-sync.production.path ' );
37
+ $ remote = $ this ->option ('remote ' );
38
+
39
+ $ this ->remoteHost = $ this ->option ('host ' ) ?: Config::get ("server-sync. $ remote.host " );
40
+ $ this ->remoteUser = $ this ->option ('user ' ) ?: Config::get ("server-sync. $ remote.user " );
41
+ $ this ->remotePath = $ this ->option ('path ' ) ?: Config::get ("server-sync. $ remote.path " );
42
+
43
+ if ($ remote ) {
44
+ $ this ->info ("Pulling from {$ this ->remoteHost } as {$ this ->remoteUser }" );
45
+ }
41
46
42
- if (!$ this ->validateRequirements ()) {
47
+ if (!$ this ->validateRequirements ()) {
43
48
return 1 ;
44
49
}
45
50
@@ -57,7 +62,7 @@ public function handle()
57
62
58
63
protected function validateRequirements (): bool
59
64
{
60
- if (!$ this ->prodHost || !$ this ->prodUser || !$ this ->prodPath ) {
65
+ if (!$ this ->remoteHost || !$ this ->remoteUser || !$ this ->remotePath ) {
61
66
$ this ->error ('Production server details are required. Please provide --host, --user and --path options or configure them in config/server-sync.php ' );
62
67
return false ;
63
68
}
@@ -75,12 +80,14 @@ protected function validateRequirements(): bool
75
80
}
76
81
77
82
// Test SSH connection
78
- $ testConnection = Process::fromShellCommandline ("ssh -q {$ this ->prodUser }@ {$ this ->prodHost } exit " );
79
- $ testConnection ->run ();
80
-
81
- if (!$ testConnection ->isSuccessful ()) {
82
- $ this ->error ('Failed to connect to production server. Please check your SSH configuration. ' );
83
- return false ;
83
+ if (!$ this ->option ('skip-db ' ) || !$ this ->option ('skip-files ' )) {
84
+ $ testConnection = Process::fromShellCommandline ("ssh -q {$ this ->remoteUser }@ {$ this ->remoteHost } exit " );
85
+ $ testConnection ->run ();
86
+
87
+ if (!$ testConnection ->isSuccessful ()) {
88
+ $ this ->error ('Failed to connect to production server. Please check your SSH configuration. ' );
89
+ return false ;
90
+ }
84
91
}
85
92
86
93
return true ;
@@ -165,9 +172,9 @@ protected function syncFiles()
165
172
'rsync -avz --compress %s %s --progress %s@%s:%s/%s/ %s/ ' ,
166
173
$ deleteFlag ,
167
174
$ excludeFlags ,
168
- $ this ->prodUser ,
169
- $ this ->prodHost ,
170
- $ this ->prodPath ,
175
+ $ this ->remoteUser ,
176
+ $ this ->remoteHost ,
177
+ $ this ->remotePath ,
171
178
$ relativePath ,
172
179
$ path
173
180
);
@@ -193,9 +200,9 @@ protected function getProductionDatabaseConfig(): ?array
193
200
$ this ->info ('Retrieving production database credentials... ' );
194
201
$ sshCommand = sprintf (
195
202
'ssh %s@%s "cd %s && grep -E \'^DB_(HOST|DATABASE|USERNAME|PASSWORD)= \' .env" ' ,
196
- $ this ->prodUser ,
197
- $ this ->prodHost ,
198
- $ this ->prodPath
203
+ $ this ->remoteUser ,
204
+ $ this ->remoteHost ,
205
+ $ this ->remotePath
199
206
);
200
207
201
208
$ process = Process::fromShellCommandline ($ sshCommand );
@@ -228,8 +235,8 @@ protected function buildMysqlDumpCommand(array $dbConfig, string $tempFile): str
228
235
{
229
236
$ command = sprintf (
230
237
'ssh %s@%s "mysqldump -h%s -u%s -p \'%s \' %s ' ,
231
- $ this ->prodUser ,
232
- $ this ->prodHost ,
238
+ $ this ->remoteUser ,
239
+ $ this ->remoteHost ,
233
240
$ dbConfig ['host ' ],
234
241
$ dbConfig ['username ' ],
235
242
$ dbConfig ['password ' ],
@@ -254,7 +261,7 @@ protected function buildMysqlDumpCommand(array $dbConfig, string $tempFile): str
254
261
255
262
// Create a temporary file on the remote server, then download it
256
263
$ remoteTempFile = '/tmp/temp_dump.sql ' ;
257
- $ command .= " > {$ remoteTempFile }\" && scp {$ this ->prodUser }@ {$ this ->prodHost }: {$ remoteTempFile } {$ tempFile } && ssh {$ this ->prodUser }@ {$ this ->prodHost } \"rm {$ remoteTempFile }\"" ;
264
+ $ command .= " > {$ remoteTempFile }\" && scp {$ this ->remoteUser }@ {$ this ->remoteHost }: {$ remoteTempFile } {$ tempFile } && ssh {$ this ->remoteUser }@ {$ this ->remoteHost } \"rm {$ remoteTempFile }\"" ;
258
265
259
266
return $ command ;
260
267
}
0 commit comments