Recently, I’ve been working with CircleCI for doing some automation and testing work, and I’ve been trying to run things locally on my machine, rather than pushing everything up to CircleCI to have it run on their servers.

But I kept running into problems with things like SSH keys, known hosts, and environment variables. These are all things that have easy solutions when you’re running them on the CircleCI servers (e.g., the add-ssh-keys special step.)

However, not so easy when you’re running the jobs locally with the command line interface.

But after quite a bit of googling for an answer, I found that it was much easier than I thought to make it work. Turns out, you can use docker-style volume syntax with the circleci CLI tools!

So, if you are running a local circleCI job called check-repo, for instance, you can mount your local ~/.ssh directory directly into the container, and viola!

circleci local execute --job check-repo --volume /home/{YourUsername}/.ssh:/root/.ssh

Likewise, you can include runtime values for environment variables you may need with the -e flag:

circleci local execute --job check-repo --volume /home/{YourUsername}/.ssh:/root/.ssh -e GITHUB_TOKEN=Y0UrG17hU870k3nG03zH3r3

Remember, when you’re mounting local folders into the container, you’re going to want to use absolute paths, not relative ones.

Was this helpful to you? Drop me a line and let me know.

Ok, so this particular problem took me a while to solve, but it turns out to be a useful technique, at least in my case, so I’m reproducing it here in the hopes that if you’re searching around on the internet looking for an answer, it’ll save you a little bit of time.

First, let’s describe the problem.

Let’s say you have a basic Laravel class something like:

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;

class Aspect extends Model{
    public function display(){ ... }
}

And you have a bunch of other classes that extend your base class, including, possibly, classes that do not yet exist.

class SpecialAspect extends Aspect{
    public function display() { .... but with something different! }
}

class StupidAspect extends Aspect {
    public function display() {  ... and something else is different! }
}

Now, all of these classes will share the same underlying table, which includes a field which specifies what type of Aspect each record represents.

And what you want to do is to continue using Eloquent ORM to work with collections of aspects, such that belongsToMany() and the like will give you back a Collection object containing a bunch of Aspects, all cast into the correct sub-classes (e.g., [Aspect, Aspect, SpecialAspect, Aspect, StupidAspect]).

So you try it out, and you find everything is getting returned as the base class [Aspect, Aspect, Aspect, Aspect, Aspect].

Laravel thinks that you only want instances of the base class, but you don’t; you want the object with overridden methods to load correctly so you can work with them normally.

This is the classic use-case for the Factory pattern.

So how do you do it?

What you do is create a Custom Collection object to override the normal Collection method that your object uses.  In the Custom Collection, you iterate through the objects available, figure out what type the are supposed to be, and then create new objects of those types.  Then you essentially load the data into them manually, build them into an array, and replace the $items in the Custom Collection with your new array of objects.

So first, modify your base class to implement a custom collection method.  While you’re at it, make a manual_load() method as well; remember, the newCollection method is going to override the normal Collection method all the time, so if you don’t load your objects up manually, you’re going to get yourself into a situation with an infinite loop, until you run out of memory:

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;

class Aspect extends Model{

    public function display(){ ... }
    
    public function newCollection(array $models = []){
        return new AspectCollection($models);
    }
    
    public function manual_load(){
        // use the DB::select method to pull your data out of the underlying table
        // and add it to the respective properties on $this
    }

}

So far, so good.

Now, you’re going to want to build your custom Collection object:

class AspectCollection extends \Illuminate\Database\Eloquent\Collection {
    public function __construct($items){
        parent::__construct($items);
        $this->recastAll();
    }      
    
    private function recastAll(){
        $new_collection_array = array();
        foreach ($this->items as $k => $m){
            $new_object = AspectFactory::make($m->id);
            $new_collection_array[$k] = $new_object;
        }
        $this->items = $new_collection_array;
    }
}

You’ll notice from that class, there is yet a third class that we’re going to need, an AspectFactory class that decides what kind of object you’re going to create for each individual element, so we’ll create that too:

class AspectFactory{
    public static function make($aspect_id){

        $new_classname = 'App\DefaultAspect'; // <--- if we don't have a custom type, we'll use this as our default.

        $new_type_name = DB::select('SELECT aspect_name FROM { ... whatever query will give you the name you need} ); 
        $mutated_aspect_type = $new_type_name[0]->aspect_name;
        $custom_classname = 'App\\' . $mutated_aspect_type . 'Aspect'; // This string is the name of the class we're going to test for.

        if ( class_exists( $custom_classname ) ){
            // The custom class exists, so override our default.
            $new_classname = $custom_classname;
        }

        $finder = new $new_classname();  // Here, we create the new class.
        $finder->id = $aspect_id;        // Assign the ID to the new object
        $finder->manual_load();          // Call that manual_load() method we wrote for our base class.
        return $finder;                  // Send our custom class back to our Custom Collection.    
    }
}

So now, if you have a relationship that looks like:

App\Subject->belongsToMany(‘App\Aspect’);

Then you can do Eloquent operations such as:

$s = new Subject::find(1);
foreach ($s->aspects as $a ){
     $a->display();
}

And the correctly overridden display() method will spit out whatever it is you’ve got it doing, because your Collection will look like:

[
   0 => Aspect, 
   1 => Aspect, 
   2  => SpecialAspect, 
   3  => Aspect, 
   4  => StupidAspect
]

Or whatever.

And there you have it.  Implementing the Factory pattern with Laravel (5.4).

 

UPDATE (1/3/2018) : Giulio Troccoli-Allard very helpfully got in touch (thanks!) with me to point out the recastAll() function in the collection class wasn’t preserving the keys of the items.  He included some code to provide the enhancement, and so I updated the relevant portion above.

 

 

Do this: Right now, take out your smartphone (presuming you use one that runs iOS or Android.)  Go to your app store of choice (or just follow this link) and install an app called Signal.  It’s free.  It costs you nothing.  But one day, it may help you in ways you cannot yet foresee.

Signal is a privacy and security app that replaces your built-in SMS/text message software.  It seamlessly handles your text messages for you, just like you’re used to now.  But as an added bonus, it automatically encrypts texts that you send to other Signal users.  The software uses end-to-end encryption to ensure nobody can eavesdrop on your texts.  That includes the people who make the software, the NSA, the FBI, the phone company, your tricky hacker kids, the people sniffing your wi-fi at the Starbucks, and everyone else in the world.  It means you can rest assured your private communications STAY PRIVATE.

In addition to encrypted texts, you can also use Signal to make encrypted phone calls, video calls, and picture messages.  It’s open-source, so it’s been peer-reviewed by the cybersecurity community.  It’s dead simple; easy enough that anyone can use it effectively.  And did I mention that it’s free?

Look, it’s 2017.  Donald Trump is going to be inaugurated as President of the United States on Friday, at which point, the controls of the most sophisticated surveillance apparatus in the entirety of human history will be at the disposal of a thin-skinned, sociopathic demagogue.  18 months from now, you don’t want to find yourself in a situation where you you’re asking, “Why didn’t I think of encrypting my communications sooner?”  And even if you’re a straight shooter who never does a single thing wrong, and never wants to privately express controversial opinions, you should still use Signal to secure your communications.  What if you are, or know, a journalist, an activist, or a protester who fears being targeted for retribution or censorship?  What if you need to pass sensitive financial information to your accountant, or your lawyer, or your family?  Are you going to PGP-encrypt your emails?  If you’re like most people the answer is no; PGP-encrypted emails still frustrate even sophisticated techies.  Don’t make it hard on yourself, when Signal is so easy to use.

Edward Snowden recommends using Signal, and he’s the kind of guy who has to worry about assassination attempts by state-level adversaries.  World-renowned security researcher Bruce Schneier recommends it.  The Electronic Frontier Foundation recommends it.  I recommend it.  It costs you nothing, and it could one day protect you from fraud, scams, and theft.  It may one day save your life or the life of someone you care about.  Go install it now.  Seriously.

A novice asked the Master: “Here is a programmer that never designs, documents or tests his programs. Yet all who know him consider him one of the best programmers in the world. Why is this?”

The Master replied: “That programmer has mastered the Tao. He has gone beyond the need for design; he does not become angry when the system crashes, but accepts the universe without concern. He has gone beyond the need for documentation; he no longer cares if anyone else sees his code. He has gone beyond the need for testing; each of his programs are perfect within themselves, serene and elegant, their purpose self-evident. Truly, he has entered the mystery of Tao.”

Click here for the full article

Posted from Facebook

This is why I prefer to keep my passwords in an offline password manager, namely KeePassX.

I think this discussion came up once before, and Scott Schmitt asked me why I thought KeePass was better than LastPass — I didn’t have an example to point to at the time, but this is why. The fewer people that can even see my database file, let alone decrypt it, the better I feel about it.

Adoption of poorly secured password managers opens a single point of failure.

Click here for the full article

Posted from Facebook

Ok, listen, I’m not going to get into the details or whatever, but it was recently brought to my attention that I really, really should be backing up my MySQL databases on a daily basis at least.  So here’s the recipe.  Modify and use it for your own purposes, and don’t be as dumb as I am.

Create a directory to hold your backups.
Create the following shell script in your backup directory.  Substitute your own info for the stuff in brackets.

backup_script.sh:

#!/bin/sh
logfile=/[PATH-TO-BACKUPS]/backup_script.log
echo "------------" >> $logfile
echo "Starting MySQL Database backup script" >> $logfile
location=/[PATH-TO-BACKUPS]/backup_"$(date +'%d_%m_%Y_%H_%M_%S')".sql
mysqldump -u root --password='[YOUR-PASSWORD]' --opt [YOUR-DATABASE] > $location
echo "Completed MySQLDump." >> $logfile
gzip $location
echo "GZipped the backup file "$location >> $logfile
echo "Removing backups older than 10 days." >> $logfile
find /[PATH-TO-BACKUPS]/ -maxdepth 1 -type d -mtime +10 -exec rm -rf {} \;
echo "Old backups removed." >> $logfile
echo "Backup script completed on "$(date +'%d_%m_%Y_%H_%M_%S') >> $logfile
echo "------------" >> $logfile
exit 0

Set the permissions to 700, to make sure nobody can see your plaintext MySQL password.

Edit your cron tab to run the shell script once a day (or however often you think is prudent.)

To unzip the backed up SQL file:

gunzip -v [YOUR-BACKUP-FILE].gz

To restore your backed up SQL dump:

mysql [YOUR-DATABASE] < [YOUR-BACKUP-FILE].sql

Take it from me, kids. Only fools don’t back up their work.

 

Oh, Klout.  I want to love you, but you just won’t let me.

Let me begin this post by saying that Klout, the web site that claims to measure social media influence, isn’t a terrible idea.  There’s a really good reason to want a decent methodology for determining influence online.  After all, if you’re going to be spending time and effort to reach out to your audiences through social media, it makes sense to try to target the audience members who are most influential, and most likely to use their influence to talk up your product or service.

The idea is solid.  But Klout’s implementation is terrible, for one simple reason.  Their algorithm is ridiculously bad.

I’m not the first person to point this out.  But until today, I was willing to give them the benefit of the doubt; maybe it works, mostly, with little problems here and there.  But in fact, their ratings just don’t bear any resemblance to reality.

To demonstrate, have a look at the screen caps after the jump.  These were all taken today.

Continue reading

With the explosion of mobile internet access that has been building for the past few years, I’ve gotten a lot of questions from people lately asking about what sort of strategy they should take in approaching mobile for their news or information site.  Should I develop a mobile version of my web site?  Should I build an iPhone app?  What about Android, should I build an app for that, too?  How much does it cost?  How can I get the best return for my mobile development dollars?

Well, this is a question we’ve been working on at the ABA Journal, and we think we have found a good way to

The approach I’ve been advocating recently is to turn the bulk of your attention to building out the mobile web site, and then using small “wrapper” apps to maintain a presence in app stores.

There are several benefits to this strategy.
  • It’s easy to develop for the web.  After all, you’re already doing it.  You probably have scripts and code to do 90% of what you want your mobile app to do, so why re-invent the wheel?
  • Web development is much cheaper than app development.  You know how your web developer wants $100 an hour?  App developers want more than that, and it takes much, much more work to build out a native app.
  • There’s pre-existing libraries to make your website “app-like”.  I’ve had good success with JQuery Mobile, but there’s also Sencha, JQTouch, iUI, and plenty of others.  Using these frameworks, you can make your webpages touch-friendly in no time.  Plus, they give you access (via javascript) to the device’s internal sensors, so you can use that info in your web app.
  • It’s fast to deploy new features.  If you build out an iOS app, then sign it, get it submitted to the app store, get it approved, and then installed on the devices of your user, you’re not going to want to go through all that time and hassle again in three months when you want to roll out your shiny new feature.  If your apps are just small wrappers pointing to a touch-ified website, when you want to change something, you just change it once, on the web, and the changes propagate through all your apps.
  • All your platforms stay in feature-parity.  Since you’re just changing the web app, every platform gets updated at the same time.
  • It’s simple to write the wrapper apps.  With Phonegap, you can turn your web app into a mobile app in no time.  In fact, using Phonegap Build (their online, web-based compiler), I churned out apps for iOS, Android, Blackberry, Symbian and WebOS in a matter of hours.  No nativedevelopment environment required.
  • No worries about writing custom client-server protocols.  It’s the web, so you use standard web stuff like JSON or XML for client-server stuff.
  • You don’t have to use the advertising software the platform advocates.  That means Apple doesn’t get a cut of your ad revenue, since you don’t have to use iAds.
Downsides?  Yeah, there are some.
  • Web apps are slower than native apps.  For most information-driven applications, this doesn’t matter, but if you need to do heavy math or things like 3D animations and the like, then native is your only choice.
  • Not all features are supported on all platforms.  Blackberries, for instance, don’t have a compass sensor, so you can’t rely on having that input available.
  • Web apps rely on the device’s default HTML handling capabilities.  That can lead to layout differences, etc. so it may not look identical on all devices.  This generally isn’t a problem, if you’re making sure to design your pages to gracefully degrade.
What it comes down to, for me at least, is that native apps are HARD.  For each platform, you have to essentially learn a new language and a new set of tools, or hire someone to do it for you.  Mobile developers are in high demand, so farming it out is expensive. So if web developers can build it out instead, why not go that route?
Anyhow, I’d love to hear if anyone else on the list has any insights on this approach.

Today is the day that much of the internet is going dark to protest the SOPA/PIPA acts in the United States.

I wrote a little piece on it for Acceler8or, and I’ve blacked out my logo for the day.

Please, take a moment to register your displeasure with legislators.  Don’t break the internet.

I like tablet form factors, I really do.  I’d love to get one, but they don’t quite make my kind yet.

I need, need, need for there to be a stylus.  I’m a doodler.  Handwriting recognition is also a must.

I need it to be Android 3.1 or higher

An 8″ screen is about optimal, though I’d go down to a 7.  10″ might be too big for my purposes.

It’s got to have GPS sensors, 3G/4G data (unlimited preferred), wifi, NFS, accelerometers, gyro, etc.  I’m of the MOAR SENSORS! school of thought.

Lenovo has almost gotten there, according to this Ars Technica review, but not quite yet.

Soon though.  Soon.