Wednesday, May 11, 2005

Build with ant, open source files in TextPad, jump to lines with compilation errors

I use cygwin and textpad in my day-to-day work, among many other things. To compile my current java project, I use ant. I'm always interested in integrating utilities to make everything more convenient, so this afternoon I set out to create an entry in the textpad "Tools" menu, to run ant and compile my source code.

I found what seemed like useful information here, so I was able to at least run ant from textpad. However, compilation errors would show up in the "Command Results" window, and the part on that web page about being able to click on a compilation error to jump to the offending file and line number was not working for me. I tried messing with the regex and switching my textpad regex type from POSIX to the textpad default type, but I could not get it to work.

So, I went a different route. I decided to attack it from the bash shell angle, by running ant and manipulating the output. What I ended up with is one string of commands that runs ant, then opens all source files with compilation errors into textpad, and jumps to the line numbers that the errors occurred on:

ant 2>/dev/null ¦ grep "\[javac\] [A-Za-z]:" ¦ sed -e "s/^ *\[javac\] \([A-Za-z]:[^:]*\):\([0-9]*\):.*$/\1(\2)/g" > /cygdrive/c/temp/textpadant.txt ; "/cygdrive/c/Program Files/TextPad 4/TextPad.exe" @c:\\temp\\textpadant.txt &

I will probably try to expand on this a little further when I have time, so I can initiate all this from inside textpad, as an entry in the "Tools" menu. It should be pretty easy, but I don't have time to mess with it any more right now. For now, the solution I came up with will already save me some time every day.

-dave

Friday, April 29, 2005

imposing some of my programming style on a whole source tree of files (muahahaha!)

I inherited a project at my current job that had only been worked on by one person before, over a long period of time. I've been refactoring it for quite a while, now, and one thing that I've done a lot of during this is reformat into a style that I'm used to/more comfortable with. I've done this largely with the help of various sets of regular expressions, using either search and replace in TextPad (my text editor of choice) or a combination of find/grep/sed/etc.

Here's one that I did fairly recently, which, while not incredibly useful or complicated, did what I needed it to do. I also had fun figuring out the right expressions, and enforcing my programming style on hundreds of files with one commandline. :)

for f in `find . -name '*.jsp'`; do echo $f; sed -e 's/^\([ \t]\+\)\(.*[^ \t]\+.*\)[ \t]*{$/\1\2\n\1{/g' -e 's/^\([ \t]*\)}[ \t]*\([^ \t]\+.*\)$/\1\}\n\1\2/g' $f >$f.2; diff $f $f.2; mv $f.2 $f; chmod 755 $f; done

I created this in two parts, originally in textpad, then decided I wanted to put them together and run them on all of the JSPs in the source tree. Here are the two parts, as I documented them originally, which should make it easier to understand the final command above:

----
move {'s from ends of code lines to blank lines,
for example:
    try {
would change to:
    try
    {

search for:
^([ \t]*)(.*[^ \t]+.*)\{\n
replace with:
\1\2\n\1{\n

sed -e 's/^\([ \t]\+\)\(.*[^ \t]\+.*\)[ \t]*{$/\1\2\n\1{/g' FileName.jsp
----
move }'s from beginnings of code lines to blank lines,
for example:
    } catch (Exception e)
would change to:
    }
    catch (Exception e)

search for:
^([ \t]*)\}[ \t]*([^ \t]+.*)\n
replace with:
\1\}\n\1\2\n

sed -e 's/^\([ \t]*\)}[ \t]*\([^ \t]\+.*\)$/\1\}\n\1\2/g' FileName.jsp
----

-spugbrap

Thursday, April 28, 2005

remote access to a firewalled machine with ssh port forwarding

At some point last year, I needed to be able to remotely control a computer at work that could not be accessed from the outside world due to a firewall. I already knew the power of ssh port forwarding, and figured there was some way to accomplish what I wanted to do using ssh.

Sure enough, I was able to put together the following two commands, which allowed me to do what I needed to do, with the help of my computer at home (whose firewall I could actually open a port on). I only did it once, just to see if it could really be done, but I did not want to risk getting in trouble for making a hole in the firewall. It was a fun exercise, though, and I wanted to share it with anyone who cares to listen.

The following represent things to modify in the commandlines below, to suit your own needs:

HOME_IP = the ip address of my machine at home
HOME_USER = my username on my machine at home
RESTRICTED_HOSTNAME = the hostname of the machine I'm trying to open up
RESTRICTED_USER = my username on the machine I'm trying to open up

First, I executed this command from the machine I wanted to open up to the outside world:
ssh -g -R 8022:localhost:22 HOME_USER@HOME_IP

This forwards my local port 22 (on the restricted machine) to my home machine's port 8022
-g tells it to allow remote hosts to connect to locally forwarded ports


Next, I executed this command in that ssh session to my home machine that I created with the first command:
ssh -p 8022 -N -f -g -L 15900:RESTRICTED_HOSTNAME:5900 RESTRICTED_USER@localhost

This forwards the VNC port (5900) on the machine I'm trying to open up to port 15900 on my home machine.
-g tells it to allow remote hosts to connect to locally forwarded ports
-N says I just want to make this connection for port forwarding, not to actually execute a command
-f says to put ssh into the background after establishing the connection


Now, from any machine with an internet connection and a VNC client, I can open a VNC connection to HOME_IP:15900, and I will be remotely controlling the restricted machine.

Note that this only requires me to have ports 22 and 15900 open on my firewall at home.%