Skip to content

Commit

Permalink
Add backup and restore commands (#27)
Browse files Browse the repository at this point in the history
* Create simple way to ask for site

* Initial version of backup command

* wip

* Restore database as part of restore process

* Update Restore.php

* Implement backup and restore using terminal commands

* Prefer kebab case for backup names

* Add notes

* wip

* Prompt changes

* Update Backup.php

* Add missing return types

* Clean up

* Document class

* Bail on backup if database export fails

* Add docs

* Update README.md

* Update Backup.php
  • Loading branch information
andrewjmead authored Nov 4, 2024
1 parent 09b7ab8 commit 64a050a
Show file tree
Hide file tree
Showing 11 changed files with 475 additions and 142 deletions.
270 changes: 168 additions & 102 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ https://github.com/user-attachments/assets/77ca8ba5-2e6e-45be-9d75-9e16f6056120

1. [Why?](#why)
1. [Getting started](#getting-started)
1. [Commands](#commands)
1. [Config](#config)
1. [Create](#create)
1. [Destroy](#destroy)
1. [Open](#open)
1. [Backup](#backup)
1. [Restore](#restore)
1. [Configuring WPSites](#configuring-wpsites)
1. [Template options](#template-options)
1. [Commands](#commands)
1. [Limitations](#limitations)

# Why?
Expand Down Expand Up @@ -150,6 +156,167 @@ Notice that you didn't need to log in to the admin panel. This is thanks to the

Creating your first site is just the beginning. Read on to learn how you can make your own templates to create sites specific to your needs!

# Commands

1. [Config](#config)
1. [Create](#create)
1. [Destroy](#destroy)
1. [Open](#open)
1. [Backup](#backup)
1. [Restore](#restore)

### Config

Run `wpsites config` to create the default config file. You can rerun `wpsites config` to reset the config file back to its default state.

```
$ wpsites config
Loading config file at "/Users/andrewmead/.wpsites.php"
Copying default config to `/Users/andrewmead/.wpsites.php`
Config file successfully created!
```

### Create

Run `wpsites create` to create a new WordPress site based on a template in your config file.

```
$ wpsites create
Loading config file at "/Users/andrewmead/.wpsites.php"
┌ Which template would you like to use? ───────────────────────┐
│ › ● Basic WordPress │
│ ○ Basic Multisite WordPress │
│ ○ Symlink plugin example │
│ ○ Bug recreation example │
└──────────────────────────────────────────────────────────────┘
┌ What slug would you like to use? ────────────────────────────┐
│ any-slug-you-like │
└──────────────────────────────────────────────────────────────┘
Downloading core files...
Creating site...
Creating database...
Running installation...
Enabling error log...
Enabling automatic login...
Installing default theme...
Opening site...
```

### Destroy

Run `wpsites destroy` to destroy one or more sites.

```
$ wpsites destroy
Loading config file at "/Users/andrewmead/.wpsites.php"
Checking which sites are WordPress sites...
┌ Which sites would you like to destroy? ──────────────────────┐
│ wp-test │
│ iawp │
└──────────────────────────────────────────────────────────────┘
┌ Are you sure you want to destroy the sites listed above? ────┐
│ Yes │
└──────────────────────────────────────────────────────────────┘
Deleting site "wp-test"
Deleting site "iawp"
```

### Open

Run `wpsites open` to open an existing site in your browser.

```
➜ ~ wpsites open
Loading config file at "/Users/andrewmead/.wpsites.php"
Checking which sites are WordPress sites...
┌ Select a site to open ───────────────────────────────────────┐
│ › ● iawp │
│ ○ latest-production-install │
│ ○ woocommerce │
└──────────────────────────────────────────────────────────────┘
```

### Backup

Run `wpsites backup` to create a backup of an existing site.

Backups are created in `~/.wpsites/backups/`. Each backup contains `db.sql` and `files.zip`.

These backups are not created in a proprietary format. The database export is created using WP CLI's [`wp db export`](https://developer.wordpress.org/cli/commands/db/export/). The file export is just a zip of the WordPress files. That means you can take them with you if you decide to stop using WPSites.

```
➜ ~ wpsites backup
Loading config file at "/Users/andrewmead/.wpsites.php"
Checking which sites are WordPress sites...
┌ Select a site to backup ─────────────────────────────────────┐
│ iawp │
└──────────────────────────────────────────────────────────────┘
┌ Pick a name for the backup ──────────────────────────────────┐
│ before-migration │
└──────────────────────────────────────────────────────────────┘
Backing up database
Backing up files
Backup successfully created!
Backup saved to /Users/andrewmead/.wpsites/backups/before-migration
```

### Restore

Run `wpsites restore` to restore a backup.

```
➜ ~ wpsites restore
Loading config file at "/Users/andrewmead/.wpsites.php"
┌ Select a backup to use ──────────────────────────────────────┐
│ before-migration (2024-11-04 2:51 pm) │
└──────────────────────────────────────────────────────────────┘
Checking which sites are WordPress sites...
┌ Select a site to restore ────────────────────────────────────┐
│ iawp │
└──────────────────────────────────────────────────────────────┘
Restoring files
Importing database
Backup successfully restored!
```

# Configuring WPSites

In this section, you'll learn how to customize WPSites to fit your needs. This includes defining a reasonable set of defaults, as well as defining your own templates so you can quickly spin up a preconfigured site.
Expand Down Expand Up @@ -498,107 +665,6 @@ An array of options to set in the options database table. The value should be an
]
```

# Commands

1. [Config](#config)
1. [Create](#create)
1. [Destroy](#destroy)
1. [Open](#open)

### Config

Run `wpsites config` to create the default config file. You can rerun `wpsites config` to reset the config file back to its default state.

```
$ wpsites config
Loading config file at "/Users/andrewmead/.wpsites.php"
Copying default config to `/Users/andrewmead/.wpsites.php`
Config file successfully created!
```

### Create

Run `wpsites create` to create a new WordPress site based on a template in your config file.

```
$ wpsites create
Loading config file at "/Users/andrewmead/.wpsites.php"
┌ Which template would you like to use? ───────────────────────┐
│ › ● Basic WordPress │
│ ○ Basic Multisite WordPress │
│ ○ Symlink plugin example │
│ ○ Bug recreation example │
└──────────────────────────────────────────────────────────────┘
┌ What slug would you like to use? ────────────────────────────┐
│ any-slug-you-like │
└──────────────────────────────────────────────────────────────┘
Downloading core files...
Creating site...
Creating database...
Running installation...
Enabling error log...
Enabling automatic login...
Installing default theme...
Opening site...
```

### Destroy

Run `wpsites destroy` to destroy one or more sites.

```
$ wpsites destroy
Loading config file at "/Users/andrewmead/.wpsites.php"
Checking which sites are WordPress sites...
┌ Which sites would you like to destroy? ──────────────────────┐
│ wp-test │
│ iawp │
└──────────────────────────────────────────────────────────────┘
┌ Are you sure you want to destroy the sites listed above? ────┐
│ Yes │
└──────────────────────────────────────────────────────────────┘
Deleting site "wp-test"
Deleting site "iawp"
```

### Open

Run `wpsites open` to open an existing site in your browser.

```
➜ ~ wpsites open
Loading config file at "/Users/andrewmead/.wpsites.php"
Checking which sites are WordPress sites...
┌ Which site would you link to open? ──────────────────────────┐
│ › ● iawp │
│ ○ latest-production-install │
│ ○ woocommerce │
└──────────────────────────────────────────────────────────────┘
```

# Limitations

I only use macOS, so I haven't verified that WPSites does (or doesn't!) work on Windows or Linux. I hope to get it running in those environments at some point. If you run into problems, please open an issue so I can support those platforms.
12 changes: 9 additions & 3 deletions app/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@
use Illuminate\Support\Str;
use Phar;

class Command
/**
* Transform a command and associative array of arguments into a single string command. WP CLI commands
* that start with "wp " will be modified to use wpsites-wp-cli.phar that ships with the project.
*
* $command = Command::from('wp some command', [ 'argument' => 'value' ]);
*/
readonly class Command
{
public function __construct(private readonly string $command, private readonly array $arguments = [])
private function __construct(private string $command, private array $arguments = [])
{
}

public function toString(): string
private function toString(): string
{
return $this->command() . ' ' . $this->arguments();

Expand Down
50 changes: 50 additions & 0 deletions app/Commands/Backup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace App\Commands;

use function Laravel\Prompts\error;
use function Laravel\Prompts\text;

use LaravelZero\Framework\Commands\Command;

class Backup extends SiteCommand
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'backup';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Backup a site';

/**
* Execute the console command.
*/
public function handle(): void
{
$site = $this->ask_user_for_site('Select a site to backup');
$name = text(
label: 'Pick a name for the backup',
placeholder: 'backup-name',
required: true,
validate: function (string $value) {
if (!$this->is_valid_kebab_name($value)) {
return 'Only lowercase letters, numbers, and hyphens are allowed';
}

return null;
},
);
$success = $site->backup($name);

if (!$success) {
error('Unable to run backup');
}
}
}
2 changes: 1 addition & 1 deletion app/Commands/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function handle()

if (ConfigFile::exists()) {
$confirmed = confirm(
label: 'Config file already exists. Do you want to override it?',
label: 'Config file already exists. Override it?',
default: false,
);

Expand Down
Loading

0 comments on commit 64a050a

Please sign in to comment.