Montag, 19. Dezember 2011

Intro into Node Modules Part III - CLI FAQ

FAQ on Command Line 
My last post on Command Line Tools is missing some questions that you might find valuable when creating your own command line tools.

A) Can I create multiple command line tools within one package?
Yes. Just add new scripts and the associated keys into your package.json


Lets say we would like to write ccap foo instead of cap -c foo and
dcap FOO instead of cap -d FOO.

First we will create the 2 missing scripts in our bin directory and make them executable

Hector:~/capitalize j$ cd bin
Hector:~/capitalize/bin $ touch ccap.js
Hector:~/capitalize/bin $ chmod +x ccap.js
Hector:~/capitalize/bin $ touch dcap.js
Hector:~/capitalize/bin $ chmod +x dcap.js

Then add the following code into this new files (ccap.js and dcap.js)



Then change the the package.json to have a new version number and to include the new entries within the bin key.


Finally publish the package and install it globally

Hector:~/capitalize $  npm update
Hector:~/capitalize $  cd ..
Hector:~ $  sudo npm install capitalize -g
/opt/local/bin/ccap -> /opt/local/lib/node_modules/capitalize/bin/ccap.js
/opt/local/bin/dcap -> /opt/local/lib/node_modules/capitalize/bin/dcap.js
/opt/local/bin/cap -> /opt/local/lib/node_modules/capitalize/bin/cap.js
capitalize@0.3.0 /opt/local/lib/node_modules/capitalize 


As you see ccap and dcap are now linked into /opt/local/bin and available anywhere on your command line


B) Can I install a command line tool only locally?
Yes - but what is the purpose of that?!
If you install a package containing a command line tool locally then you would have to create a symlink yourself and you need adjust your PATH variable manually to include the symlink etc. 


C) Can I install a command line tool that overwrites an already installed one?
No!
Lets say we want to overwrite the coffee command as we have already installed CoffeeScript on our machine. First we will change the version number of our package again and add a new key called coffee to our bin key.
Now publish and install globally

Hector:~/capitalize robertj$ npm publish
Hector:~/capitalize robertj$ cd ..
Hector:~ robertj$ sudo npm install -g capitalize
npm ERR! error installing capitalize@0.4.0
/usr/local/bin/cap -> /usr/local/lib/node_modules/capitalize/bin/cap.js
/usr/local/bin/ccap -> /usr/local/lib/node_modules/capitalize/bin/ccap.js
/usr/local/bin/dcap -> /usr/local/lib/node_modules/capitalize/bin/dcap.js
npm ERR! error rolling back capitalize@0.4.1 Error: Refusing to delete: /usr/local/bin/coffee not in /usr/local/lib/node_modules/capitalize


Unluckily for you from now on you will be punished. The package has been installed partly and any attempt to update or uninstall it will be greeted with the message that /usr/local/bin/coffee can't be deleted. 
Your last help is to use the force to uninstall

Hector:~ robertj$ sudo npm uninstall --force -g capitalize


I hope you enjoyed the show. Next time as promised "pre/post/installation" scripts.

Mittwoch, 14. Dezember 2011

NPM Modules Step by Step (Part II) - Command Line Tools

Having created our first module and having published as described in this blog post (Introduction into Node Modules Part I) wouldn't it be cool if we could use this extremely sophisticated capitalize and decapitalize functions as a command line tool as well?

Lets say we want to be able to do this on the command line:

Hector:~ $ cap -c foo (yields => FOO)
Hector:~ $ cap -d FOO (yields => foo)

Where cap -c capitalizes the given argument and -d decapitalizes it.

Actually that is very easy.
First we have to change our package.json file


Please take care of the 2 changes that we made against the previous version of that file.
  1. we changed the version from "0.1.0" to "0.2.0" (line 5)
    If we don't change that version to a higher version than the one that has been published previously npm will complain about that fact.
  2. We need to add the key "bin" and the name of the command line tool and the associated script that shall be executed on calling that command (line 18-21)
Lets start hacking on our command line tool. First of all we will create a subdirectory for our command line tool. The standard name for the command line directory is "bin". This is no hard requirement however most npm packages seem to adhere to it. So will we.

Hector:~/capitalize $ mkdir bin
Hector:~/capitalize j$ cd bin
Hector:~/capitalize/bin $ touch cap.js

now add the following code to ~/capitalize/bin/cap.js


Please take care of to a hash-bang in line 1. This is needed (at least under *nix systems).
Lines 4 and 5 are the ones that return the command line arguments.
Argument 0 is the node itself and argument 1 is the script being executed (in this case cap.js).

We are almost done. Actually our script wont be executed (on *nix systems) we have forgotten to change the execution rights. Please do

Hector:~/capitalize/bin $ chmod +x cap.js
Hector:~/capitalize/bin $ ls -ls
total 0
0 -rwxr-xr-x  1 robertj  staff  0 14 Dez 14:20 cap.js

Now we move back to our directory containing our package.json and publish it.

Hector:~/capitalize/bin $ cd ..
Hector:~/capitalize $ npm publish

Finally install the package globally


Hector:~ $ sudo npm install capitalize -g
/opt/local/bin/cap -> /opt/local/lib/node_modules/capitalize/bin/cap.js
capitalize@0.2.0 /opt/local/lib/node_modules/capitalize 

this will install the the command cap as a global link into your global node_modules directory.

I hope you enjoyed the show. Next time: "installation/deinstallation scripts"

Donnerstag, 8. Dezember 2011

A Small Rant On Twitter Followers

I admit I am pretty late to that whole twitter thing. So I am probably astonished by things that the more experienced of you might simply put aside.

Nevertheless it is intriguing to me how sometimes people start to follow me on tweets without obviously reading my bio or at least reading that tweet. My impression is that my bio is pretty clear
Payment expert, entrepreneur & geek
No mentioning of any kind of interest in shoes or vegan products or sex contacts in the Netherlands.
Nevertheless sometimes when twittering or retweeting I get a new hilarious follower ...

Shoes
Lets start with a post about Zalando (the German copy of Zapatos in the US). I had this post which is telling the story of our first shoe delivery by Zalando and has an implicit reference to a german TV-spot.
This brought me @rueschen as new follower.
Very nice - she searches for the perfect shoe meanwhile she walks bare foot and sells shoes from Prada and D&G etc. - seems like the more expensive option.
I am wondering if she is more into my tweets about software development or if she is more interested in payment technology?

Opodo
Actually I made a mistake by booking my travel arrangements via Opodo.
Big service fail which I tweeted about here.
The decision to book my travel arrangements via Opodo is certainly more than foolish. Consequently  those 2 guys started to follow me - probably in the hope that if I was so foolish once I will even more foolish in the future and might buy from them as well.
This one is certainly a candidate for news about CoffeeScript

The next guy is even funnier - he is so obviously trying to sell a multi level marketing scheme while pretending he doesn't want to sell you anything that it almost hurts.
His bio says: #entrepreneur #earn money #freelance #wellness #sidejob # fun etc.
Just because I made the dumb mistake to book my travel via Opodo doesn't mean I will fall into you MLM ponzi scheme.
Or is he realy into node.js?

Vegan
Then I stumbled about a link for vegan shoes which I loudly wondered about
Which made Gordon an avid follower of mine
Gordon is vegan, balanced and informed - sadly he lacks any kind of bull shit detector.
Hey LuckyThorsten I think I got a new customer for you!

Adult Dating
My last and most curious follower started to follow me after this blog post:
This one really opens up a whole bunch of questions:

  • what kind of sexual techniques is nodejs or npmjs?
  • I am located in Munich - why should I follow adult dating contacts in the Netherlands
  • Wouldn't it be fare more cheaper if I got my self a professional instead of travelling to Amsterdam for example
  • How should participate in your web site? Everything is in Dutch! The pictures on your frontpage are universally understood thou.
  • How should I know that you are the best sex dates site in the Netherlands. Have you been audited? By whom? KPMG? Please show me the certificate!
Obviously I will twitter about this blog. Lets see who starts to follow me ...


Mittwoch, 7. Dezember 2011

Introduction into Node Modules Part I

Lets start with a bit of advertising from Node Package Managers (npm - ww.npmjs.org) own home page:
npm is a package manager for node. You can use it to install and publish your node programs. It manages dependencies and does other cool stuff
There is really nothing I can add to this.

Goal
The goal of this blog post is to show you the simplest way to build your own package.
Therefore I will lead you through the creation of a trivial module which will export 2 functions that capitalize and decapitalize a string - Just toUpperCase and toLoverCase by a more fancy name.

This blog post assumes that you have installed node and npm.

Preparation
First create a new directory named "capitalize" and change into that new directory.

Hector:~ $ mkdir capitalize
Hector:~ $ cd capitalize/

within that directory issue the command "npm init" and follow the "wizard".

Hector:~/capitalize $ npm init
Package name: (capitalize)
Description: capitalizes and decapitalizes a string
Package version: (0.0.0) 0.1.0
Project homepage: (none) www.capitalize.org
Project git repository: (none)
Author name: robert kuzelj
Author email: (none) robert@capitalize.org
Author url: (none)
Main module/entry point: (none) main.js
Test command: (none)
What versions of node does it run on? (~0.6.0)

This will create the following "package.json" file. Which is by far the most important
file when creating and managing node packages.
"npm publish" will use this file when publishing your module locally or to the internet.

Code
Lets start hacking some serious code. First we will create a sub directory called "lib" 
that contains the actual code. We will split our code into 2 files for illustration purposes.

Hector:~/capitalize $ mkdir lib
Hector:~/capitalize $ cd lib
Hector:~/capitalize/lib $ touch capitalize.js
Hector:~/capitalize/lib $ touch decapitalize.js

Now enter this extremely sophisticated code in the file "~/capitalize/lib/capitalize.js"
Now enter the following code in the file "~/capitalize/lib/decapitalize.js"

Finally add the code for the file "~/capitalize/main.js"

Obviously the code within capitalize.js and decapitalize.js could have also been directly in main.js. However I wanted to show you 2 things:

  1. it is good practice to split your module into smaller files and put those files under the lib directory and into lib's child directories.
    You can use a different directory name however the node community has implicitly agreed on "lib" as the default name.
  2. it is good practice to have the entry point of your module require any files in the lib subfolder and reexport those functions that should be accessible from any client code.
Local Publishing
Now lets test our industry strength module before we are going to publish it.
First we will create a symbolic link within the npm system

Hector:~/capitalize/lib $ cd ..
Hector:~/capitalize $ npm link

npm link reads the package.json file and creates a symbolic name using the "name"-entry on top of your OS's symbolic links (at least thats what I assume).

Now lets create some test Javascript that uses our new module. First we create a new directory and create a new npm link within.

Hector:~/capitalize $ cd ..
Hector:~ $ mkdir cap-test
Hector:~ $ cd cap-test
Hector:~/cap-test $ touch test.js
Hector:~/cap-test $ npm link capitalize
capitalize@0.1.0 /opt/local/lib/node_modules/capitalize
./node_modules/capitalize -> /opt/local/lib/node_modules/capitalize

If you execute npm link <module-name> a symbolic OS link that points to the source directory of <module-name> will be created. Any changes within the source directory will be visible within the client directory and can immediatly tested.

Now add the following code to your "~/cap-test/test.js"
This will (hopefully) yield the following output

Hector:package-03 $ node test.js
FOO
bar

Public publishing
We are almost there ;-) only on small final thing. We need to add a user to the registry at www.npmjs.org.

Hector:~ $ npm adduser
Username: robkuz
Password:
Email: robert@capitalize.org

This will create a file named ~/.npmrc that includes your email and your authentication token. This file is  used when you publish anything to the global npm registry.

Now its time to begin our journey into land of the rich and famous. Change back into the root directory of your module and issue npm publish

Hector:~ $ cd capitalize
Hector:~/capitalize $ npm publish

Finally everybody can find our module

Hector:~/cap-test $ npm find capitalize
NAME        DESCRIPTION                                                   AUTHOR   KEYWORDS
capitalize  capitalizes and lowercases strings (example - No Production!) install scripts =robkuz
or install our module by simply issuing the command npm install capitalize.


Parting Words
Please change the "name" key  in the package.json when you following this post.
you can't use "capitalize" as a name on the global npm registry as it is already exclusively assigned to me.

I hope you enjoyed the show.
ps: the next blog will show you how to create command line tools with node.js