blog.bronosky.com

Tuesday, June 1, 2010

Playhouse in progress, part 3

I'm really excited to have finally found a reason to learn Google Sketchup. I've recreated a 3D version my plans, which I created in Adobe Illustrator (2D PDF in an earlier post). I took some still shots and exported an animation to video.

Yesterday I graded the land and set the foundation stones. Today I moved all of the pre-constructed floor, porch, and walls outside to the foundation and assembled it all. I still need to put plywood on the walls, and have not even begun to do the roof.

Playhouse Animation from Richard Bronosky on Vimeo.

Wednesday, May 26, 2010

Playhouse in progress, part 2

I bought the windows for the playhouse today. I finally uploaded some photos to Flickr. They are a bit underwhelming so far. I haven't been able to start on the 3 walls that contain windows because I didn't know where I could buy them. I can finally move on with my plans.

Monday, May 17, 2010

Playhouse in progress

I decided to make the girls a playhouse that would take up 8ft x 8ft in the back yard. Most of the plans I found online were for a 8ft x 4ft, only 4ft tall (excluding the pitched roof) with a 2ft porch. I really appreciate the insight I got from those plans but I think 4ft on the inside is just too small, my 3 yr old is 41 inches tall already, and 2ft for a porch doesn't even give you room for a chair. So, I decided to make it 5ft x 8ft and 5ft tall with a 3ft porch. I realize that at some point we won't want this thing in the backyard anymore and an 8x8 structure can't be moved without a CDL (trucker's license). For this reason I have decided to make the covered front porch detachable. I accomplish this with separate foundations for the house and porch and a 2 piece over-under roof system. Here are the plans.

So far I have framed both floors and the back wall. Today I bought and cut the composite decking for the porch and picked out the 4 windows. Now that I have settled on 18in x 27in windows, I can make the front and side walls.

Saturday, April 3, 2010

Hosting your own Blog is stupid!

I've hosted my own blog for 15 years. For me it has been about "freedom". The new "freedom" is being free to not have to deal with the hassle.

I started in 1994 with plain HTML. A year later I added JavaScript, ColdFusion, and MSSQL server when I started working professionally. In late 1998, I got into Macromedia Flash. At that point I broke from expressing myself verbally ("blogging") and was more interested in artistic expression. (This would be a short lived diversion.) In 1999 I started coding in PHP and learned about Free Software.

By the end of 2000 I had solid experience with RedHat 6 & 7 and considered my self an "expert". (In reality I know nothing but bash and GNU utils.) Near the end of 2000, my company hired Jerry Tubbs who brought with him a Beta of Mac OS X which I installed on my company issued G3 PowerBook "Lombard". (I clearly remember how the blue Apple logo in the center of the menu bar made it feel like an iMac.) I found myself compiling Apache, PHP, and MySQL from source tarballs and being amazed that it worked "on a freaking Mac"! I hated Apple up until that point. I hated that my company forced me to use OS 9. I hated that anybody used any web browser other than Internet Explorer 5! I quickly upgraded to Mac OS 10.0 and then 10.1. At this point I would never own another MSFT windows computer.

I would continue developing PHP for 10 years. I used custom PHP to template my own blog, then for content entry. I was very active in the Open Source community. I used a lot and contributed a lot of code snippets from/to places like http://www.phpclasses.org/ and numerous mailing lists and forums. I was very resistant to using Wordpress, but I eventually submitted to temptation in late 2004. Since then I have dealt with comment spam, plugins, a few exploit avoidance upgrades, backups, blah, blah, blah. I use http://flickr.com to host my photos. I use http://github.com to host my code. I use http://gmail.com for email with my own bronosky.com domain. I just can't justify hosting my own blog. I will continue to own bronosky.com and use it for email, FTP, and as a SOCKS proxy and SSH hop. I will continue to run a VPS at http://slicehost.com to keep up my sysadmin chops. However, I will not be hosting a blog there. For now I've chosen to use http://blogger.com and I am very pleased with my ability to use things like the http://cooliris.com Flash widget. I can now remove modPHP and optimise my Apache configuration for serving Django via WSGI and Worker MPM.

Monday, November 16, 2009

git One-liners

This started out as a tweet but quickly became a collection of one-liners. Some of this may be able to be accomplished with switches to regulart git commands, but I can write awk faster than I can read a man page. Sad but true.


# add files to the index which `git status` lists as untracked:
git add $(git status | awk 'p==1{print $2}; /git add /{p=1}')

# remove files from the index which `git status` lists as deleted:
git rm $(git status | awk '$2=="deleted:" && p==1{print $3}; /git add\/rm /{p=1}')

# add files to the index which `git status` lists as ``Changed but not updated``/modified:
git add $(git st | awk '$2=="modified:" && 'p==1{print $3}; /git add /{p=1}')

# checkout the penultimate commit (used for stepping backwards through commit to find the introduction of a bug)
git checkout $(git log | awk '/^commit /{if(i++>0){print $2; exit}}')

Thursday, April 30, 2009

Linux One-liners

I am moving entries of my old one-liners text file to a web page for easier access.

# mount cdrom
[ -d "/mnt/cdrom" ] || mkdir -p /mnt/cdrom; mount /dev/cdrom /mnt/cdrom/

# mount a samba/cifs share (hostess is used by vmware in NAT mode)
user=rbronosky; [ -d "/mnt/smb" ] || mkdir -p /mnt/smb; mount -t cifs //hostess/$user -o username=$user /mnt/smb

# remove the leading path from a find
find . | sed 's/^..//'

# basic bash for-looping
for f in $(cat changed_files.txt) ;do vimdiff trunk/$f branches/iteration3/$f; done;
# if you have spaces in filenames
find . -type f |sed 's/^..//'|while read f; do ls "$f"; done
# or
(IFS=$'\n';for f in $(find . -type f) ; do cat ../Logs2/$f $f>../LogsCat/$f; done;)

# version number comparison using the power of the Python standard lib
[ "1" == "$(python -c "from distutils.version import *;print int(LooseVersion('3')>=LooseVersion('2.5.1'))")" ] \
&& echo Yes || echo No
# above is True, below is False...
[ "1" == "$(python -c "from distutils.version import *;print int(LooseVersion('2.3')>=LooseVersion('2.5.1'))")" ] \
&& echo Yes || echo No

# basic anonymous cvs
cvs -z3 -d:pserver:anonymous@iterm.cvs.sourceforge.net:/cvsroot/iterm ls

# make wget use filenames as suggested by the HTTP header Content-Disposition (requires wget>=1.11)
# http://www.vim.org/scripts/download_script.php?src_id=6328 becomes ps_color.vim
echo -e '\ncontent-disposition=on'>>~/.wgetrc

# copy files using ONLY ssh, not scp or sftp
tar cvf - $files_and_dirs_to_send | gzip | ssh $destination_server "cd $destination_dir; tar zxvf -"
# or to leave them compressed on the remote side...
tar cvf - $files_and_dirs_to_send | gzip | ssh $destination_server "cat > $destination_dir\archive.tar.gz"

### Help dad out via ssh (and telephone) ###
## I configure my router to forward $secret_port to port 22 on my machine.
## Because Ubuntu does not default to having and ssh server, I tell dad to do:
sudo apt-get install openssh-server
## I to tell dad to connect to my computer via:
ssh -p $secret_port -R $secret_port:localhost:22 -N $my_username@$my_router_ip & screen; kill %1
## I connect to his computer via:
ssh -v -p $secret_port $dad_username@localhost screen -x
## Now we are both looking at the same shell. We can both type and collaborate.

## Convert/get a date from a timestamp using only Gnu Date
date -d @1199163600

## Sync the date of one server to that of another. (Useful when firewalls prevent you from using NTP.)
sudo date -s "$(ssh user@server.com "date -u")"

## Get 255 random chars from /dev/random
uuencode -m - < /dev/random |sed 1d|tr -d \\n|head -c 255
# That is Base64 [/+a-zA-Z0-9], but you can add a substirution to the sed.
# This one limits it to hex chars:
uuencode -m - < /dev/random |sed '1d;s/[^0-9A-F]//g'|tr -d \\n|head -c 255
# However, for storing into a DB, I like to keep the newlines so:
uuencode -m - < /dev/random |sed 1d|head -c 255

# Time stamp for a file name
date +%s
# a readable one
date +%Y%m%d%H%M%S


# DiG format as a clean single line for batch processing
dig +nocmd kudzu.ajc.com +noall +answer

Thursday, April 23, 2009

How to create patches with diff or “svn diff” and apply them with patch

Nearly all of this information is available elsewhere on the internet. However, I am going to go about demonstrating it in ways that I wish others had. I am primarily concerned with recursively patching directories (patching a single file is very simple), so I ran into some problems which I didn't see anyone else address. Those unique solutions are the main reason I chose to create yet another diff/patch how to.

I like to create demonstrations that you (or I, 6 months from now when I forget all of this) can copy/paste on your own system to prove that it works. (The whole freaking thing, or line-by-line.) I learn best by doing, so I encourage you to "do" these proofs instead of trusting me.

First exercise: Let us create our test environment.

mkdir -p difftest/date
date >> difftest/date/time.txt
find difftest > difftest/files.txt
# Okay, no you have a project folder called difftest

cp -r difftest difftest_new
date >> difftest_new/date/time.txt
mkdir difftest_new/files
mv difftest_new/files.txt difftest_new/files/list.txt
# Now we have made a few modifications to new revision called difftest_new

# Lets not touch the original project folder. We will make a copy to hack on.
cp -r difftest difftest-to-be-patched

# The following command creates a patch
diff -ruN difftest difftest_new > difftest-to-difftest_new.patch
# That is it. You have a patch file that you can share with anyone without embarrassment.
# Note: It is customary to create the patch from the parent folder of both the old and
# new folders. It is bad form to create the patch from either of those folders
# with ../path to get to the other.

# A customary diff patch can be with -p1 which strips the first dir off the path
patch -E -p1 -d difftest-to-be-patched < difftest-to-difftest_new.patch
# The -E is not important here, but it is needed for patches created by svn. I suggest you
# always use it.

# The following command will tell you 2 directories are identical. You just have to trust me.
# We will use this more later.
diff -r difftest_new difftest-to-be-patched
# You want it to return nothing. (It is a diff command, not a same command.)


You need to lookup the means of the args given to the diff and patch commands in there man pages. I hate telling people to RTFM because most are so long you cannot find what you need. I am telling you what you need and asking you to learn why.

The mysterious argument is "N" on the diff command. The manual says, "Treat absent files as empty." Which meant nothing to me, but I learned that I need it. That is what causes the patch to handle the files you move/remove/rename in your revision. That's important and hard to troubleshoot.

Second exercise: Let's put our test into an svn repo and create the patch from there.

# These steps assume you have completed the steps above.
svnadmin create repo
svn mkdir file://$PWD/repo/tags -m 'initial setup'
svn import -m "initial import" difftest file://$PWD/repo/trunk
# Now we have our original project in a new local repo

svn copy file://$PWD/repo/trunk file://$PWD/repo/tags/release1 -m "deployed $(date)"
# Now we have it tagged

# We will make the same changes to trunk that we made in the first exercise.
svn checkout file://$PWD/repo/trunk
date >> trunk/date/time.txt
mkdir trunk/files
mv trunk/files.txt trunk/files/list.txt
svn add trunk/files
svn remove trunk/files.txt
svn commit trunk -m "new"
# Changes are made and commited

svn copy file://$PWD/repo/trunk file://$PWD/repo/tags/release2 -m "deployed $(date)"
# Now we have this one tagged

# Just to prove that you do not need to have a local copy of the code to do this...
rm -rf trunk

# You can create a patch that would bring release1 up to release2 like so...
svn diff file://$PWD/repo/tags/release1 file://$PWD/repo/tags/release2 > release1-to-release2.patch

# So, if your client has release1... created like so...
svn export file://$PWD/repo/tags/release1

# You can tell them to apply the patch like so...
patch -d release1 -p0 -E < release1-to-release2.patch

# I can prove it to you like so...
svn export file://$PWD/repo/tags/release2
diff -r release1 release2
# Again, you have to trust that diff works.

# Finally, if you do not have tags to work with you can do a similar thing with revision numbers
svn diff -r2:4 file://$PWD/repo/trunk > revision2-to-revision4.patch
# That patch is functionally identical to release1-to-release2.patch
# To discover which -r range to use, examine: svn log file://$PWD/repo/trunk


The argument "-E" is important when applying patches created from svn. (There is a subtle difference between patches created with diff and svn diff.) If you leave off the -E you will notice that files you remove (and that includes the original of any file your rename or move) will still exist after applying the patch, but they will have a size of 0 bytes. This is a booger to trouble shoot, and none of the other "how tos" are going to help you much.

So, why would you do this? Why not just send the complete revision to your client, production server, etc. In many cases your projects code can be hundreds of Megabytes. These patches are usually small enough to email. Even if you only modified a single file, following the customary form will save the recipient from having to locate the file that needs to be replaced/patched.

If that doesn't convince you, check out Transferring large PSD files quickly using Diff-Patch

Followers

Blog Archive

About Me

Richard Bronosky
View my complete profile