]> scripts.mit.edu Git - wizard.git/commitdiff
Finish repository conversion docs, move re_define to app.php.
authorEdward Z. Yang <ezyang@mit.edu>
Thu, 19 Nov 2009 18:21:17 +0000 (13:21 -0500)
committerEdward Z. Yang <ezyang@mit.edu>
Thu, 19 Nov 2009 18:21:17 +0000 (13:21 -0500)
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
TODO
doc/module/wizard.app.php.rst
doc/repository-conversion.rst
wizard/app/php.py
wizard/app/wordpress.py

diff --git a/TODO b/TODO
index c55b94d04be4e6acb2a5f7d3dbf42fefe686b1aa..f83867461576a6cf6944321d0ffac3a6f4d6cea9 100644 (file)
--- a/TODO
+++ b/TODO
@@ -2,6 +2,9 @@ The Git Autoinstaller
 
 TODO NOW:
 
+- Test code should auto-nuke the database using `wizard remove` before doing a new install
+- git diff :1:$file :2:$file to find out what the user did, or is it :3:?
+- Document how to fix a broken upgrade
 - php.ini needs to get substituted!
 - Make wizard install accept appname-head (so that you can do a test with
   head, and do things without tags).  Also make it accept commit hashes.
index c46732dbb45daeb1a2539e0a96ef970493e73de6..ddef120af5bb74daf6e265d80b1f07c3d681f5cf 100644 (file)
@@ -6,6 +6,7 @@
 Functions
 ---------
 .. autofunction:: re_var
+.. autofunction:: re_define
 
 Data
 ----
index 171f592db46ddcc70bf76a64d543d761cd2207ee..b1d0699cf06346aacdca5a18f723e923b331bd37 100644 (file)
@@ -346,8 +346,10 @@ the deployment, so you can simplify your code accordingly:
 
 .. code-block:: python
 
-    def checkConfig(self, deployment):
-        return os.path.isfile("wp-config.php")
+    class Application(app.Application):
+        # ...
+        def checkConfig(self, deployment):
+            return os.path.isfile("wp-config.php")
 
 :meth:`~wizard.app.Application.detectVersion` should detect the version of the application
 by regexing it out of a source file.  We first have to figure out where the version number
@@ -377,24 +379,129 @@ in the string, so the former is relatively safe.
 
 .. code-block:: python
 
-    def detectVersion(self, deployment):
-        contents = open("wp-includes/version.php").read()
-        match = php.re_var("wp_version").search(contents)
-        if not match: return None
-        return distutils.version.LooseVersion(match.group(2)[1:-1])
+    class Application(app.Application):
+        # ...
+        def detectVersion(self, deployment):
+            contents = open("wp-includes/version.php").read()
+            match = php.re_var("wp_version").search(contents)
+            if not match: return None
+            return distutils.version.LooseVersion(match.group(2)[1:-1])
 
 :attr:`~wizard.app.Application.parametrized_files` is a simple list of files that the
 program's installer wrote or touched during the installation process.
 
 .. code-block:: python
 
-    parametrized_files = ['wp-config.php']
+    class Application(app.Application):
+        # ...
+        parametrized_files = ['wp-config.php']
 
 This is actually is a lie: we also need to include changes to :file:`php.ini` that
 we made:
 
 .. code-block:: python
 
-    parametrized_files = ['wp-config.php'] + php.parametrized_files
+    class Application(app.Application):
+        # ...
+        parametrized_files = ['wp-config.php'] + php.parametrized_files
+
+And finally, we have :attr:`~wizard.app.Application.extractors` and
+:attr:`~wizard.app.Application.substitutions`.  At the bare metal, these
+are simply dictionaries of variable names to functions: when you call the
+function, it performs either an extraction or a substitution.  However, we can
+use higher-level constructs to generate these functions for us.
+
+The magic sauce is a data structure we'll refer to as ``seed``.  Its form is
+a dictionary of variable names to a tuple ``(filename, regular expression)``.
+If we manually coded one out, it might look like:
+
+.. code-block:: python
+
+    seed = {
+        'WIZARD_DBSERVER': ('wp-config.php', re.compile(r'''^(define\('DB_HOST', )(.*)(\))''', re.M)),
+        'WIZARD_DBNAME': ('wp-config.php', re.compile(r'''^(define\('DB_NAME', )(.*)(\)), re.M)),
+    }
+
+There's a lot of duplication, though.  For one thing, the regular expressions are almost
+identical, safe for a single substitution within the string.  We have a function
+:meth:`wizard.app.php.re_define` that does this for us:
+
+.. code-block:: python
+
+    seed = {
+        'WIZARD_DBSERVER': ('wp-config.php', php.re_define('DB_HOST')),
+        'WIZARD_DBNAME': ('wp-config.php', php.re_define('DB_NAME')),
+    }
+
+.. note::
+
+    If you find yourself needing to define a custom regular expression generation function,
+    be sure to use :func:`wizard.app.expand_re`, which will escape an incoming variable
+    to be safe for inclusion in a regular expression, and also let you pass a list,
+    and have correct behavior.  Check out :mod:`wizard.app.php` for some examples.
+
+We can shorten this even further: in most cases, all of the configuration values live in
+one file, so let's make ourselves a function that generates the whole tuple:
+
+.. code-block:: python
+
+    def make_filename_regex_define(var):
+        return 'wp-config.php', php.re_define(var)
+
+Then we can use :func:`util.dictmap` to apply this:
+
+.. code-block:: python
+
+    seed = util.dictmap(make_filename_regex_define, {
+        'WIZARD_DBSERVER': 'DB_HOST',
+        'WIZARD_DBNAME': 'DB_NAME',
+        'WIZARD_DBUSER': 'DB_USER',
+        'WIZARD_DBPASSWORD': 'DB_PASSWORD',
+    })
+
+Short and sweet.  From there, setting up :attr:`~wizard.app.Application.extractors` and
+:attr:`~wizard.app.Application.substitutions` is easy:
+
+.. code-block:: python
+
+    class Application(app.Application):
+        # ...
+        extractors = app.make_extractors(seed)
+        extractors.update(php.extractors)
+        substitutions = app.make_substitutions(seed)
+        substitutions.update(php.substitutions)
+
+Note how we combine our own dictionaries with the dictionaries of :mod:`wizard.app.php`, much like
+we did for :attr:`~wizard.app.Application.parametrized_files`.
+
+With all of these pieces in place, run the following command::
+
+    wizard prepare-config
+
+If everything is working, when you open up the configuration files, any user-specific
+variables should have been replaced by ``WIZARD_FOOBAR`` variables.  If not, check
+your regular expressions, and then try running the command again.
+
+When you are satisfied with your changes, add your files, amend your previous
+commit with these changes and force them back into the public repository::
+
+    git status
+    git add wp-config.php
+    git commit --amend -a
+    git push --force
+
+Ending ceremonies
+-----------------
+
+Congratulations!  You have just implemented the installation code for a new install.
+If you have other copies of the application checked out, you can pull the forced
+change by doing::
+
+    git reset --hard HEAD~
+    git pull
 
+One last thing to do: after you are sure that your commit is correct, tag the new
+commit as ``appname-x.y.z-scripts``, or in this specific case::
 
+    git tag wordpress-2.0.4-scripts
+    git push --tags
index a049716326ba58ec23e87f735c05cdfda2c6d5c3..5dbc5190869d3b8bd519579e89bb7accc595d67e 100644 (file)
@@ -20,6 +20,16 @@ def re_var(var):
     """
     return re.compile('^(\$' + app.expand_re(var) + r'''\s*=\s*)(.*)(;)''', re.M)
 
+def re_define(var):
+    """
+    Generates a regexp for the definition of a constant in PHP; the
+    quoted value is the second subpattern.
+
+    >>> re_define('FOO').search("define('FOO', 'bar');").group(2)
+    "'bar'"
+    """
+    return re.compile('^(define\([\'"]' + app.expand_re(var) + r'''['"]\s*,\s*)(.*)(\);)''', re.M)
+
 def _make_filename_regex(var):
     return 'php.ini', re.compile('^(' + app.expand_re(var) + r'\s*=\s*)(.*)()$', re.M)
 
index 9bc112fd60798d90a2bbf959f62933c5014fcc19..a7f8e7d38cd5b39bb342b68844d8ebbff04bb341 100644 (file)
@@ -5,9 +5,8 @@ import logging
 from wizard import app, install, resolve, sql, util
 from wizard.app import php
 
-# XXX: We probably want to separate out the re.compile() line
 def make_filename_regex_define(var):
-    return 'wp-config.php', re.compile('^(define\(\'' + app.expand_re(var) + r''''\s*,\s*)(.*)(\);)''', re.M)
+    return 'wp-config.php', php.re_define(var)
 
 seed = util.dictmap(make_filename_regex_define, {
     'WIZARD_DBSERVER': 'DB_HOST',