Posh Git shows the current branch and the state of files in powershell prompt

Posted on

It’s a set of PowerShell scripts that gives Git integration in PowerShell prompt.

https://github.com/dahlbyk/posh-git

The first thing you notice once you install it, is that it can show the current branch and the state of files, additions, modifications, and deletions within.

Another nice feature is tab completion.

For example,

git ch<tab> --> git checkout

You can install it via PsGet

Install-Module posh-git

Node.js의 힘, npm

Posted on Updated on

Node.js, 이제는 모르는 사람이 없는 서버쪽 자바 스크립트 프로그래밍 언어 및 환경.

작년부터 Node.js를 개인 프로젝트에 조금씩 써보다가 이제는 거기에 꽂혀서 모든 개인 프로젝트를 Node.js로 하고 있다. 그런데 계속 쓰다보니, 이 npm이란 놈이 여간 기특하지 않은거다. Node Package Manager, 말 그대로 Node 관련 모든 패키지들이 모인 곳인데, 그야말로 무궁무진한 패키지들이 있다. 전에 Ruby 개발자들과 만나서 얘기할 때, 그 친구들이 농담식으로 “코드짜다는 일의 대부분이 패키지를 찾아서 설치하고 그걸 이용하는 것” 이라고 말하는 걸 들었는데, Node를 쓰면서 정말 실감이 난다. 웹 프로그래밍을 하려면 Express.js를 찾아 설치하고, 각종 미들웨어들을 설치한다. 로깅이 필요하면, bunyan이나 winston을 설치하고, azure-table storage를 설치해서 데이터를 저장하고 (회사 MSDN 계정에서 매달 Azure를 공짜로 쓸 수 있는 금액을 충전해줘서) 등등.

그런데 계속해서 npm에서 이것 저것 찾아서 쓰다보니, 점점 내가 만드느 코드들도 패키지 비슷하게 되어간다. C#에서는 그냥 Helper나 Util 등의 폴더에 넣어 쓰고말 코드를 패키지처럼 만들게 되고, 또 만들다 보면, 이걸 npm에 올려 공유하고 싶어진다. 함수가 어느정도 복잡해지면, 이제 이를 패키지로 만들고 싶어진다. 패키지가 일반적인 추상화 (Abstraction)의 패턴이 된다. 이는 C#으로 코딩할 때는 깨닫지 못하던 패턴이다.

RubyGems와 Ruby가 한 몸 이듯이 npm이 없다면 Node.js 역시 없다는 생각이 든다

The rising tide of shipping glitter bombs

Posted on Updated on

It seems that people are suddenly mad with the sweet revenge of bombing people with glitter. Shipping enemies glitter is becoming world-wide phenomenon. This is the list of web sites that sell glitter, promising to bomb the buyer’s enemy.

The original stunt: http://www.shipyourenemiesglitter.com/

And a whole new industry appeared.

Sacrifice is noble, but what if the cause is not clear?

Posted on Updated on

I saw American Sniper last week. Undoubtedly, it’s a great film to watch and it was heroic for Kyle to guard his fellow soldiers against the attack from the “savages”, yet the film is so dishonest of the history. Kyle sacrificed his life and family for the country, but unfortunately it turned out Iraq wasn’t responsible for 9/11 or any WMD.

american-sniper

from http://www.vox.com/2015/1/22/7859791/american-sniper-iraq

birdman and becoming polyglot

Posted on Updated on

Birdman is an American black comdy that features a faded Hollywood actor famous for his superhero role. While seeing the film, I kind of thought I have something in common with the character. He doesn’t wanted to be labelled as Hollywood superhero junkie, but to be seen as an artist, a Broadway actor.

I like the word, “polyglot programming”. I’m fascinated by people who code in different language on cross-platforms. Though I mostly use C# and .NET framework on windows at work. I strive to be polyglot. Also I want to be seen as a polyglot developer, capable of using multiple sets of language. On my linkedin profile, I proudly wrote that I’ve got skills of F#, javascript (includindg Node.js), Python, and Ruby. I consciously spend time to learn those languages. For my side projects, I use Node.js, express, and angular. I wrote a couple of simple android apps in Java. I spent quite bit of time learning ruby, went through Ruby Koans twice, and did one project in ruby and rails.

However, I often did so, because I loved the glorious title of “polyglot programmer.” I had hope that one day I will be like a magician with spinning dishes on poles, using different languages and platforms skilfully.

At the end of the film, the actor finally accepts that he is a Birdman. Accepting the identity frees him. Working hard to be polyglot for the sake of its glory was tiring, I confess. It’s like you get exhausted if you try to be cool or impressive all the time. Like the birdman, I need to accept that I might not be polyglot, if being polyglot has minimum requirements, like you have to know at least 4 different major languages on different platforms. If the word, “polyglot”, enslaves you, I must fell. I don’t have to cool or awesome. I just want to be a programmer, who is good at what he’s doing. I don’t have to a guru. I’m happy to be a journeyman

A good developer would eventually be polyglot. You need a right tool for the job, and if you know more tools, and then you can do the job much better more effectively, For example,

“Using Java to solve a clearly functional problem, when Clojure would be simpler. Or building a Rails app when your users want the kind of fluid interface a single page JavaScript framework can give them.”(http://thoughtworks.github.io/p2/issue08/hire-polyglot/)

So, to be polyglot for the sake of being polyglot doesn’t give you much benefit. It may make you rather arrogant. Just try to know different languages, tools, and environments enough that you can decide which would be the best tool for the job you have now. Use the language and tool for job and deepen your understanding and knowledge along. Don’t be afraid of using different toolsets. Then along the journey, at some point, you will find you have become truly polyglot.

Being polyglot can’t be the purpose. It’s the end result you become, when you try to be good at your job.

Opening an office document from Code

Posted on Updated on

It’s a simple job at a glance, and it should be. But we had a bug with that feature. You open a document on Huddle and it should be opened in an application that is associated with the file, for example, MS Word, if it is word document. You can do that if you have installed Huddle for Windows, which is a desktop application for Huddle.

It worked. Yet, customers often complained that the document opened in the background. When we open any document, it opens in the foreground on dev machine. so you are very tempted to say “it works on my machine!”

This is the code that opens the document. No magic, just simple process.Start()

var process = new Process
{
    StartInfo =
    {
        FileName = path,
        CreateNoWindow = true,
        UseShellExecute = true,
        LoadUserProfile = false,
        ErrorDialog = false,
        Verb = &amp;quot;open&amp;quot;
    },
    EnableRaisingEvents = true
};

process.Start();

The application that’s launched is supposed to be active in the foreground, and I’ve got that behaviour on my dev machine. Yet on non-dev machines, especially our product manager’s laptop, the document opened consistently in the background, especially behind Chrome browser when it was maximised.

So, we made a win api call to set it in the foreground.


[DllImport(&amp;quot;User32.dll&amp;quot;)]
private static extern Int32 SetForegroundWindow(IntPtr hWnd);

...
var handle = process.MainWindowHandle
SetForegroundWindow(handle);

Now it was working on one of my VMs (Virtual Machines) and I thought it should be working. However it was still failing on a laptop.
Why? A little more investigation reveals that process.MainWindowHandle doesn’t return the handle immediately. When MS Word splash screen pops up, the process to MS Word exists, but the main window is not fully loaded yet, so the handle was IntPtr.Zero. You have to wait until MainWindowHandle is populated, and it takes 3 to 6 seconds and up to 10 seconds, if you open Word first time on the day.

So, the last missing bit was waiting for the handle.

int threshold = 0;
while (process.MainWindowHandle == IntPtr.Zero)
{
    if (threshold &amp;gt; 100) break; 

    _log.DebugFormat(&amp;quot;Waiting for the document is fully loaded... - {0}&amp;quot;, threshold);
    Thread.Sleep(TimeSpan.FromMilliseconds(100));
    threshold++;
}

_log.DebugFormat(&amp;quot;Bringing the application (handle: {0}) to the front&amp;quot;, process.MainWindowHandle);
SetForegroundWindow(handle);

And happy developers and customers, finally

Update as of Fri.19/12/2014

The journey didn’t end there unfortunately. The issue was deeper than I previously assumed.

Opening documents in the background had a mixture of causes.

  1. If there’s any Excel document, Excel opens all subsequent documents are in the same instance, just flashing the icon since Windows 7
  2. Event SetForegroundWindow doesn’t work, if the process that’s running the command is not in the foreground. So you have to set your process foreground first, if you want to set any other process you spawn foreground.

To sort them out, I took a different approach. First, I gave up the simple and elegant Process.Start() with UseShellExecute option. Instead, I query windows registry and find the associated application with the file extension.

[Flags]
public enum AssocF : uint
{
    None = 0,
    Init_NoRemapCLSID = 0x1,
    Init_ByExeName = 0x2,
    Open_ByExeName = 0x2,
    Init_DefaultToStar = 0x4,
    Init_DefaultToFolder = 0x8,
    NoUserSettings = 0x10,
    NoTruncate = 0x20,
    Verify = 0x40,
    RemapRunDll = 0x80,
    NoFixUps = 0x100,
    IgnoreBaseClass = 0x200,
    Init_IgnoreUnknown = 0x400,
    Init_FixedProgId = 0x800,
    IsProtocol = 0x1000,
    InitForFile = 0x2000,
}

public enum AssocStr
{
    Command = 1,
    Executable,
    FriendlyDocName,
    FriendlyAppName,
    NoOpen,
    ShellNewValue,
    DDECommand,
    DDEIfExec,
    DDEApplication,
    DDETopic,
    InfoTip,
    QuickTip,
    TileInfo,
    ContentType,
    DefaultIcon,
    ShellExtension,
    DropTarget,
    DelegateExecute,
    SupportedUriProtocols,
    Max,
}

// from http://www.pinvoke.net/default.aspx/shlwapi/AssocQueryString.html
[DllImport(&quot;Shlwapi.dll&quot;, CharSet = CharSet.Unicode)]
static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra, [Out] StringBuilder pszOut, ref uint pcchOut);

public string GetApplicationPath(string extension)
{
    const int S_OK = 0;
    const int S_FALSE = 1;

    uint length = 0;
    uint ret = AssocQueryString(AssocF.None, AssocStr.Executable, extension, null, null, 
         ref length);
    if (ret != S_FALSE)
    {
        throw new InvalidOperationException(&quot;Could not determine associated string&quot;);
    }

    var sb = new StringBuilder((int)length); 
    ret = AssocQueryString(AssocF.None, AssocStr.Executable, extension, null, 
          sb, ref length);
    if (ret != S_OK)
    {
        throw new InvalidOperationException(&quot;Could not determine associated string&quot;);
    }

    return sb.ToString();
}

You get the application and run it with Process.Start. You pass the file name as argument. In case of office documents, you can add “/x” switch, so that it creates a new instance all the time, not reusing the existing one.

var extension = Path.GetExtension(path);
try
{
    string application = _windowManager.GetApplicationPath(extension);
    var process = new Process
    {
        StartInfo =
        {
            FileName = application,
            Arguments = GetArguments(application, path),
            WindowStyle = ProcessWindowStyle.Normal
        }
    };

    _log.Debug(string.Format(&quot;Starting {0}&quot;, path));

    var huddleWinHandle = Process.GetCurrentProcess().MainWindowHandle;
    _windowManager.MinimiseWindow(huddleWinHandle);
    _windowManager.BringToFront(huddleWinHandle);
    process.Start();
}
...

private string GetArguments(string application, string path)
{
    if (application.ToLower().Contains(&quot;microsoft&quot;))
    {
        return &quot;/x \&quot;&quot; + path + &quot;\&quot;&quot;;
    }

    return &quot;\&quot;&quot; + path + &quot;\&quot;&quot;;
}

Why do you minimise the window of the current process before setting it foreground? For some reason, SetForegroundWindow didn’t work consistently, if you process main window is in normal mode, hidden behind other windows. When it was minimised programatically and set to foreground, it was always brought to the front.

So, to summarise how to open documents in the foreground,

  1. Set your application to the foreground first by minimising the window and then bringing it to the front
  2. Find the associated application with the file and start it as new instance.
  3. Before you start another process, make sure your process in the foreground first. Only foreground process can make an attached process run in the foreground. There are more rules in setting a process in the foreground.

SRP (Single Responsibility) and encapsulation

Posted on Updated on

Single Responsibility is one of key principles in writing good code, I believe. So when you change a method or a class, you should have only one reason to change it. But at the same time, you don’t want to reveal too much details. You want to encapsulate the internals and nicely abstract your business logic.

This morning, I had a brief chat with a colleague about method encapsulation. I was saying the method was hiding too much and he called it encapsulation. This kind of chat happens often among developers. We didn’t come to conclusion and I thought about it afterward. This is my thought.

A method should do only one thing

For example,

  • contentStore.remove(doc)
  • metaDataStore.remove(doc)
  • raise(new UiDocumentDeletedEvent(doc))

The 3 lines of code are written separately and each call does only one thing. In my opinion, contentStore.remove() method shouldn’t hide the following two call inside its method call. contentStore.remove() should do only one thing it’s good at, which is removing the document from ContentStore.

Encapsulation

However, what if the 3 operations happen together very often. if it does, I think it’s the time to introduce a facade object (facade pattern) or a command and command handler. The command handler can have those 3 objects as dependencies and call them in sequence.

public class DocumentRemovedCommandHandler : IHandle<DocumentRemovedCommand> 
{
    ...
    public void Handle(DocumentRemovedCommand command)
    {
        _contentStore.remove(doc);
        _metaDataStore.remove(doc);
        _event.raise(new UiDocumentDeletedEvent(doc));
    }
}

So, in conclusion, use facade or command, if you want to perform a group of operations. Otherwise, do one thing at a time, well.