wordmove 1.3.0.pre2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 93d562d9eedcf4142b15279b786de308bef1aa1e
4
- data.tar.gz: a56e964fa64606740a27415a8eb76d31550f710a
3
+ metadata.gz: ef259f42e99168010fa346b266b25ae9e116f633
4
+ data.tar.gz: 11fe30b4ff34778cb26a26d74c23e04da4a9e3bf
5
5
  SHA512:
6
- metadata.gz: ca1dc544d5228b2cbe473bd1308eb9acf5eaa66424c0d3d8776879d024a0ecaffae70bbf020d89a21c0e7781c965b6e327cba0a1c96dab31b535223200febef4
7
- data.tar.gz: 346965aa474662a79bad2d430ed50c5723975b05bfa843c3201113e5098b50796e3eb6f476bf683a85904f74a307e5200b7895f35c06dfbee00ad3d4883efa80
6
+ metadata.gz: 37f218ec6741be9fb5fe47737f7b740b011ce709b5d40047e43986944219161443ddcc67c6534f38ab20c1be83f35ad6d7368fb658ea5711247996022b72436b
7
+ data.tar.gz: 6e685dad79f7679c1d7b926e698c85dc8cf70c1d267065ff5f8fa96d58daf8cb252e9f5ff65b071bdc9b6623353939868dda3d8ca1ba8d66c7dceb0f6a233926
data/.gitignore CHANGED
@@ -12,6 +12,8 @@ lib/bundler/man
12
12
  pkg
13
13
  rdoc
14
14
  spec/reports
15
+ spec/coverage
16
+ spec/examples.txt
15
17
  test/tmp
16
18
  test/version_tmp
17
19
  tmp
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --color
2
+ --require spec_helper
data/.travis.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.0.0
4
- - 2.1.5
4
+ - 2.1.6
5
5
  - 2.2.2
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ # 1.3.0.pre
2
+
3
+ - required ruby version ~> 2.0
4
+ - replace `escape` gem with `Shellwords`
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'http://rubygems.org'
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in wordmove.gemspec
4
4
  gemspec
data/README.mdown CHANGED
@@ -1,5 +1,7 @@
1
1
  # Wordmove
2
2
 
3
+ ![logo](https://raw.githubusercontent.com/welaika/wordmove/master/assets/images/wordmove.png)
4
+
3
5
  Wordmove is a nice little gem that lets you automatically mirror local Wordpress
4
6
  installations and DB data back and forth from your local development machine to
5
7
  the remote staging server. SSH and FTP connections are both supported.
@@ -148,6 +150,9 @@ too much about security though: the script is deleted just after the usage,
148
150
  and can only be executed by `wordmove`, as each time it requires a pre-shared
149
151
  one-time-password to be run.
150
152
 
153
+ ## Need more tools?
154
+ Visit [Wordpress Tools](http://wptools.it).
155
+
151
156
  ## Credits
152
157
 
153
158
  * The dump script is the [`MYSQL-dump` PHP package](https://github.com/dg/MySQL-dump) by David Grudl;
data/Rakefile CHANGED
@@ -1,7 +1,5 @@
1
- #!/usr/bin/env rake
2
-
3
1
  require "bundler/gem_tasks"
4
- require 'rspec/core/rake_task'
2
+ require "rspec/core/rake_task"
5
3
 
6
4
  RSpec::Core::RakeTask.new(:spec)
7
- task :default => :spec
5
+ task default: :spec
Binary file
data/bin/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "wordmove"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ require "pry"
10
+ Pry.start
data/bin/rake ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rake' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rake', 'rake')
data/bin/rspec ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rspec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rspec-core', 'rspec')
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/exe/wordmove ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
4
+
5
+ require 'wordmove'
6
+ Wordmove::CLI.start
data/lib/wordmove.rb CHANGED
@@ -1,4 +1,29 @@
1
+ require 'thor'
2
+ require 'thor/group'
3
+ require 'colorize'
4
+ require 'logger'
5
+ require 'yaml'
6
+ require 'ostruct'
7
+ require 'erb'
8
+ require 'open-uri'
9
+ require 'active_support'
10
+ require 'active_support/core_ext'
11
+
12
+ require 'photocopier'
13
+
14
+ require 'wordmove/exceptions'
15
+ require 'wordmove/cli'
16
+ require 'wordmove/logger'
17
+ require 'wordmove/sql_adapter'
1
18
  require "wordmove/version"
19
+ require 'wordmove/wordpress_directory'
20
+
21
+ require 'wordmove/generators/movefile_adapter'
22
+ require 'wordmove/generators/movefile'
23
+
24
+ require 'wordmove/deployer/base'
25
+ require 'wordmove/deployer/ftp'
26
+ require 'wordmove/deployer/ssh'
2
27
 
3
28
  module Wordmove
4
29
  end
@@ -1,186 +1,223 @@
1
1
  <?php
2
2
 
3
+ $shared_key = '<%= password %>';
4
+ if ($_GET['shared_key'] != $shared_key) {
5
+ die();
6
+ }
7
+
3
8
  /**
4
9
  * MySQL database dump.
5
10
  *
6
- * @author David Grudl
11
+ * @author David Grudl (http://davidgrudl.com)
7
12
  * @copyright Copyright (c) 2008 David Grudl
8
13
  * @license New BSD License
9
- * @link http://phpfashion.com/
10
- * @version 0.9
14
+ * @version 1.0
11
15
  */
12
-
13
16
  class MySQLDump
14
17
  {
15
- const MAX_SQL_SIZE = 1e6;
16
-
17
- /** @var mysqli */
18
- private $connection;
19
-
20
- /**
21
- * Connects to database.
22
- * @param mysqli connection
23
- */
24
- public function __construct(mysqli $connection)
25
- {
26
- $this->connection = $connection;
27
-
28
- if ($this->connection->connect_errno) {
29
- throw new Exception($this->connection->connect_error);
30
- }
31
- }
32
-
33
- /**
34
- * Sends dump to browser.
35
- * @param string filename
36
- * @return void
37
- */
38
- public function send($file)
39
- {
40
- $this->write(fopen('php://output', 'wb'));
41
- }
42
-
43
- /**
44
- * Writes dump to logical file.
45
- * @param resource
46
- * @return void
47
- */
48
- public function write($handle)
49
- {
50
- if (!is_resource($handle) || get_resource_type($handle) !== 'stream') {
51
- throw new Exception('Argument must be stream resource.');
52
- }
53
-
54
- if (!$this->connection->set_charset('utf8')) { // was added in MySQL 5.0.7 and PHP 5.0.5, fixed in PHP 5.1.5)
55
- throw new Exception($this->connection->error);
56
- }
57
-
58
- $views = $tables = array();
59
-
60
- $res = $this->connection->query('SHOW TABLES');
61
- while ($row = $res->fetch_row()) {
62
- $tables[] = $row[0];
63
- }
64
- $res->close();
65
-
66
- $db = $this->connection->query('SELECT DATABASE()')->fetch_row();
67
- fwrite($handle, "-- David Grudl MySQL Dump Utility\n"
68
- . "-- Created at " . date('j.n.Y G:i') . "\n"
69
- . (isset($_SERVER['HTTP_HOST']) ? "-- Host: $_SERVER[HTTP_HOST]\n" : '')
70
- . "-- Server: " . $this->connection->server_info . "\n"
71
- . "-- Codepage: " . $this->connection->character_set_name() . "\n"
72
- . "-- Database: " . $db[0] . "\n"
73
- . "-- Tables: " . implode(', ', $tables) . "\n"
74
- . "\n"
75
- . "SET NAMES utf8;\n"
76
- . "SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';\n"
77
- . "SET FOREIGN_KEY_CHECKS=0;\n");
78
-
79
- foreach ($tables as $table)
80
- {
81
- $res = $this->connection->query("SHOW CREATE TABLE `$table`");
82
- $row = $res->fetch_assoc();
83
- $res->close();
84
-
85
- if (isset($row['Create View'])) {
86
- $views[$table] = $row['Create View'];
87
- continue;
88
- }
89
-
90
- fwrite($handle, "-- --------------------------------------------------------\n\n");
91
- fwrite($handle, "DROP TABLE IF EXISTS `$table`;\n\n");
92
- fwrite($handle, $row['Create Table'] . ";\n\n");
93
-
94
- $numeric = array();
95
- $res = $this->connection->query("SHOW COLUMNS FROM `$table`");
96
- $cols = array();
97
- while ($row = $res->fetch_assoc()) {
98
- $col = $row['Field'];
99
- $cols[] = '`' . str_replace('`', '``', $col) . '`';
100
- preg_match('/^([a-z]+)/', $row['Type'], $matches);
101
- $type = strtolower($matches[1]);
102
- $numeric[$col] = in_array($type, array('byte','counter','serial','int','long','currency','real','money','float','double','decimal','numeric','number'));
103
- }
104
- $cols = '(' . implode(', ', $cols) . ')';
105
- $res->close();
106
-
107
-
108
- $size = 0;
109
- $res = $this->connection->query("SELECT * FROM `$table`", MYSQLI_USE_RESULT);
110
- while ($row = $res->fetch_assoc()) {
111
- $s = '(';
112
- foreach ($row as $key => $value) {
113
- if ($value === NULL) {
114
- $s .= "NULL,\t";
115
- } elseif ($numeric[$key]) {
116
- $s .= $value . ",\t";
117
- } else {
118
- $s .= "'" . $this->connection->real_escape_string($value) . "',\t";
119
- }
120
- }
121
-
122
- if ($size == 0) {
123
- $s = "INSERT INTO `$table` $cols VALUES\n$s";
124
- } else {
125
- $s = ",\n$s";
126
- }
127
-
128
- $len = strlen($s) - 1;
129
- $s[$len - 1] = ')';
130
- fwrite($handle, $s, $len);
131
-
132
- $size += $len;
133
- if ($size > self::MAX_SQL_SIZE) {
134
- fwrite($handle, ";\n");
135
- $size = 0;
136
- }
137
- }
138
-
139
- if ($size) fwrite($handle, ";\n");
140
- $res->close();
141
-
142
- fwrite($handle, "\n\n");
143
- }
144
-
145
- foreach ($views as $view => $sql)
146
- {
147
- fwrite($handle, "-- --------------------------------------------------------\n\n");
148
- fwrite($handle, "DROP VIEW IF EXISTS `$view`;\n\n$sql;\n\n");
149
- }
150
-
151
- fwrite($handle, "-- THE END\n");
152
- fclose($handle);
153
- }
154
- }
18
+ const MAX_SQL_SIZE = 1e6;
19
+
20
+ const NONE = 0;
21
+ const DROP = 1;
22
+ const CREATE = 2;
23
+ const DATA = 4;
24
+ const TRIGGERS = 8;
25
+ const ALL = 15; // DROP | CREATE | DATA | TRIGGERS
26
+
27
+ /** @var array */
28
+ public $tables = array(
29
+ '*' => self::ALL,
30
+ );
31
+
32
+ /** @var mysqli */
33
+ private $connection;
34
+
35
+
36
+ /**
37
+ * Connects to database.
38
+ * @param mysqli connection
39
+ */
40
+ public function __construct(mysqli $connection, $charset = 'utf8'
41
+ {
42
+ $this->connection = $connection;
43
+
44
+ if ($connection->connect_errno) {
45
+ throw new Exception($connection->connect_error);
46
+
47
+ } elseif (!$connection->set_charset($charset)) { // was added in MySQL 5.0.7 and PHP 5.0.5, fixed in PHP 5.1.5)
48
+ throw new Exception($connection->error);
49
+ }
50
+ }
51
+
52
+
53
+ /**
54
+ * Saves dump to the file.
55
+ * @param string filename
56
+ * @return void
57
+ */
58
+ public function save($file)
59
+ {
60
+ $handle = strcasecmp(substr($file, -3), '.gz') ? fopen($file, 'wb') : gzopen($file, 'wb');
61
+ if (!$handle) {
62
+ throw new Exception("ERROR: Cannot write file '$file'.");
63
+ }
64
+ $this->write($handle);
65
+ }
66
+
67
+
68
+ /**
69
+ * Writes dump to logical file.
70
+ * @param resource
71
+ * @return void
72
+ */
73
+ public function write($handle = NULL)
74
+ {
75
+ if ($handle === NULL) {
76
+ $handle = fopen('php://output', 'wb');
77
+ } elseif (!is_resource($handle) || get_resource_type($handle) !== 'stream') {
78
+ throw new Exception('Argument must be stream resource.');
79
+ }
80
+
81
+ $tables = array();
82
+
83
+ $res = $this->connection->query('SHOW TABLES');
84
+ while ($row = $res->fetch_row()) {
85
+ $tables[] = $row[0];
86
+ }
87
+ $res->close();
88
+
89
+ $this->connection->query('LOCK TABLES `' . implode('` READ, `', $tables) . '` READ');
90
+
91
+ $db = $this->connection->query('SELECT DATABASE()')->fetch_row();
92
+ fwrite($handle, "-- Created at " . date('j.n.Y G:i') . " using David Grudl MySQL Dump Utility\n"
93
+ . (isset($_SERVER['HTTP_HOST']) ? "-- Host: $_SERVER[HTTP_HOST]\n" : '')
94
+ . "-- MySQL Server: " . $this->connection->server_info . "\n"
95
+ . "-- Database: " . $db[0] . "\n"
96
+ . "\n"
97
+ . "SET NAMES utf8;\n"
98
+ . "SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';\n"
99
+ . "SET FOREIGN_KEY_CHECKS=0;\n"
100
+ );
101
+
102
+ foreach ($tables as $table) {
103
+ $this->dumpTable($handle, $table);
104
+ }
105
+
106
+ fwrite($handle, "-- THE END\n");
107
+
108
+ $this->connection->query('UNLOCK TABLES');
109
+ }
110
+
111
+
112
+ /**
113
+ * Dumps table to logical file.
114
+ * @param resource
115
+ * @return void
116
+ */
117
+ public function dumpTable($handle, $table)
118
+ {
119
+ $delTable = $this->delimite($table);
120
+ $res = $this->connection->query("SHOW CREATE TABLE $delTable");
121
+ $row = $res->fetch_assoc();
122
+ $res->close();
123
+
124
+ fwrite($handle, "-- --------------------------------------------------------\n\n");
125
+
126
+ $mode = isset($this->tables[$table]) ? $this->tables[$table] : $this->tables['*'];
127
+ $view = isset($row['Create View']);
128
+
129
+ if ($mode & self::DROP) {
130
+ fwrite($handle, 'DROP ' . ($view ? 'VIEW' : 'TABLE') . " IF EXISTS $delTable;\n\n");
131
+ }
132
+
133
+ if ($mode & self::CREATE) {
134
+ fwrite($handle, $row[$view ? 'Create View' : 'Create Table'] . ";\n\n");
135
+ }
136
+
137
+ if (!$view && ($mode & self::DATA)) {
138
+ $numeric = array();
139
+ $res = $this->connection->query("SHOW COLUMNS FROM $delTable");
140
+ $cols = array();
141
+ while ($row = $res->fetch_assoc()) {
142
+ $col = $row['Field'];
143
+ $cols[] = $this->delimite($col);
144
+ $numeric[$col] = (bool) preg_match('#^[^(]*(BYTE|COUNTER|SERIAL|INT|LONG$|CURRENCY|REAL|MONEY|FLOAT|DOUBLE|DECIMAL|NUMERIC|NUMBER)#i', $row['Type']);
145
+ }
146
+ $cols = '(' . implode(', ', $cols) . ')';
147
+ $res->close();
148
+
149
+
150
+ $size = 0;
151
+ $res = $this->connection->query("SELECT * FROM $delTable", MYSQLI_USE_RESULT);
152
+ while ($row = $res->fetch_assoc()) {
153
+ $s = '(';
154
+ foreach ($row as $key => $value) {
155
+ if ($value === NULL) {
156
+ $s .= "NULL,\t";
157
+ } elseif ($numeric[$key]) {
158
+ $s .= $value . ",\t";
159
+ } else {
160
+ $s .= "'" . $this->connection->real_escape_string($value) . "',\t";
161
+ }
162
+ }
163
+
164
+ if ($size == 0) {
165
+ $s = "INSERT INTO $delTable $cols VALUES\n$s";
166
+ } else {
167
+ $s = ",\n$s";
168
+ }
169
+
170
+ $len = strlen($s) - 1;
171
+ $s[$len - 1] = ')';
172
+ fwrite($handle, $s, $len);
173
+
174
+ $size += $len;
175
+ if ($size > self::MAX_SQL_SIZE) {
176
+ fwrite($handle, ";\n");
177
+ $size = 0;
178
+ }
179
+ }
180
+
181
+ $res->close();
182
+ if ($size) {
183
+ fwrite($handle, ";\n");
184
+ }
185
+ fwrite($handle, "\n");
186
+ }
187
+
188
+ if ($mode & self::TRIGGERS) {
189
+ $res = $this->connection->query("SHOW TRIGGERS LIKE '" . $this->connection->real_escape_string($table) . "'");
190
+ if ($res->num_rows) {
191
+ fwrite($handle, "DELIMITER ;;\n\n");
192
+ while ($row = $res->fetch_assoc()) {
193
+ fwrite($handle, "CREATE TRIGGER {$this->delimite($row['Trigger'])} $row[Timing] $row[Event] ON $delTable FOR EACH ROW\n$row[Statement];;\n\n");
194
+ }
195
+ fwrite($handle, "DELIMITER ;\n\n");
196
+ }
197
+ $res->close();
198
+ }
199
+
200
+ fwrite($handle, "\n");
201
+ }
202
+
203
+
204
+ private function delimite($s)
205
+ {
206
+ return '`' . str_replace('`', '``', $s) . '`';
207
+ }
155
208
 
156
- function get_connection($db_host, $db_user, $db_password, $db_name, $db_port, &$error = NULL) {
157
- $db_connection = new mysqli($db_host, $db_user, $db_password, $db_name, $db_port);
158
- if (!$db_connection || !$db_connection->select_db($db_name)) {
159
- if ($db_connection) {
160
- $error = mysqli_connect_error();
161
- } else {
162
- $error = "Unable to connect to mysql database";
163
- }
164
- return NULL;
165
- }
166
- return $db_connection;
167
209
  }
168
210
 
169
211
  $db_host = '<%= escape_php db[:host] %>';
170
- $db_port = '<%= escape_php db[:port] %>';
212
+ $db_port = '<%= db[:port] %>';
171
213
  if (!$db_port) {
172
214
  $db_port = ini_get("mysqli.default_port");
173
215
  }
174
216
  $db_user = '<%= escape_php db[:user] %>';
175
217
  $db_password = '<%= escape_php db[:password] %>';
176
218
  $db_name = '<%= escape_php db[:name] %>';
177
- $shared_key = '<%= password %>';
178
-
179
- $mysql_error = '';
180
-
181
- if ($_GET['shared_key'] == $shared_key) {
182
- $connection = get_connection($db_host, $db_user, $db_password, $db_name, $db_port, $mysql_error);
183
- $dump = new MySQLDump($connection);
184
- $dump->send('dump.mysql');
185
- }
219
+ $db_charset = '<%= escape_php db[:charset] %>';
186
220
 
221
+ $connection = new mysqli($db_host, $db_user, $db_password, $db_name, $db_port);
222
+ $dump = new MySQLDump($connection, $db_charset);
223
+ $dump->save('dump.mysql');