As stated
on my about page, I work as .NET developer in a company producing business
software. I believe a traditional C# developer spends most of their time in a
feature-rich IDE, which is Microsoft Visual Studio in most cases. However,
during recent months I’ve been seeing myself gradually moving some of my
activities to the command line, where in fact I can achieve a great deal of my
goals at much lower cost than in a modern IDE.
My first
conscious moves toward command line took place more than a year ago when I did
Java development on my previous job. Like the .NET world has its most popular
IDE, Java world has its own guys – for instance, Eclipse. Due to the simplicity of things that I
built back then I haven’t faced most of the problems, which Eclipse-based
developers lament about, though at some point it turned out that I actually
want my job to be done a bit faster and a little different than the IDE allowed
to. My primary concern was the need to quickly package a couple of JARs, obfuscate them and put the result
into an appropriate place. It was easy to achieve something like this through
doing all three steps separately: open project in Eclipse and assemble a JAR, launch obfuscator tool and feed the
archive to it, put the result wherever it has to go – nothing complex. On
the other hand, both launching Eclipse and the obfuscator took some time, with
the additional seconds being spent on surfing through the Eclipse menus as well
as locating the desired configuration files for the obfuscator, so after
running the scenario several times manually I had no choice except for forming
a strong desire to automate it. Because I also wanted to understand what
Eclipse does under the hood when I ask it to compile the project I got some ant manuals and started automating everything away. In a couple of days I had
what I wanted: I could open Powershell, type in ant ship and it would quickly
do all the above steps on its own, so that I have only to decide what should be
done with the obfuscated JARs. The
economy of time that it awarded amazed me so strong, that I even went further
and included into the build-file such targets as test and testncommit so
that I could not only run tests from the shell, but also check changes into
Mercurial in case the tests pass – sort of continuous integration on a single-man project. What made me stick with the command line then was the fact that it
could save me from navigating through multiple IDE’s windows in addition to
merely running things a bit faster.
Next time I
searched for help from the shell during the work on my diploma project. At
some stage of a major refactoring I still had a dozen or so very long and slow
tests for fat components, which I was going to replace later. Since these classes
were not touched during the most days until the time has come to deal with
them, there was no reason to waste time on their tests during each run.
However, it turned out that one cannot simply ask Visual
Studio 2012 tests runner to ignore a couple of TestClasses or TestMethods. In addition to
this, the IDE didn’t always successfully discover all the tests upon
rebuilding. These little issues made me search for better options and thus find
the vstest.console.exe tool, which simply runs the tests from command line. Not
surprisingly, it allows to filter the tests being run, for example, by test
classes names – that was precisely what I wanted at that moment. A
nice thing to mention is that while the command required to run vstest utility
with certain tests library and filters is quite long and awkward, most shells,
including the PowerShell, allow one to set up different aliases to save some
typing, so running tests becomes easier and faster than from the IDE – in
addition to providing broader functionality.
Maybe the
strongest push in the direction of command line I got from Visual Studio 2012
for C++, when I was experimenting with Cinder graphics library. Here the
blocker was the environment’s speed: VS did everything deadly slow – sometimes
so slow, that it was literally impossible to put in a line of code. I spent
some time on tuning precompiled headers, which helped with compile time and
even seemed to improve the situation in editor, still the state of affairs remained
awful. What made me finally close Visual Studio and turn to compiling like
msbuild.exe MyProject.vcxproj was the fact that in an attempt to increase the
speed of IDE and fight the horrible lags I had turned off IntelliSense. While
it didn’t help much with the original goal it made me ask myself why do I want
to stick with the environment if I get no assistance from it? With quite modest support
of C++ in the IDE part of Visual Studio (or without it after disabling
IntelliSense) I merely could not find a reason to stay in the slow environment
when I could switch to the Sublime + PowerShell combination boosting things
considerably. I acknowledge that my Acer Aspire P3 slate with i5
processor is not a powerful machine, while C++ is more difficult to handle than,
say, C# with which I did not face such awful quirks – I
can even assume that it would be faster should I use a Professional version of
Visual Studio instead of the Express one. Nevertheless, I can’t believe that it
is so bad that not being able to enter a line of code in the editor for 5
minutes (let alone the timeframes when it builds the project) is considered OK.
On the other side, once you turn to the shell, you are able to get binaries in
a matter of several seconds after typing in the msbuild.exe MyProject.vcxproj command. In case you change the contents of the precompiled headers, you’ll
have to wait a bit more, but at the same time you are not blocked by the build
process and it won’t prevent you from looking through your files or switching to
the browser. In contrast, if you build from Visual Studio, the only option you have is
to get some coffee and take a walk, because it somehow manages to slow down the
entire system significantly. This is another crucial characteristic of the command
line tools – they tend to do precisely what you ask for, while the complex and
shiny IDEs in their pursuit for the users’ satisfaction seem to be doing lots of
stuff behind the curtains even when you don’t ask for it. Furthermore, since
IDE has this beautiful and handy user interface, it also has a great option of
doing some hard work on the UI thread, thus making user face unresponsive
windows and feel frustrated, because their own tool stands in their way to
getting the job done.
Another
area where I quite often use shell-based tools instead of IDE functionality is
talking to TFS. One particular example is checking out a file for edit. When
the desired file belongs to a solution you work on, the task is pretty easy to
accomplish in Visual Studio – you just locate it in the Solution Explorer and chose check out in its context menu. The situation, however, gets a bit worse if
you want to edit a file, which is not included into any solution at all – just
a file in the repository. In this case you have to open the Source Control
Explorer thing, navigate it to the desired file (as far as I remember, unlike
Solution Explorer it has no handy Search function) and check it out through the
context menu – that is in fact a bit too slow because you have to switch to a certain
window and do some folders joggling there. Does command line have something on
offer to make the process easier? If you are used to navigating the folder
trees like ‘first 2 letters of the desired folder – TAB, … ‘ then absolutely
yes, because all you have to do to check-out a file through the command line is
type tf checkout path/to/your/file.extension. Although, this is not that
significant problem of the IDE and, in fact, I can hardly imagine the way it
could have been done better, there are other tasks where Visual Studio clearly
sucks in terms of working with version control – most notably, merging.
Since we
support several versions of our product, merge is frequently used on a
changeset basis, where you fixed a bug in one version and want to merge the fix
into another one. What you have to do to accomplish this in Visual Studio is going to cause some pain, because before letting you pick a changeset the IDE will
first ask the server for the entire list of those available for merging between the
selected branches (or locations inside them). Moreover, in my experience the
process of assembling this list sometimes takes up to a minute and in case there
exist broken changesets it may finish with a failure message not letting you
merge anything. Now, let me ask you a question: why would one want such a list
of merge candidates in case they’ve just checked-in the changeset, which they
want to merge and know its number? Why couldn’t there be a Merge button in
the Changeset Details window in Visual Studio? I don’t know the answer to the
second question, but I am pretty sure about the first one – I don’t need this
list at all, because I can go and type something like tf merge 4_10 5_00
/version:C159001~C159001 /recursive in the shell and it will instantly merge
the changeset 159001 from branch 4_10 to branch 5_00 if that is possible.
Certainly, this example does not serve to prove that command line is vastly
more powerful than IDEs – instead it just highlights the fact that there are
ways to go in making the developers’ tools better and sometimes one doesn’t have to
go very far to introduce a major improvement.
Overall, my
programming activities, even those started in powerful modern IDEs like
Microsoft Visual Studio, sooner or later led me to doing at least a portion of
work in command line. While there were always serious reasons for switching
from the fancy windows of the former to the awkward, 80s-style text-based
environment of the latter, I still don’t believe that this is a sentence to the
IDEs and their developers. Instead, I think programming environments are
just in the process of becoming better and easier to use tools and sometime
later, particularly when the human-computer interaction technologies will
afford that, IDEs will give developers as much power and freedom as shells do
for several decades already. Still, currently command line offers significant
advantages and here are just some of them:
- Shell is a lot faster;
- It’s more controllable and does precisely what you ask for, leaving out a lot of yak shaving;
- In some sense it is easier to navigate;
- Shell also serves as an entry point to a great deal of things, including your text editors, compilers, diff tools, revision control systems, testing frameworks and whatnot;
- It allows to set up and hold a piece of context through the use of aliases, functions and variables, which also means that shell is quite customizable;
- Command line keeps your fingers at the keyboard, which is especially important when coding – even the numerous hotkeys in an IDE can hardly compensate for this;
- And finally, yes, shell gives one a feeling of being a hacker in one of those legendary movies from 90s.
What makes
you trade a comfortable IDE for a good old command line? Are there any
particular tasks that you can’t accomplish in the modern environment, but which
are crazy simple to do in the shell? Or maybe you never had to leave the IDE
because it satisfies all your needs and never stands between you and your
goals? Please, share your opinion!