A small Ruby script to quickly throttle any port

Here is a small Ruby script I made for quickly throttling a specific port. It uses an ipfw pipe in order to do so; the script should work on any computer that has both Ruby and ipfw installed (that includes all Macs).

If you’re interested in using the script and if you haven’t done so already, I recommend that you create a folder to store all of your scripts and add that path to the bash $PATH variable (in your ~/.bash_profile file or any other equivalent file) as follows:

export $HOME/path/to/my/scripts/folder:$PATH

Copy the script to that folder and make it executable, like so (where “throttle” is the filename of the script to make executable):

chmod +x throttle

After that’s done you’ll be able to throttle any port with a simple command. Here, we limit port 80 to 200 KB/s.

throttle 80 200

Here’s the script. Note the use of %x[] to execute bash commands, combined with $? to obtain their exit status. Also note the use of “#!/usr/bin/ruby” at the beginning of the script. This is what prevents us — combined with the executable flag set above — from having to type “ruby throttle 80 200″ instead of simply “throttle 80 200″.

#!/usr/bin/ruby

usage = "Usage: throttle [port-number] [KB/s]"

# Arguments validity check
if ARGV.count != 2 then; puts usage; exit; end

# Store arguments
port = ARGV.at(0)
kbps = ARGV.at(1)

# Throttle using ipfw
%x[
	sudo ipfw pipe 1 config bw #{kbps}KByte/s
	sudo ipfw add 1 pipe 1 src-port #{port}
]
if $? != 0 then
	puts "Oops! #{usage}"
	exit
end

puts "Throttling port #{port} at #{kbps}KB/s."
puts "Press ENTER to stop throttling..."
STDIN.gets

# Stop throttling
%x[sudo ipfw delete 1]
Posted in Scripting | Tagged | Leave a comment

Recommended Reading — Part 1

Here’s a quick list of recommended reading for anyone interested in Mac OS X development and software development in general:

Cocoa Programming for Mac OS X by Aaron Hillegass

THE book everyone recommends (as well as myself) to start developing for Mac OS X. Very comprehensive. You can read this from cover to cover easily, and you’ll have fun doing it. This is a tutorial-style book with concrete examples demonstrating each concept. The book is a great introduction to the world of Cocoa programming and enables you to begin developing your own apps for the platform.

Required skill level: Beginner

Cocoa Design Patterns by Erik M. Buck, Donald A. Yacktman

A great book that goes more in depth on the design patterns and concepts behind the Cocoa frameworks. Required reading for anyone who wants to master Cocoa. You will have some “aaah!” moments when you realize how the patterns help Cocoa do it’s magic. Easy to read from cover to cover, but it’s also a great reference.

Required skill level: Intermediate

Pragmatic Programmer: From Journeyman to Master by Andrew Hunt, David Thomas

Programming philosophy and self-discipline, if you will. It does contain quite a few code samples to demonstrate various recommended techniques, so it’s not only philosophy. This book contains a lot of very good advice for software development and everything related. Also a must-read, particularly for someone with little software development background.

Required skill level: Beginner / Intermediate

Posted in Uncategorized | Leave a comment

Git Aliases Quick Tip

Here’s a quick tip to create Git aliases for commands that you use often but are too long to type each time you want to use them. If you haven’t heard of Git or if you want to get up to speed, you could check out my previous Git article here.

Step 1 – Edit one of those files:

Global Git config: ~/.gitconfig
Project-specific config: myproject/.git/config

Step 2 – Add this to the file:

[alias]
	logd = log --decorate
	logg = log --decorate --graph --oneline

You will then be able to do this:

	git logd # Runs git log --decorate
	git logg # Runs git log --decorate --graph --oneline

You can make aliases for all your favorite, lengthy Git commands this way.

Posted in Version Control | Leave a comment

Selling my apps on the Mac App Store

Distributing apps on the Mac App Store is definitely an interesting prospect for Mac developers. I have seen many highly regarded Mac app developers backing the initiative almost immediately after the announcement saying their apps would be available on the App Store at launch. No wonder: imagine the amount of people who have never even thought about downloading an app that will suddenly discover all the great apps that they’ve been missing. As we’ve seen from the iOS App Store, the one-click simplicity of purchasing, downloading and installing apps makes them so much more accessible to the common user. I wouldn’t be surprised if Microsoft creates an app store of their own soon.

When news got out that the Mac App Store was a reality, some speculated that developers could decide to price their apps differently on the App Store than on their own websites because of the 70/30 cut for app sales revenues. I was intrigued by this possibility but didn’t consider it until recently.

Selling my apps on the App Store

I have decided to try something: selling my apps on the App Store for a small amount of money while keeping them free on my website for anyone to download. This could be seen as some kind of variation on the “different pricing for different stores” strategy I talked about in the previous paragraph, but instead of a developer charging say, 12$ on his website and 15$ on the App Store, I’ll be charging 0$ (nothing) on my website and 2$ on the App Store.

Why?

Developing applications takes time and hard work. Even more so maintaining them and supporting them in the long run. As I am currently studying software engineering, I’ve been pretty much booked since I first published my apps back in April 2010. Still, I’ve been able to publish two apps that I’m very proud of and I have received great feedback, feature requests and bug reports from many of you.

As much as I like to give to the community, there are some fees that I must pay to make that possible (website hosting, domain names, Mac Developer Program membership, etc.). I don’t really care if I’m not making a profit with my apps because they aren’t meant for that. I created them for myself in the first place, then decided to polish and publish them. One thing that’s a bit uncool though is if I’m losing money publishing my apps, which is currently the case (donations have alleviated that a bit, thanks so much!).

I really don’t mean this as a cry for help; I simply don’t want to begin charging for apps that have been available for free thus far and screw my current users, while I would also like to compensate for some of the fees that I have to pay in order to make my projects work.

The App Store seems like a great way to do this and keep everyone happy.

What do you think about this strategy? Do you think it’ll work? Do you think it’s fair? Tell me in the comments. Take care!

Posted in Discussion, Mac App Store | 5 Comments

Git Cheat Sheet, Overview & Tutorial

Introduction

This is my personal cheat sheet for Git, which I built as I learned the tool more in depth in the past few days, cleanly formatted for your enjoyment (God knows it didn’t look like this before I started bringing all of it into WordPress!).

If you’re already fluent using a version control system such as SVN you should be able to get a good grasp of Git by reading this article. Though if you’re looking for a complete, extensive multi-page tutorial, I suggest this one which is very well-written and easy to follow: http://book.git-scm.com/index.html.

I’ve tried to include as much relevant information in as little space as possible. If you have some favorite commands and tips of your own, please share them in the comments. Enjoy!

Important Git Facts to Keep In Mind

  • Each Git repository clone contains the whole commit history and all branches (including master, which you could consider the equivalent of a SVN project’s trunk). You use git clone instead of svn checkout to clone a whole repository onto your own machine. Example:
    git clone git://git.videolan.org/vlc.git
    
  • The concept of branches, tags and trunk (the master branch, in Git’s case) is part of Git itself. This structure is not visible on disk, it is stored in myproject/.git in compressed form; you can switch between branches using git checkout [branch name] which replaces the contents of the working copy with the branch in question.
  • Because of its distributed nature, Git doesn’t have monotonic revision numbers, it rather uses SHA-1 hashes as commit identifiers. Still, it is possible to obtain monotonically-increasing commit names using git describe and other commands. While this may seem awkward, I didn’t find this to be an issue because of how tags work in Git.
  • You can refer to commits using only part of their commit name (the SHA-1 hash). As long as no other commit name contains the same string the commit will be found.
  • Git workflows can vary a lot. They can be very inventive or they can pretty much match the kind of workflow you may be used to with SVN or other version control systems. See the “Any Workflow” section in this page for some very nice and clear examples of various Git workflows.

Configuration

Before committing code to a repository, you should setup your Git user name and email so that your commits contain the correct contact information. There are also some interesting global variables that you can tweak before you begin working with Git.

# User configuration, shown in commit log.
git config --global user.name = "John Doe"
git config --global user.email = "john.doe@email.com"
# Activate colored output. IMHO makes "git diff" and "git log --graph"
# much clearer and easier to follow.
git config --global color.diff = auto
git config --global color.status = auto
git config --global color.branch = auto

The --global flag stores the settings in the ~/.gitconfig file which applies automatically to all projects configured for the current user on the machine. You can set variables on a per-project basis by using the same command without the --global flag within the project’s directory.

Creating Repositories

Normal repositories contain both the repository (history, branches, tags, etc.) and a working copy, while bare repositories contain only the repository and no working copy. This makes bare repositories ideal for server-side or centralized repositories where no work will be done directly.

# Bare repository
git --bare init
# Normal repository
git init

Staging & Committing

Git has what’s called the staging area or index. Here’s how it works:

The Git add / commit / push & pull process

The git add command effectively stages new, removed and even modified files for the next commit. If you don’t stage changes, they won’t be committed. This means that by using git add filename and git status (which prints the staging area’s contents as well as information about what’s not staged) you can add part of your changes to the staging area and commit only that. You can then commit the rest afterwards. If you would rather commit all changes (added, modified and removed files), you can use git add -A and git commit -a. More below:

Adding files

# Adds and stages a single file
git add myfile.txt

# Stages all files, including new files that haven't been added yet.
git add -A

Staging and committing

# Stage all files that have previously been added at least once (-a) and commit.
# New files aren't staged automatically.
# Use git add -A or git add filename for this.
git commit -a

# Add to the last commit (very useful!).
git commit -a --amend

# Stage, commit and specify an inline commit message.
git commit -a -m "This is a description."

Seeing what’s staged and what’s not

# Detailed output
git status

# Compact output
git status -sb

The staging area can be useful, so make sure you read a bit on this subject before compulsively appending the “-a” option to all commit commands. For more information about the staging area or “index”:
Git Community Book – The Git Index
git ready – the staging area

The Commit Message

Regarding the commit message, it is recommended (but not necessary) to include a small summary as the first line (about 50 characters or less), then leave the second line empty and enter the rest of the commit details below. The syntax highlighting in the commit message editor (vim) will indicate this by making the first 50 characters or so a different color and marking the second line as an error if it’s not empty.

A non-optimal Git commit message
A better Git commit message

Pushing & Pulling

Because you have a complete clone of the repository on your machine, what you’re actually doing when using git commit is committing to your own local repository. If you want to send the committed changes to a remote repository (whether on same machine, somewhere on your local network or on a web server), you must use the git push command. To obtain changes from a remote repository, use git pull.

A relevant quote regarding tags and git push (more in the Tags section of this article): “By default, tag objects (i.e. signed or annotated tags) attached to commits new to the remote being pushed to are pushed. Lightweight tags and tags attached to commits already on the remote aren’t pushed.” — http://stackoverflow.com/questions/2988088/do-git-tags-get-pushed-as-well

Setting up remote repositories

# Setting up the "origin", a default remote repository (usually once per project).
git remote add origin ssh://username@mydomain.com/~/repos/myproject

# Setting up another remote repository.
git remote add otherrepo ssh://username@myotherdomain.com/~/git/myproject

Remote repositories can also be accessed using HTTP and Git’s own protocol (git://). Obviously SSH has the security advantage. The Git protocol though has the speed advantage. HTTP can be useful when you want to be able to bypass firewalls and proxies.

Pushing

# Push all branches that are common to the remote and local repositories.
git push

# Push the branch "master" to the "origin" repository.
git push origin master

# Push tags to the remote repository (tags are NOT pushed automatically!).
git push --tags

Pulling

# Pull changes from origin remote repository.
# Fetches from repository then merges into current branch.
git pull

Status, Logs & Graph

Often you will want to know in what state your repository is. Using these commands you can obtain details about previous commits, branching and merging in the repository, changes between the working copy and the staging area, etc.

# Shows the commit log.
git log

# Shows the commit log for the repository, including tag / branch membership.
git log --decorate

# Obtain a graphical view of commits, branches and merges.
git log --graph --all

# Same as the previous command but with compact output.
git log --graph --all --oneline

# Shows what changed in the current branch since the last commit.
git status

Diffs

You can use git diff to see the differences between your working copy and the last commit, between different commits, in your local repository, or between various other things in your repositories.

Seeing what you will commit

# Working copy VS the staging area.
git diff

# Staging area VS the latest commit.
git diff --cached

# Working copy VS the latest commit.
git diff HEAD

Other comparisons

# Compare the master branch with the tag named "1.1".
git diff master..1.1

# Compare the master branch with a branch named "mybranch".
git diff master..mybranch

# Compare only the files and folders containing "Unit" in branch1 and branch2.
# Note the use of the "*" wildcard character. The "--" is a path delimiter.
git diff branch1..branch2 -- *Unit*

Tags

There are two types of tags in Git: lightweight tags and annotated tags. Lightweight tags are essentially a simple reference to a commit’s name, while annotated tags are actual objects in the Git repository database and contain additional information such as the tag author, date and other useful metadata.

It’s generally recommended to create annotated tags (using the -a option) because those are supported by git describe and other useful commands. You can at any point in time replace a lightweight tag with an annotated one by noting the commit name, deleting the lightweight tag and re-tagging the commit with an annotated tag.

Obtaining information about tags

# List all tags.
git tag

# Show the commit log including tags and branches
git log --decorate

# List details of the tag named "1.1b1".
git show 1.1b1

Working with tags

# Tags the latest commit with the name "1.1b1" (annotated tag).
git tag -a 1.1b1

# Tags the commit with the name that begins with "1b2e1d63ff"
# with the tag name "1.1b1".
git tag -a 1.1b1 1b2e1d63ff

# Tags the latest commit with the name "1.1b1" and a message.
git tag -a 1.1b1 -m 'Version 1.1 beta 1 (pre-release)'

# Deletes the tag named "1.1b1".
git tag -d 1.1b1

Branches

You can easily create, remove and merge branches with Git. As explained in the Important Git Facts to Keep In Mind section, branches are not stored as-is in the filesystem but are rather stored in the hidden .git folder in your project’s directory. When you use git checkout mybranch, the whole working copy is replaced with the “mybranch” branch. You can switch back to the master branch by using git checkout master.

# Lists all branches in the local repository.
git branch

# Creates a new branch named "mybranch" based on the current branch.
git branch mybranch

# Switches the working copy to "mybranch".
git checkout mybranch

# Creates a new branch named "mybranch" and switches to it right away.
git checkout -b mybranch

# Deletes the branch named "mybranch" but only if the branch
# doesn't contain commits that haven't been merged into the current branch.
git branch -d mybranch

# Deletes the branch named "mybranch" regardless
# of differences with the current branch.
git branch -D mybranch

Checking out a branch with local changes

When using git checkout to switch to another branch, if your current branch has local changes, Git can either try to carry your local changes across to the new branch or discard the changes altogether. See this Stack Overflow question for more details.

Merge

Of course if you branch some work you will want to merge it back into your master branch after your work is done. The git merge command does this. Note that when you use git pull, Git actually fetches the changes from the remote repository then merges them into the current repository.

# Merges the branch "mybranch" into the current branch.
git merge mybranch

Fixing merge conflicts

If there are conflicts after a merge, Git will have inserted conflict markers in the conflicted files. The git status command will show those files are “unmerged”. All you need to do is to edit those files to fix the conflicts, then stage and commit them. Note that when committing after fixing merge conflicts, you don’t need to specify a commit message (but you can); the commit message will have already been filled in with information about the merge.

If the conflict is in a binary file, you can choose either your current branch’s file or the merge source’s file as the correct one using these commands:

# Replace the current branch's file with the version in the merge source branch.
git checkout --theirs -- path/to/conflicted-file.txt

# Consider the file in the current branch to be the correct one.
git checkout --ours -- path/to/conflicted-file.txt

Related useful commands

# Returns the working copy to pre-merge state.
# Use this if your merge wasn't successful and you want to start over.
git reset --hard HEAD

# Replace a file with the version in the latest commit.
git checkout filename

For more information on git merge see this page:
Git Community Book – Basic Branching and Merging

Conclusion

That’s it! For now that’s what I’ve found to be the most important knowledge to get going using Git (at least in a one-man-team context). I hope you learned some things reading this. I’ll make sure to post some new interesting Git tips as I discover them, so I encourage you to subscribe to the RSS feed if you liked what you read. You are also invited to post some feedback in the comments if you find inaccuracies, if you have something interesting to share or simply if you have something to say about the article. Until next time!

Posted in Version Control | Leave a comment

Interesting technical stuff worth writing about

I don’t know about you but I often find myself noting down procedures to remember myself of some of the technical things I work on for a while before they work like I want them to. You know, so that I don’t have to scour the Internet for the answer all over again when the time comes to do that thing again.

From now on this blog will be my notepad for all those little things I spend more time than I would like trying to setup and/or implement. Most of my posts will be about technical stuff (workflow tips, shell scripting, version control, server configuration, software development, web development, etc.) so if you are not technically inclined this is not a blog for you. Else I encourage you to subscribe to the RSS feed by clicking here. I won’t post very often but when I do it will be about things that I think are truly relevant to anyone involved in software development and general computer geekery.

I am currently preparing my first couple articles, so check back in a short while or subscribe to the RSS feed to stay in the loop!

Michaël

Posted in Discussion | Leave a comment