How I setup my Terminal on Linux

Today, I got a new computer in my company. So I have to set it up to have my comfortability.

This one runs CentOS 7 and for Linux based OS, Terminal is what you work with the most.

So, I started to configure it.

  • Change the background color and cursor of Terminal

The default color of Terminal is white background and block cursor. But I prefer black background and underline cursor because white background is so dazzlingly bright.

So, open up the Terminal, choose from the menu: Edit > Profile Preferences:

2017-05-10_110243

2017-05-10_110512

  • Change Bash PS1 colors for easy navigating and observing and show git branch information

Bash allows us to customize color and appearance of Terminal information, below is my own style. For more information for your own customization, refer this link.

And I also work quite much with Git so I need to visible branch information in Terminal.

# get current branch in git repo
 function parse_git_branch() {
 BRANCH=`git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'`
 if [ ! "${BRANCH}" == "" ]
 then
 STAT=`parse_git_dirty`
 echo "[${BRANCH}${STAT}]"
 else
 echo ""
 fi
 }

# get current status of git repo
 function parse_git_dirty {
 status=`git status 2>&1 | tee`
 dirty=`echo -n "${status}" 2> /dev/null | grep "modified:" &> /dev/null; echo "$?"`
 untracked=`echo -n "${status}" 2> /dev/null | grep "Untracked files" &> /dev/null; echo "$?"`
 ahead=`echo -n "${status}" 2> /dev/null | grep "Your branch is ahead of" &> /dev/null; echo "$?"`
 newfile=`echo -n "${status}" 2> /dev/null | grep "new file:" &> /dev/null; echo "$?"`
 renamed=`echo -n "${status}" 2> /dev/null | grep "renamed:" &> /dev/null; echo "$?"`
 deleted=`echo -n "${status}" 2> /dev/null | grep "deleted:" &> /dev/null; echo "$?"`
 bits=''
 if [ "${renamed}" == "0" ]; then
 bits=">${bits}"
 fi
 if [ "${ahead}" == "0" ]; then
 bits="*${bits}"
 fi
 if [ "${newfile}" == "0" ]; then
 bits="+${bits}"
 fi
 if [ "${untracked}" == "0" ]; then
 bits="?${bits}"
 fi
 if [ "${deleted}" == "0" ]; then
 bits="x${bits}"
 fi
 if [ "${dirty}" == "0" ]; then
 bits="!${bits}"
 fi
 if [ ! "${bits}" == "" ]; then
 echo " ${bits}"
 else
 echo ""
 fi
 }

export PS1="\[\e[31;40m\]\u\[\e[m\]@\[\e[33;40m\]\H\[\e[m\]:\[\e[36;40m\]\w\[\e[m\]\[\e[32m\]\`parse_git_branch\`\[\e[m\]\n"

Add above to .bashrc (sudo gedit ~/.bashrc and paste above scripts to the end of the file) file and the result:

2017-05-10_111541

P/s: don’t forget to run source ~/.bashrc to make it takes effects.

  • Setup git autocompletion

It supports us to work faster and more accurate with git commands. So to make it happens, I use a guide from here:

Get the autocompletion script:

curl https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash -o ~/.git-completion.bash

Add the below script to the end of the ~/.bashrc file (sudo gedit ~/.bashrc):

test -f ~/.git-completion.bash && . $_

Fire up changes:

source ~/.bashrc

Now the Terminal is ready to be worked on. Yay.

P/s: Actually I use Git to manage my dotFiles, including terminal customization.

Advertisements

How to deploy your hubot to Heroku and why your bot is not working after deploying

After completing the development of my Hubot, I decided to deploy it to Heroku.

I followed the tutorial on Github’s Hubot guideline as here.

For, short:

$ cd [path-to-your-hubot-folder]
$ heroku login

# Setup git (if not yet).
$ git init
$ git add .
$ git commit -m "Initial commit"

# Create a new heroku application.
$ heroku create

# Push to heroku master.
$ git push heroku master

# Set Slack token for heroku (Can be found at
# https://[your-slack-channel].slack.com/home 
# and under your Hubot app config).
$ heroku config:set HUBOT_SLACK_TOKEN=[xoxb-YOUR-TOKEN]

# Set heroku keep alive url (To keep your bot active).
$ heroku config:set HUBOT_HEROKU_KEEPALIVE_URL=$(heroku apps:info -s  | grep web-url | cut -d= -f2)

But my bot is not working at all, it keeps sleeping on the new Heroku’s bed and not responded to any of my commands.

I checked the build log on Heroku dashboard, it shows a lot of node modules are lack.

I viewed the .git_ignore file and its content:

node_modules
.DS_Store*
.hubot_history

So entire node_modules is ignored during commit and pushing to Heroku. So I think that it’s the reason why my bot is not working after deploying.

I forced to add the folder with -f parameter in git add command (or you can just remove the line in .git_ignore folder), then commit and push again to Heroku.

And finally… the monster awakens.

How to debug Github’s Hubot script?

First of all, Hubot is a complete Node.js application itself. And for Node.js applications in general, node-inspector is a celebrity out there as a debugger based on Blink Developer Tools.

If you did not install node-inspector yet, install it as a global package and under root.

$sudo npm install -g node-inspector

Wait for a few seconds till the installation process is done.

Inside your hubot project folder, start the debugger:

$node-inspector --no-preload --web-port 8123

When the following message appears, it means that our debug session is ready.

Node Inspector v1.0.0
Visit http://127.0.0.1:8123/?port=5858 to start debugging.

Now we need to start our bot, in a different way than the old ‘bin/hubot’ command and remember to put your bot name corresponding to your application:

$coffee --nodejs --debug node_modules/.bin/hubot --name "[your_bot_name]"

And to set a breakpoint, put debugger to any line of your code, like:

2017-04-04_174110

In Chrome, visit http://127.0.0.1:8123/?port=5858 to start your debugging session, debug like any of your web applications.

 

zsh cannot execute global npm packages

Today, I installed an npm package globally, no problem here.

Screen Shot 2017-03-11 at 2.01.37 PM.png

But, when I execute the package, there comes an error:

~  yo
zsh: command not found: yo

So, it means that the system doesn’t realize the path to my package. I confirm by using:

~/W/C/htnmaruko  echo $PATH
/Users/duchoang/.rbenv/shims:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin

So that, we need to export the path to where my package is lying in.

Because I installed by -g parameter, so it is lying in global npm. In my case, it is being in ~/.npm-global.

Steps:

1. Export your path in ~/.zshrc (in case of using zsh, otherwise using ~/.bashrc) by  print it to your ~/.zshrc or ~/.bashrc (in case of not using zsh) file:

~/.n/bin  printf "\nexport PATH=\"\$PATH\":%s\n" ~/.npm-global/bin >> ~/.zshrc

Or just editing with vi:

~  vi /Users/duchoang/.zshrc

2. Now, fire up the changes:

~  . ~/.zshrc

3. And finally, the problem gets solved, the result we have:

Screen Shot 2017-03-11 at 2.03.28 PM

Now we can get back to our work.

The git error: “gpg failed to sign the data”

Today, I need to commit some pieces of stuff to my GitHub repository, but somehow this error comes I don’t know.

It’s really painful.

error: gpg failed to sign the data
fatal: failed to write commit object

After some researches on Google, I know that Github has implemented something called GPG to sign and verify work from trusted collaborators, using public-secret key mechanism. (refer: https://help.github.com/articles/signing-commits-with-gpg/)

My below guide is used on MacOS. For other platforms, please refer this link for Windows and this link for Linux.

So, to solve the problem, I have to config gpg to be able to sign commits. Note that from now, I will use brew to manage my installations. To install and know more about brew, you could go through its homepage: https://brew.sh

Homebrew installs packages to their own directory and then symlinks their files into /usr/local.

1. We need pinentry to read passphrases and PIN numbers in a secure manner. (For more information: https://www.gnupg.org/related_software/pinentry/index.en.html)

~/W/G/TalentHub-solutions brew install pinentry-mac

2. We need gpg of course, I use gpg2

~/W/G/TalentHub-solutions ❯ brew install gpg2

3. Now we are ready to generate our secret key, I chose all by default.

~/W/G/TalentHub-solutions  gpg --gen-key

Screen Shot 2017-03-10 at 10.35.20 PM

4. Once you have a private key to sign with, you can configure Git to use it for signing things by setting the user.signingkey config setting.

4.1. Get your secret key:

~/W/G/TalentHub-solutions  gpg --list-secret-keys

You will see something like:

Screen Shot 2017-03-10 at 10.40.35 PM

Then, B069A034 is your secret key.

4.2. Config your signing key:

~/W/G/TalentHub-solutions  git config --global user.signingkey B069A034
~/W/G/TalentHub-solutions  git config --global gpg.program gpg
~/W/G/TalentHub-solutions  git config --global commit.gpgsign true
~/W/G/TalentHub-solutions ❯❯❯ echo "no-tty" >> ~/.gnupg/gpg.conf

5. Point out the pinentry program to gpg-agent.conf:

~/W/G/TalentHub-solutions  touch  ~/.gnupg/gpg-agent.conf
~/W/G/TalentHub-solutions  echo "pinentry-program /usr/local/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf

Now you will be able to commit to your git repository.

An example of how Excel can boost your coding productivity

During my working time in software companies, there are ton of cases which the support of Excel helps alot.
Today for an example.

I have to add rules to validate many fields with the similar name like below:

  • open1post
  • open1person
  • open2corp
  • open2post
  • open2person
  • open3corp
  • …and so on…

I need to create some code lines like below:

  • $val->add(‘open1corp’, $multi_lang_items[‘lbl’][23])
    ->add_rule(‘match_pattern’, ‘/^[0-9]*$/’);
  • $val->add(‘open1post’, $multi_lang_items[‘lbl’][23])
    ->add_rule(‘match_pattern’, ‘/^[0-9]*$/’);
  • $val->add(‘open1person’, $multi_lang_items[‘lbl’][23])
    ->add_rule(‘match_pattern’, ‘/^[0-9]*$/’);
  • $val->add(‘open2corp’, $multi_lang_items[‘lbl’][24])
    ->add_rule(‘match_pattern’, ‘/^[0-9]*$/’);
  • $val->add(‘open2post’, $multi_lang_items[‘lbl’][24])
    ->add_rule(‘match_pattern’, ‘/^[0-9]*$/’);
  • $val->add(‘open2person’, $multi_lang_items[‘lbl’][24])
    ->add_rule(‘match_pattern’, ‘/^[0-9]*$/’);
  • $val->add(‘open3corp’, $multi_lang_items[‘lbl’][25])
    ->add_rule(‘match_pattern’, ‘/^[0-9]*$/’);
  • …and so on…

So, in excel:

  1. First column, I store a list of fields, name it “Form control name”.
  2. Because, a label is provided to 3 fields, for example: “open1corp”, “open1post”, “open1person” use the same lbl 23.

So that, we have to calculate the same number for each open[x][post_fix]. In order to achieve that, I used the magic of mod like below formula.

Note that, 19 is the row number of the first open[x][post_fix] item.

=CONCATENATE("$val->add('",[@[Form control name]],"', $multi_lang_items['lbl'][",ROW()-MOD(ROW()-1,3)+4-2*(FLOOR.MATH((ROW()-19)/3)),"])
 ->add_rule('match_pattern', '/^[0-9]*$/');")

And the result we get:
Excel productivity
That’s it, now we can copy those code to our IDE.

Create a linux shell to wrap files to the corresponding wrapper folder

I have list of around 200 .log files, and I am in need of creating a wrapper for each file.
Laborious buffaloes may have a flow like: Copy file name > Right click and create a folder > Move the file into it, repeat 200 times. Seems ez.
And this case, beside those human-beings, linux shell is also a kind of that buffalo.
Ok let’s go.

What I have:

  • 20161208_access.log
  • 20161209_access.log

What I about to have:

  • 20161208_access\20161208_access.log
  • 20161209_access\20161209_access.log

Step 1:

[ducfilan@localhost]$ cd logs
[ducfilan@localhost logs]$ vi wrapper_creator
# wrapper_creator file.
for full_filename in *log; do # loop through the log files.
 filename="${full_filename%.*}" # get the file name without extension.
 mkdir -p "$filename" # create the folder.
 mv "$full_filename" "$filename" # move the file into it.
done
echo "Done!"

Ok done, save it.

Step 2:

In order to execute it, we need to grant the execute permission.

[ducfilan@localhost]$ chmod +x wrapper_creator

Step 3:

And execute it.

[ducfilan@localhost]$ ./wrapper_creator
Done!

Ok I have what I want.

How to auto compile sass/scss files in Eclipse

First of all, sass/scss compilation needs Ruby to work with.

So, ok, we will install it.

But, we need to use system wide Ruby, ’cause I tried with rvm but there comes some problems:

/usr/bin/env: ruby_executable_hooks: No such file or directory

So if you use rvm, switch it back to:

rvm use system

Now go to:

https://www.ruby-lang.org/en/documentation/installation/

Then to make sure that Ruby is successfully installed:

ruby -v

It should have some information like:

[ducfilan@localhost]$ ruby -v
 ruby 2.1.8p440 (2015-12-16 revision 53160) [x86_64-linux]

Now come to sass:

gem install sass
# su in case of permission errors

Once again to make sure:

sass -v

Some information like this means we’ve successfully installed it:

[ducfilan@localhost]$ sass -v
Sass 3.4.23 (Selective Steve)

Ok, preparation is done. Open your project in Eclipse.

Right click on it > Properties > Builder > New > Choose ‘Program’ then Ok.

2017-01-25_140725

We need to fill out some fields:

  1. Location
    • Get the location of sass using:
      • which sass
  1. Working Directory
    • Relative path to your folder, with ${workspace_loc:/…} as root. Use Browse workspace to make it ez.
  2. Arguments
    • --update ${workspace_loc:/QTEC-Web/public/sass}:${workspace_loc:/QTEC-Web/public/css} --sourcemap=none --style compressed
    • With:
      • –update: Means compiling when your sass file is changed.
      • ${workspace_loc:/QTEC-Web/public/sass}: Your sass folder
      • ${workspace_loc:/QTEC-Web/public/css}: Your output folder
      • –sourcemap=none: No generating .map file
      • –style compressed: Output style

For example in my case:

2017-01-25_141341.png

After that, don’t close the configuration screen.

Switch to Build options tab and check only following files, uncheck all others if they are pre-checked.

  1. Allocate Console
  2. During auto builds

Now you’re done, edit an .scss file and you will see the message of writing .css file in the output screen. If not, you’re doing it wrong.

How to connect to localhost using Postgres Admin (pgadmin) in CentOS

First of all, a recall how to install Postgres and pgAdmin3 in CentOS (CentOS 6.8, Postgres 9.5 in my case):

Postgres:

[ducfilan@localhost]# su

[root@localhost]# wget https://download.postgresql.org/pub/repos/yum/9.5/redhat/rhel-6-x86_64/pgdg-centos95-9.5-3.noarch.rpm

[root@localhost]# rpm -ivh pgdg-centos95-9.5-3.noarch.rpm

[root@localhost]# yum install postgresql95-server postgresql95-devel postgresql95-contrib

[root@localhost]# service postgresql-9.5 initdb

[root@localhost]# service postgresql-9.5 start

[root@localhost]# chkconfig postgresql-9.5 on

And pgAdmin:

yum install pgadmin3_95

To start Postgres Admin:

[root@localhost]# pgadmin3

When you add a server to connect to localhost database, the error message appears:

postgresql The server doesn't accept the current user: The server report
Ident authentication failed
The server doesn't accept the current user: The server reports 

FATAL: Ident authentication failed for user "pgadmin" 
If this message appears, the pg_hba.conf entry found for your 
client / user / database combination is set to "ident" authentication.  
Some distributions, e.g. Debian, have this by default. To perform ident  
based authentication successfully, you need additional setup; see the  
PostgreSQL help for this. For a beginner, it might be more appropriate  
to use a different authentication method; MD5 encrypted passwords are  
a good choice, which can be configured by an entry in pg_hba.conf like  
this: 

host all all 192.168.0.0/24 md5 

This example grants MD5 encrypted password access to all databases to  
all users on the private network 192.168.0.0/24. 
You can use the pg_hba.conf editor that is built into pgAdmin III to  
edit the pg_hba.conf configuration file. After changing pg_hba.conf,  
you need to trigger a server configuration reload using pg_ctl or by  
stopping and restarting the server process. 

Look at the message, it means that ident authentication is not usable here.
We have to edit the pg_hba.conf file. After several researches, I knew the location of pg_hba.conf file, open it up:

[root@localhost]# nano /var/lib/pgsql/9.5/data/pg_hba.conf

You will find some ident here, change it to md5 (username – password authentication)
But…
Dont forget to restart the postgres service:

<[root@localhost]# service postgresql-9.5 restart

Try again, the sky will be brighter.

What needs to consider when sorting arrays in Perl

I ‘ve working with a coding challenge, my solution leads me to sort an array of numbers.

As the Perl variables are scalar, and sorting syntax in Perl is as easy as eating a cookie.

Just:

@sorted = sort @unsorted;

But it’s not promissed the array elements are numbers, so by default, it will be sorted by alphabet order.

This will lead to: 11 < 2

So the result is not what we desire.

If we cannot debug the right case, it will be so frustrated.

Conclusion:

When sorting array of numbers, you have to pass a custom comparison function to Perl’s sort routine, as below:

@sorted = sort { $a <=> $b } @unsorted;