IBM i Toolkit for Ruby, iit For Short
April 7, 2015 Aaron Bartell
What if I told you that the best developers in the world are available to work on your next project? What if I told you that they will work for free? Well, they are and they will. In the following paragraphs, I tell you why and how. The best developers in the world will help you with your projects, for free, because of the magic of open source. Open source efforts have to rank right up there on the list of abnormalities of the human race. Why? Because so much is given away at high cost (time, which in turn is often money). It makes one scratch their head as to why it has become so prolific. Watch this video. It will tell you–in a very entertaining way–more about what motivates open source developers. I suppose each person has their own reason(s) for contributing. I equate it to how I might go and ask my neighbor for a cup of sugar because I am out and don’t have time to run to the store. In that scenario my neighbor was able to help me and maybe it gave them a slice of life purpose. In short, community has happened. The other important reality is we are greater than the sum of our parts. My development team and I can only produce so much in a workday, and more than likely somebody else is going through the same motions of development. If we combine our efforts, we can get an end solution quicker and most likely a more robust and honed solution for multiple purposes or industries. It is for these reasons I am introducing a new open source project named iit, short for “IBM i Toolkit”. The iit project is meant to give Ruby developers simple and easy access to existing IBM i resources. The code was born out of needs we had at KrengelTech and we believe others could make use of iit, and even more importantly we are hoping others will contribute. That’s what this article is about: how to contribute to an open source project. These are the high-level steps you need to take to contribute to the iit project:
The first skills you need to learn are how to fork a project and how to generate pull requests. At KrengelTech, we use Bitbucket to carry out these processes because we get unlimited private repositories, and because Bitbucket integrates with a number of other tools that are very useful to an IT development team, including: Bitbucket has some good documentation here, so I won’t delve too deep as to the definition but instead describe why it is necessary for the iit project. Right now only a few people have write access to the iit Bitbucket git repository, but we still want to make it easy for others to contribute to the project. Let’s pretend for a moment that I am not allowed to commit changes to the iit git repo, yet I desire to add a new feature to retrieve IBM i system values (i.e. DSPSYSVAL). To do this I need to fork the existing iit repo, as shown below, which makes a copy of the entire repo under my profile. This repo is completely separate from the original iit repo. NOTE: You will need to sign up for a free Bitbucket account before you can fork. Next you will be prompted to supply additional information. I only changed the Description field. Once the fork is complete you will now have a git repo named iit under your personal profile, as shown below. At this point the code is only on the server and we now need to “clone” it down to the IFS on our IBM i. If you look to the far right of the project page you can see the field that holds the path to the repository. Copy that value and use it on the next step. Open up a shell (either through ssh or CALL QP2TERM) and run the following commands, making sure to supply your profile and Bitbucket repo. $ mkdir -p /home/aaron/git $ cd /home/aaron/git $ git clone git@bitbucket.org:aaronbartell/iit.git Cloning into 'iit'... remote: Counting objects: 10, done. remote: Compressing objects: 100% (8/8), done. remote: Total 10 (delta 0), reused 0 (delta 0) Receiving objects: 100% (10/10), 5.06 KiB | 0 bytes/s, done. Checking connectivity... done Now go into the newly created project directory. $ cd iit Being that this is a RubyGem we need to first build and install it. This will allow us to test the existing functionality in the next step. $ gem build iit.gemspec Successfully built RubyGem Name: iit Version: 0.0.1 File: iit-0.0.1.gem $ gem install ./iit-0.0.1.gem Successfully installed iit-0.0.1 Parsing documentation for iit-0.0.1 1 gem installed Now it is time to write the new feature of obtaining a system value. I plan on parsing the DSPSYSVAL output with regular expressions (regex for short), but first I need to get an idea of what the output looks like. Below I’ve started up an irb session, required iit gem, and run the existing IIT.qcmdexc command. $ irb irb(main):001:0> require 'iit' => true irb(main):002:0> IIT.qcmdexc "DSPSYSVAL SYSVAL(QMODEL)" => " System Values Page 1n5770SS1 V7R1M0 100423 GREEN 12/03/14 11:52:48 CSTn Current Shippedn Name value value Descriptionn QMODEL E8D ' ' System model numbern Note: > means current value is different from the shipped valuen * * * * * E N D O F L I S T I N G * * * * *n" irb(main):003:0> The portion immediately following => is the output from the command and what we need to parse with a regex. I am far from a regex expert so I head over to http://regex101.com, which is a tool that lets me interactive enter regex syntax to test my selection. Below is a screenshot of what the regex matcher looks like and the regex expression I used. I use regex infrequently enough that I have to reach out for help. The cool thing about regex101.com is they have an IRC (instant chat) page where you can ask questions including posting a URL where your current string and regex isn’t working. Below is the conversation I had on IRC. Note that my question was answered within two minutes. Nice! Now we are ready to introduce that regex into a new Ruby method named DSPSYSVAL to file lib/iit.rb, as shown below. The second line of the method starts out with the regex, then calls the “match” method on the regex passing the result from the call to “qcmdexc”. The “rescue” at the end is in case something blows up, then it will simply return blanks. def DSPSYSVAL(value) result = qcmdexc "DSPSYSVAL SYSVAL(#{value})" /QMODELs+([0-9A-Z]+)/.match(result)[1].strip rescue '' end Now that the method is written we need test it. We can do that by first building and then installing the Gem, as shown below. $ gem build iit.gemspec Successfully built RubyGem Name: iit Version: 0.0.1 File: iit-0.0.1.gem $ gem install ./iit-0.0.1.gem Successfully installed iit-0.0.1 Parsing documentation for iit-0.0.1 1 gem installed Next start an irb session and invoke the new method, as shown below. $ irb irb(main):001:0> require 'iit' => true irb(main):002:0> IIT.DSPSYSVAL "QMODEL" => "E8D" It worked! The next step, if I am a responsible programmer, is to create a unit test for this new method. I will definitely do that but we won’t digress through it here for the sake of brevity and will instead cover that in another article. At this point I have new code I need to put back into my Bitbucket so I can subsequently issue what’s called a “Pull Request” (PR for short). A PR is basically the process of me offering my changes back to the parent repository. First things first, let’s commit and add our changes. I always issue a “git status” to learn what’s changed in my repo, as shown below. As expected there are two modified files. $ git status # On branch master # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: iit-0.0.1.gem # modified: lib/iit.rb # no changes added to commit (use "git add" and/or "git commit -a") Next I use command “git add”, “git commit”, and “git push” to log an instance of this code in time and place it back on Bitbucket in my forked repo. Note the “.” (period) used on the “git add” command is signifying that all changes from the current directory on down should be added. $ git add . $ git commit -m 'Added method DSPSYSVAL' [master 984f1fd] Added method DSPSYSVAL 2 files changed, 5 insertions(+) $ git push origin master Counting objects: 9, done. Delta compression using up to 8 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (5/5), 1.79 KiB | 0 bytes/s, done. Total 5 (delta 3), reused 0 (delta 0) To git@bitbucket.org:aaronbartell/iit.git 71877cf..984f1fd master -> master If you go back to your repo in the browser you can see the new commit, as shown below. Next create a pull request so the parent repo knows we are done with the feature and would like to share, as shown below. In the below screenshot we see the “from” and “to” repos. The title of the pull request is pre-filled with the most recent commit message and all that’s left to do is select Create pull request. Now if I go back to the parent repo I can see the pull request and have the opportunity to review and merge it, as shown below. If I am curious as to what changed in a particular file I can easily see it with the visually colorful diff tooling, as shown below. I hope this gives you a better understanding on how to participate in the community. I would greatly appreciate if others would contribute to this project, even if it is a simple edit to the README.md file to give more examples of basic usage. Stay tuned for an article on how to add unit tests to your Ruby code. Aaron Bartell is Director of IBM i Innovation for Krengel Technology, Inc. Aaron facilitates adoption of open source technologies on IBM i through professional services, staff training, speaking engagements, and the authoring of best practices within industry publications and www.litmis.com. With a strong background in RPG application development, Aaron covers topics that enable IBM i shops to embrace today’s leading technologies including Ruby on Rails, Node.js, Git for RPG source change management and RSpec for unit testing RPG. Aaron is a passionate advocate of vibrant technology communities and the corresponding benefits available for today’s modern application developers. Connect with Aaron via email at abartell@krengeltech.com. Aaron lives with his wife and five children in Southern Minnesota. He enjoys the vast amounts of laughter having a young family brings, along with camping and music. He believes there’s no greater purpose than to give of our life and time to help others. RELATED STORIES RubyGems Are The Foundation Of Success
|