PowerShell to the people

Windows PowerShell was created by Microsoft to be used for administration of Windows, Exchange, SQL Server and so on. But it is also a replacement for the old Command Prompt. With it the Windows command line goes from something vastly inferior to *nix shells to something that in many ways surpasses it. So, if you haven’t already, set aside four hours and learn the basics.

PowerShell is built on and tightly integrated with .NET. Functionality in PowerShell is generally provided by special .NET classes called cmdlets (a Microsoft madeuppy word). You also have access to .NET’s whole base class library. Although the syntax is a bit different than you may be used to.

[String]::Format("{0:#.##}", [Math]::PI * 2)

(Get-Date).ToString("dddd", [Globalization.CultureInfo]::InvariantCulture)

$web = New-Object System.Net.WebClient
$web.DownloadString("https://blog.gieron.info/robots.txt")

Customize your shell

The default console window for PowerShell is the same as for cmd.exe. It’s not very impressive. You can change the window size and the colors but that’s about it. There is however a third party alternative called Console which has some nice features such as transparency and tabs.

An example of PowerShell used with Console

PowerShell executes a script file when it starts where you can put anything you want to run whenever you open a new shell. The path to this file is contained in the variable $profile. Here is mine.

$host.UI.RawUI.ForegroundColor = "White"

function Prompt
{
  $path = $pwd -Replace "^Microsoft\.PowerShell\.Core\\FileSystem\:\:", ""
  $shortpath = $path
  $shortpath = $shortpath -Replace "^(.:\\)....+(.{20})$", "`$1...`$2"
  $shortpath = $shortpath -Replace "^(....:\\)....+(.{17})$", "`$1...`$2"
  $shortpath = $shortpath -Replace "^....+(.{23})$", "...`$1"

  Write-Host -ForegroundColor Green -NoNewLine $shortpath
  Write-Host -ForegroundColor DarkGreen -NoNewLine '>'

  $host.UI.RawUI.WindowTitle = $path
  return " "
}
Advertisements

Mercurial 2.2.1 on Windows Server 2003 x64

This is a quick run-through of how I installed Mercurial 2.2.1 on Windows Server 2003 64-bit edition and used IIS 6.0 to serve the repositories.

Install Python 2.6.6 with Windows X86-64 MSI Installer (2.6.6) found here.

Install Mercurial 2.2.1 with Mercurial 2.2.1 Python 2.6 package – x64 Windows and Mercurial 2.2.1 MSI installer – x64 Windows, both found here. The former of these installs Mercurial native for Python which we need for the web. The other one installs the command line tools necessary for managing repositories.

Create a directory to hold the repositories. I chose C:\Repositories. Create another directory to hold the files IIS will use to serve the repositories. This should be separate from the repositories themselves. I chose C:\Mercurial\Website. Create a new file in that directory named hgweb.cgi with the following content:

#!python
config = "C:\\Mercurial\\Website\\hgweb.config"
import cgitb; cgitb.enable()

from mercurial import demandimport; demandimport.enable()
from mercurial.hgweb import hgweb, wsgicgi
application = hgweb(config)
wsgicgi.launch(application)

Create another file in the same directory called hgweb.config with the following content:

[paths]
Test = C:\Repositories\Test
Main = C:\Repositories\Main
[web]
style = monoblue

Adjust the paths and names for your repositories. You should also create hgrc files within each repository to configure access. You can chose another style if you want to.

IIS Configuration

Now that all files are in place it is time to set up IIS with the help of the IIS Manager. Create a new virtual directory under the default web site. Call it hg and point it to the directory with the hgweb files (C:\Mercurial\Website in my case).

Open the properties for the new virtual directory and go to the Virtual Directory tab. It should look like this:

Click the Configuration button then click Add in the new window. Enter the following:

Executable: "C:\Program Files\Python\python.exe" -u "%s %s"
Extension: .cgi

Click OK on all windows. Back in the IIS Manager right click Web Service Extension and add a new web service extension. Give the extension the name Python and add the following as required files:

C:\Program Files\Python\python.exe
C:\Program Files\Python\python.exe -u "%s %s"

You should now be able to browse the repositories on http://servername/hg/hgweb.cgi and be able to clone the repositories from http://servername/hg/hgweb.cgi/Test (for example).

Visual Studio LightSwitch

LightSwitch is a new development tool from Microsoft which lets you create data-centric applications by writing little or no code. It is built on .NET, Silverlight and SQL Server. The result can be deployed both to the web and as a desktop application.

For an example we are going to create a very simple to do list. First download and install LightSwitch, start it and create a new project. Then we are asked if we want to create a new table or use an existing data source. We want to do the former.

Tasks table

In our application a task has a description and a Boolean flag that tells whether the task has been done. To be able to view and edit our tasks we need to add a screen to our application.

Create new screen

Right click Screens in the solution explorer to add a new screen. We want to use an editable grid screen. We must also select which data it should use and give it a name.

To do list application

That is actually all that is needed. If we run the application now we get a list where we can create new tasks, mark them as done and save them for later.

To do list screen

Let us make it a bit more interesting by only showing tasks that hasn’t been done yet. We do this by clicking Edit Query.

Edit query

While we’re at it we can also tell it to sort the tasks. Now the application will only show uncompleted tasks. But we have to manually refresh after we save for it to update properly. We can fix that. Right click on Save on the right and select Edit Saved Code.

namespace LightSwitchApplication
{
    public partial class Todo
    {
        partial void Todo_Saved()
        {
            Refresh();
        }
    }
}

This code refreshes the screen after the data has been saved. Now the application works like we would expect.

The application can now be published. If you publish it as a desktop application you also need to install an SQL server and create the tables on the target machine. In a practical situation you would probably want to connect to a common database.

Git and Mercurial side by side

Though many sources describe distributed version control systems as having no central storage the truth is that most projects do have a central repository. The difference compared to a traditional version control system like Subversion or CVS is that you also have a local repository and commits are done in two stages. First you commit your changes to your local repository, then you push those changes to the central repository.

The two biggest distributed version control systems today are Git and Mercurial. I’m going to describe them here by using them in a short test and comparing them side by side. The command line command for Mercurial is hg, from the chemical symbol for mercury.

git clone https://Gieron:Password   hg clone https://Gieron:Password
      @github.com/Gieron/test.git         @bitbucket.org/Gieron/test
cd test                             cd test

For this test I have created accounts on GitHub and BitBucket. These sites offer free hosting for software projects that use Git and Mercurial respectively.

When you start working with an existing repository you clone the entire repository to your computer. The resulting directory holds both your local repository and your working copy.

(create initial files)              (create initial files)
git add *                           hg addremove
                                     adding index.html
                                     adding images/logo.png
git commit -m "First commit"        hg commit -m "First commit"
 create index.html
 create images/logo.png
git push origin master              hg push

Here we add some files to the project. One of the files is in a different directory. Git and Mercurial track directories implicitly. By that I mean they only remember directories as file paths. This has two consequences when compared to Subversion. First you can’t add empty directories. Secondly if you commit from a sub directory you will commit the entire project.

After the files are added we commit them to the local repository and then push them to the central repository. When making the first push in Git I had to tell it which remote repository and which branch I wanted to push to.

git branch stable                   hg branch stable
git checkout stable
                                    hg commit -m "Stable branch"
git push origin stable              hg push --new-branch
(deploy code)                       (deploy code)
git checkout master                 hg update default
git branch                          hg summary

In Subversion I have been used to having a stable branch for code that I want to deploy so I can keep it separate from the latest development. I think this should still be a valid way to handle it. So we create a stable branch here and make sure we push it to the central repository as well.

One small difference here is that Mercurial automatically put us in the new branch while Git does not. In Mercurial we have to commit the new branch to our local repository. Git doesn’t see branches this way, so there is nothing to commit. The last command is just a convenient way to check which branch we are currently in as it can be easy to get lost.

(create/remove/change files)        (create/remove/change files)
git status                          hg status
 Changes not staged for commit:      M index.html
  modified: index.html               ! images\logo.png
  deleted:  images/logo.png          ? images\newlogo.png
 Untracked files:
  images/newlogo.png
                                    hg addremove
git rm images/logo.png               removing images/logo.png
git add images\newlogo.png           adding images/newlogo.png
git commit -a -m "Some changes"     hg commit -m "Some changes"
git push                            hg push

Back in the main branch (master in Git, default in Mercurial) we make some file changes that we want to commit. The status command is an easy way to see what changes are available.

Mercurial has a nice addremove command that automatically adds any untracked files and removes all missing files. In Git we have to do this manually. But here is also a very odd feature of Git, it will not automatically send changed files when we commit even if they are tracked. You have to either add them explicitly with the add command or you can give the -a argument to commit which will add all modified tracked files to the commit.

Finally we push the changes. If there are other people working on the project and you want to have their changes you use the pull command.

git checkout stable                 hg update stable
git merge master                    hg merge default
                                    hg commit -m "Merged to stable"
git push                            hg push

Finally we merge the changes to our stable branch. Again Mercurial requires us to commit the merged changes while Git has a different way of thinking.

So which one is better?

Oh look, a pony. But seriously, I wont touch that question. But I can tell you what I perceive to be different.

Mercurial

  • has better Windows support
  • has an easier learning curve

Git

  • is more widely used
  • is more flexible