Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: coding

  • Git Flow

    Git Flow

    Late as always to these git things.

    In the ever increasing madness to the method of making code easier to do, we come to the automation of git-flow. This is a library of git subcommands that helps automate some parts of the flow to make working with it a lot easier if you’re using Vincent Driessen’s model.

    This model is not bad, if a little confusing at first:

    The git-flow model

    Jeff Kreeftmeijer already has a good primer for it so these are just my quick notes to add in things that should have been obvious. The basic concept for the model is that you have two main branches, master (the ‘current’ version) and develop (where you’re working on the next version).

    Install git-flow

    You have to install it to use it. I use Homebrew so it was brew install git-flow and that was that.

    Add it to your repo

    Again, you have to add it to have it. git flow init is run inside the repo and you’re good, except you may not be.

    Since I’m starting from an existing repository, which was up to date in master, I made a new branch: git checkout -b develop

    Then I ran git flow init which is not the same as it would be on a new repo:

    $ git flow init
    Which branch should be used for bringing forth production releases?
       - REL_3.3
       - REL_3.3.1
       - REL_3.3.2
       - master
    Branch name for production releases: [master] master
    
    Which branch should be used for integration of the "next release"?
       - REL_3.3
       - REL_3.3.1
       - REL_3.3.2
    Branch name for "next release" development: [master] develop
    
    How to name your supporting branch prefixes?
    Feature branches? [feature/]
    Release branches? [release/]
    Hotfix branches? [hotfix/]
    Support branches? [support/]
    Version tag prefix? [] REL_
    

    Should you happen to do as everyone says and ‘accept the defaults’ you get this:

    Branch name for "next release" development: [master]
    Production and integration branches should differ.
    

    Also if you don’t have a develop branch, it punts you out.

    Branch name for "next release" development: [master] develop
    Local branch 'develop' does not exist.
    

    So a couple ooops along the way. It’s not

    Using A Feature

    First you make a feature:

    $ git flow feature start utility_1.0.3
    Switched to a new branch 'feature/utility_1.0.3'
    
    Summary of actions:
    - A new branch 'feature/utility_1.0.3' was created, based on 'develop'
    - You are now on branch 'feature/utility_1.0.3'
    
    Now, start committing on your feature. When done, use:
    
         git flow feature finish utility_1.0.3
    

    Eventually you’ll be done and use that finish command, which merges it all back into ‘develop’ and changes you back to that branch. Which is good for reasons we get to in a moment. Since I work on multiple computers, I do this at the end of my workday:

    $ git push --all
    Total 0 (delta 0), reused 0 (delta 0)
    To ipstenu@example.com:/home/ipstenu/repositories/theme-wordpress.git
     * [new branch]      develop -> develop
     * [new branch]      feature/utility_1.0.3 -> feature/utility_1.0.3
    

    So now when I do my pull later on the other computer, it’ll be easily usable. Provided I remember to install git-flow and init it on my other laptop. But it’s a little more complicated than just that.

    Releasing a Release

    You can only run this from the develop branch, which makes the previous command pretty awesome, right? So now we’ll do this: git flow release start RELEASE

    Once we’re good to go, it’s git flow release finish RELEASE

    What About Two People?

    This is where we want to use publishing. Technically I’m collaborating with myself across two computers, so I always publish my feature to my remote server so it can be used by my other self: git flow feature publish MYFEATURE

    To pull the feature down, git flow feature pull origin MYFEATURE is just as logical. And that’s actually how I handled pulling the feature utility_1.0.3 onto my work laptop.

    $ git checkout master
    Switched to branch 'master'
    Your branch is up-to-date with 'origin/master'.
    $ git branch develop
    $ git flow init
    [snip .. same as before]
    $ git flow feature pull origin utility_1.0.3
    Created local branch feature/utility_1.0.3 based on origin's feature/utility_1.0.3.
    

    There’s a good cheat sheet for help about this called Git Flow Cheatsheet.

    Now there’s nothing but to do it.

  • Defines, Variables, and Plugin Dirs

    Defines, Variables, and Plugin Dirs

    If you’ve spent any time looking at PHP code, then you’ve seen defines and variables

    Defines

    A define looks like this:

    define('SOMETHING', true);
    

    This makes a global constant that can be used anywhere. In the case of WordPress, it means they can be used across multiple plugins or themes. This is very useful if you make a suite of plugins that all have the possibility of using the same API key. Then you can tell a user to put define('MY_PLUGIN_API', '123456'); in their wp-config.php file, and tell your code to check for the define.

    A define also cannot be redefined. If you call it twice, you get errors, so you should be as unique as possible when creating yours.

    Variables

    A variable, meanwhile, looks like this:

    $SOMETHING = true;
    

    Variables only exist where they are, so if I have one in one function, I may not be able to call it in another. You can make global variables if needed, and in fact if you don’t, the variable won’t be available to all functions.

    Which Should I Use?

    Keeping in mind that defines are constants and variables are, well, variables, the idea is that a constant should be used for things that should not change in the running of the code. It also makes your code easier to maintain if the things that must be constant are explicitly so.

    So what’s a good define? Actually not really this:

    define('MY_PLUGIN_VERSION', '1.0');
    

    This is a constant, it’s something you should be setting and it shouldn’t be overwritten, but actually I’d want to make it a database field to check on before upgrading. Remember, you should be changing that define on upgrade, so having it be a declared constant is a little odd. Now that said, it is a good one when you consider you don’t want someone to willy-nilly override it. Except … what if you do? What if you want someone to be able to change it back to re-run an upgrade?

    So then really not this either:

    define( 'MY_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
    define( 'MY_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
    include( MY_PLUGIN_PATH . 'lib/asset.php') ;
    

    Someone’s probably thinking that their plugin directory is a constant and, thus, should be defined like that. Maybe, but it’s a pointless define in WordPress. You already have plugins_url() (which this example isn’t using) but it’s really where people use that code that makes no sense. That’s why I included the second line there. That’s what they use it for, and it means two lines of code for one function call.

    This actually magically becomes a good define when you have a complex plugin with multiple files and you need to grab the main plugin directory in sub-files. But if your plugin is one file (and yes, that’s where I see it the most), it’s overkill.

    This is a good define:

    define('MY_PLUGIN_APIKEY', '123456');
    

    But that should never be in your code itself. Not for WordPress at least. That should be in the wp-config.php, like I mentioned before.

    Basically … there aren’t great reasons to use defines unless you want things that never change. define('MY_PLUGIN_SUPPORT_HOME','http://help.example.com'); would make sense to me, as would other contact info you want to make sure is never subverted.

    What do you think define is best for?

    I’m interested to hear what you guys like to use defines for. I’m certainly guilty of using them for some pretty silly reason.

  • Slow Site Troubleshooting: Database Edition

    Slow Site Troubleshooting: Database Edition

    So your WordPress is slow and you’ve already done the needful. You’ve checked your plugins and themes, you’ve put caching in place, you’ve checked for hacks, but it’s still slow, especially on the back end of WordPress?

    It may be your database.

    More specifically it may be your wp_options table. When your options table gets very, very large, it gets very, very slow. WordPress regularly queries that when you’re logged in, and it’s not indexed. DB indexes are used to locate data fast, without searching every row in the tables. This sounds sensible in many ways, but we don’t

    Indexes are used to quickly locate data without having to search every row in a database table every time a database table is accessed. Indexes can be created using one or more columns of a database table, providing the basis for both rapid random lookups and efficient access of ordered records. We don’t use ’em in the options table for a variety of reasons, but mostly that it slows things down.

    So in lieu of making indexes on your own, what can and should you do to debug things?

    Optimize Your Database

    Got WP-CLI?

    wp db optimize
    

    Otherwise you can use phpMyAdmin to check tables with overhead and clean ’em up. I don’t use a plugin, I think asking WP to optimize itself is a little weird, but you certainly can. The point here is to keep it clean.

    Cache that Database!

    Caching makes things better. Right? Kind of right. Mostly right. I use memcacheD (which I often typo as memecached) and that plus an object-cache.php file can cache your DB calls so they’re faster, which is great. Unless your wp_optimize table is too big.

    Your cache has two major issues. First, there’s going to be data you don’t want to cache (like private, sensitive information), but also when your cache is too big, or it’s trying to save data bigger than it is, it can make things slower by trying to cache, crashing, and repeating that over and over. That gets worse when we talk about the temp data generated by _transient entries in your database.

    Check The Size

    Your options table really shouldn’t be large. My biggest, busiest, site is only using 142K. It’s a site that’s old (8+ years now), it’s had many iterations and themes and plugins. You’d think it would be filthy with leftover code, because we all know plugins don’t always clean up. Nope. I did rebuild the DB once, in 2009, when I rebuilt the entire site from scratch, but that was 5 years ago and a lot has changed since then with plugins and themes. The next biggest site, a Multisite Network, has a wp_options of 100k. The biggest I’ve had is one of 500kb and that’s on a test site where I install and delete plugins daily.

    You get the point I trust. These things should be small. At most, I’m going to have a lot of _transient entries. But that’s actually issue here.

    Clean The Transients

    There’s a story here about why WordPress doesn’t really clean your transients. Why? Well as the name implies, transient data is meant to be transient. It should be temporary data, saved and used briefly, and then it should go away. A lot of developers, as it happens, were storing it for long term caches. Like checking when the last upgrade ran, or when a cron kicked off. So while for one, glorious, month we did nuke them all on upgrade, now we only delete expired transients, which doesn’t help as much as it could. As Nacin said:

    This leaves much to be desired, but we don’t want a core update to be blamed for breaking a site that incorrectly assumes transients aren’t transient.

    Basically people doing things wrong in a way we couldn’t adjust for.

    There are plugins like Delete Expired Transients and Transient Cleaner (which has the cutest header image). Those can be used to clean out your old transients.

    If you want to go whole hog, there’s a command to clean the whole thing out with SQL:

    DELETE FROM `wp_options` WHERE `option_name` LIKE ('%\_transient\_%')
    

    Of course you want to run a db optimize afterwards to actually flush out the rows.

    As always WP-CLI has features like wp transient delete-expired and wp transient delete-all.

    What if that doesn’t help?

    Then you should check the Database to see exactly what the biggest value is. In this case, I ran wp db cli to leap into the database and then this:

    mysql> SELECT option_name , length (option_value) AS blah FROM wp_options ORDER BY blah DESC LIMIT 5;
    +--------------------------------------------------+----------+
    | option_name                                      | blah     |
    +--------------------------------------------------+----------+
    | cron                                             | 12194468 |
    | _transient_feed_d117b5738fbd35bd8c0391cda1f2b5d9 |   223838 |
    | _transient_feed_ac0b00fe65abe10e0c5b588f3ed8c7ca |    98184 |
    | _transient_is_cached_instagram_images_self       |    97315 |
    | mytheme_storage                                  |    18354 |
    +--------------------------------------------------+----------+
    10 rows in set (0.02 sec)
    

    CRON is 12 megs. That would be the problem. Of course the only way I know of to fix that would be to totally trash cron and let it start over.

    Is That It?

    When you see a ginormous wp_options table, what do you do?

  • The Ebb and Flow of Automation

    The Ebb and Flow of Automation

    Repetitive tasks suck. Let’s be honest here, we hate doing them most of the time. But also we’ll forget things and mess up our day. With code that’s pretty terrible.

    Over time, I’ve managed to automate a lot of things. WordPress upgrades itself, including plugins and themes. My code changes are auto-deployed via Git when I update them. I use a cool Coda plugin to automatically generate css from multiple files.

    I’ve now added Grunt to the mix. Grunt runs tasks for you so you can be lazy (efficient) but it’s not perfect. One of the things I love about my other tools is I don’t have to think about them. WordPress takes care of itself, git has hooks to know what it’s doing, and Coda monitors my files. I don’t have that for Grunt.

    What you have, instead, is ‘grunt watch’ which is great but it only runs while you’ve told it to watch. You have to remember to activate it every time. And I understand why. Watching is a rather expensive (computer wise) tool. But it annoys me because I already struggle to remember that the way a tool I use works, I have to run this to checkout the code: git checkout [tag_name] -b [my_branch_name] (which for some reason my brain thinks is ‘better’ than scripting a zip).

    So why would I use Grunt?

    On a site I run, I have a folder filled with scripts that are used on four separate CMS tools. One is WordPress. I’m often adding new scripts and I like to have the scripts separate because that’s easier for me. But that also means I have to edit all my CMS to add in the new JS. But with Grunt I don’t.

    Instead, I have one simple Grunt file that says “Any js file in /content/code/js/dev/ should be combined into one mondo js file and then uglified to compress it down.”

    Installing Grunt

    I didn’t have Node installed, but I do use homebrew, so this was it for me:

    brew install node
    npm install -g grunt-cli
    

    Okay. Now what?

    My First Project

    I knew I wanted to make a folder in my /content/ folder for this, so I made /content/project/. In that folder I ran the command npm init and answered the questions to generate my package.json file. That was the easy part actually. After that had to decide what I wanted to do.

    1. Concatenate (combine) all my JS files into one.
    2. Compress those files to make them minified.
    3. Watch the files while I was working on them and automate that.

    In order to do that, I need to install three grunt ‘plugins’: concat, uglify, and watch:

    npm install grunt-contrib-concat --save-dev
    npm install grunt-contrib-uglify --save-dev
    npm install grunt-contrib-watch --save-dev
    

    Doing it that way, with the save dev call, automatically adds it to my package.json file so it knows to call that.

    Next I had to make a filed called Grunfile.js and put my actual code in it. I’ve got a copy of the file below but you can break it up into some pretty basic sections. Here’s a sample file:

    module.exports = function(grunt) {  
    
        grunt.loadNpmTasks('grunt-contrib-uglify');
    
        grunt.initConfig({  
            pkg: grunt.file.readJSON('package.json')
    
            uglify: { ... }
    
        });
    
        grunt.registerTask('default', [] );  
      
    };
    

    The first call is to load the npm (node) tasks, which means I’m telling it ‘include these plugins’.

    The second call is my init command which runs when the ‘grunt’ command is used. In there I’ll put the name of my json file, where I’ve defined all my dependancies (not all get loaded by the Grunt file you see) and then I’ll make a ‘case’ for my code. That’s what the uglify: { ... } bit is.

    The last is registering the default tasks. At this point, if I want to do anything I would have to type grunt uglify to do anything, so what you can do instead is make it this:

    grunt.registerTask('default', ['uglify'] );
    

    Now when I run ‘grunt’ it will automagically uglify. If you have multiple steps, put them in order of what you want to happen, and off you go.

    At this point, I’m now a GruntJS rookie, but I can see why it’s amazing. One can use this in plugin development to make it easier to mush up all your code into something smaller to load.

    My Scripts

    For those wondering, here are my scripts:

    package.json

    {
      "name": "jfo-content",
      "version": "1.0.0",
      "description": "JFO Content Scripts",
      "main": "Gruntfile.js",
      "dependencies": {
        "grunt": "^0.4.5",
        "grunt-contrib-uglify": "^0.7.0"
      },
      "devDependencies": {
        "grunt-contrib-concat": "^0.5.0",
        "grunt-contrib-uglify": "^0.7.0",
        "grunt-contrib-watch": "^0.6.1"
      },
      "author": "Mika Epstein <ipstenu@halfelf.org>",
      "license": "WTF"
    }
    
    

    Gruntfile.js

    module.exports = function(grunt) { 
    	
    	grunt.loadNpmTasks('grunt-contrib-uglify'); 
    	grunt.loadNpmTasks('grunt-contrib-concat');  
    	grunt.loadNpmTasks('grunt-contrib-watch');
    	
    	grunt.initConfig({
            pkg: grunt.file.readJSON('package.json'),
    
    		concat: {  
    		    dist: {  
    		        src: '../code/js/dev/*.js',
    		        dest: '../code/js/content.js',  
    		    },  
    		}, 
    
    		uglify: {
    		    build: {  
    		        src: '../code/js/content.js',
    		        dest: '../code/js/content.min.js',
                        }
    		},
    
    		watch: {  
    		    scripts: {  
    		        files: '../code/js/dev/*.js',
    		        tasks: ['concat', 'uglify'],  
    		    }
    		}
    
    	});
      
        grunt.registerTask('default', ['concat','uglify'] );  
      
    };
    

    post_update (git)

    I added in a line here to delete the package folder from my live site. That’s where all my Grunt stuff lives and I really don’t need it. It also nukes the dev folder. Sometimes. In some cases I leave that alone, since it’s not like I’m worried about space.

    #!/bin/sh
    export GIT_WORK_TREE=~/public_html/content/
    git checkout -f master
    rm -rf ~/public_html/content/package/
    rm -rf ~/public_html/content/code/js/dev/
    
  • Mailbag: What Code Makes You Sigh?

    Mailbag: What Code Makes You Sigh?

    When I was talking about ThemeForest, I mentioned we had code on WordPress.org that made me sigh. Or cry depending on the day.

    Here it is:

    if (!defined('WP_CONTENT_URL')) define('WP_CONTENT_URL', get_option('siteurl').'/wp-content');
    if (!defined('WP_CONTENT_DIR')) define('WP_CONTENT_DIR', ABSPATH.'wp-content');
    if (!defined('WP_PLUGIN_URL')) define('WP_PLUGIN_URL', WP_CONTENT_URL.'/plugins');
    if (!defined('WP_PLUGIN_DIR')) define('WP_PLUGIN_DIR', WP_CONTENT_DIR.'/plugins');
    

    Why do I sigh?

    It’s not needed.

    You can use functions to determine those directories and while I’m sure someone’s thinking “But WP_PLUGIN_DIR is shorter than plugins_url()!” it’s not.

    That code block above was used so that one line of code could exist.

    include(WP_PLUGIN_DIR.'/PLUGINNAME/settings.php');

    Those four lines, plus the include, could be replaced with this:

    include( plugins_url( 'settings.php' , __FILE__ ) );

    So yes, I sigh. Because with just a little work, you could see that there’s a more efficient way to make your plugin smaller.

  • Packaging Code

    Packaging Code

    I love that people do it. I hate that they don’t review it.

    The number of projects I review, only to find that the author ran a tool like Grunt to combine files, but forgot to go over what the result was is fairly high. And this is a problem when you consider how many times I have to tell people “Your submission still has demo files, test scripts, and other files that aren’t applicable for distribution.” What happens is that people use the very cool auto-scripts and never stop to make sure that everything’s right. They make sure the code works but they don’t remember to clean up the package.

    So let’s talk about what should never be in your plugins for WordPress.org

    Deployment Scripts

    Now I know a lot of people use scripts to copy their code from GitHub to WordPress’s SVN repo, and I think those scripts are great. They’re helpful, they speed up development, and please keep them out of your plugins. Your script should include a note not to distribute itself. I understand why, when you link us to the GitHub default zip, those scripts are in the review package, and that’s okay. But I do sometimes run a sweep through the repository to see how many people are accidentally including those SH files in their plugin packages. You’ve got to remove those. They don’t matter to the final product and without them, your plugin will be smaller.

    Demo Folders

    Here’s the thing. They don’t matter. A lot of awesome 3rd party tools come with detailed demo files and extensive things you’ll never need. Those demo folders also tend to be where you’ll find all sorts of crazy things like Google Analytics tracking, calls to external resources (like jquery’s JS files), and more. Your users will rarely, if ever, need that sort of thing. They generally don’t notice it, unless you code it into your plugin, at which point you’d be better served by making it look like WordPress.

    Test Scripts

    Your test scripts don’t need to be in your plugin. They’re cool, to make sure that the code is going to work before you push it, but that code doesn’t need to be in the plugin on my site, does it? No it does not. All automated tests should be separate from your plugin code files. People don’t need to see the Travis checks in the code on their sites. If they’re developers, they’ll go look for them at your code’s home, after all.

    Compressed and Uncompressed Files

    Pick one. You don’t need both. When you’re talking about a framework or a library, it’s fine to pull in a minified (but not p,a,c,k,e,r compressed) version of the file as your own version. If there’s no need or plan to edit that file (and there shouldn’t be), you can make the plugin smaller. Of course, I feel that if the JS is all of 7 lines, for goodness sake, it’s fine to leave it all human readable.

    What Else?

    What do people leave in plugin or theme packages that drive you up the wall?