Following Ayende's post on Patch management approaches using centralized SCM, here are how I would have dealt with the 4 issues that he brings up, using a Decentralised SCM.
I use git, so I'll use git terms here. I guess it's quite similar for other DSCM systems.
Note that I haven't used patches on git development as until now all of my git work was on repositories I had write access to, However the principals are the same (i.e. - all of the tree is local to my machine, thus I can reach any point in the history locally).
First I'll clone the hosted repository to my local machine.
So, using a DSCM, I can work locally with the benefits of a SCM, have as many branches/features as I want. the whole tree is stored locally, and its blazing fast to switch branches, so I can easily work on every aspect I want, and easily create a patch from every node in the history tree, to send to the project owners.
The tools (various small helper libraries) are now under http://svn.castleproject.org:8080/svn/castlecontrib/Tools/
what's in there:
I've been asked about it several times lately, so I'll just put here an oldie that I've been using for a few years now untouched:
1: // MIT license
2: // Copyright 2005-2008 Ken Egozi
3: //
4: // Permission is hereby granted, free of charge, to any person obtaining a copy
5: // of this software and associated documentation files (the "Software"), to deal
6: // in the Software without restriction, including without limitation the rights
7: // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8: // copies of the Software, and to permit persons to whom the Software is
9: // furnished to do so, subject to the following conditions:
10: //
11: // The above copyright notice and this permission notice shall be included in
12: // all copies or substantial portions of the Software.
13: //
14: // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15: // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16: // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17: // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18: // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19: // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20: // THE SOFTWARE.
21:
22: using System;
23: using System.Collections.Generic;
24: using System.Text;
25: using System.Security.Cryptography;
26: using System.Collections;
27:
28: namespace KenEgozi.CryptographicServices
29: {
30: public static class Hashing
31: {
32: private static Hashtable hashAlgorithms = Hashtable.Synchronized(new Hashtable());
33:
34: /// <summary>
35: /// Hashing a given string with SHA2.
36: /// </summary>
37: /// <param name="data">Data to hash</param>
38: /// <returns>Hashed data</returns>
39: public static string HashData(string data)
40: {
41: return HashData(data, HashType.SHA256);
42: }
43:
44: /// <summary>
45: /// Hashing a given string with any of the supported hash algorithms.
46: /// </summary>
47: /// <param name="data">Data to hash</param>
48: /// <param name="hashType">Hashing algorithm to use</param>
49: /// <returns>Hashed data</returns>
50: public static string HashData(string data, HashType hashType)
51: {
52: HashAlgorithm hash = GetHash(hashType);
53: byte[] bytes = (new UnicodeEncoding()).GetBytes(data);
54: byte[] hashed = hash.ComputeHash(bytes);
55: StringBuilder sb = new StringBuilder(64);
56: foreach (byte b in hashed)
57: sb.AppendFormat("{0:x2}", b);
58: return sb.ToString();
59: }
60:
61: private static HashAlgorithm GetHash(HashType hashType)
62: {
63: if (!hashAlgorithms.ContainsKey(hashType))
64: hashAlgorithms.Add(hashType, CreateaHashAlgorithm(hashType));
65: return hashAlgorithms[hashType] as HashAlgorithm;
66: }
67:
68: private static HashAlgorithm CreateaHashAlgorithm(HashType hashType)
69: {
70: switch (hashType)
71: {
72: case HashType.MD5:
73: return new MD5CryptoServiceProvider();
74: case HashType.SHA1:
75: return new SHA1Managed();
76: case HashType.SHA256:
77: return new SHA256Managed();
78: case HashType.SHA384:
79: return new SHA384Managed();
80: case HashType.SHA512:
81: return new SHA512Managed();
82: default:
83: throw new NotImplementedException();
84: }
85: }
86: }
87:
88: public enum HashType
89: {
90: MD5,
91: SHA1,
92: SHA256,
93: SHA384,
94: SHA512
95: }
96: }
Not beautiful, however useful.
You can download this file from here (just remove the .txt - the server doesn't serve .cs files directly)
btw, the colouring of the source was made with the help of http://www.manoli.net/csharpformat/, even though I had to do some manual tweaking to make it work with this blog. If colours of reserved words, comments etc. do not appear, then please refresh your browser's cache to get the updated css
I really don't need to add anything, right?
Installed it myself today. Appear to be a bit faster, and to eat up less memory.
The Google Toolbar and FireFTP were updated automatically.
I needed to manually re-install FireBug and IE-Tab
btw, does anybody know where did the Back and Forward buttons has gone to? Im using the keyboard usually, but sometimes (especially during in-office-lunch-time) I need to click the Back thing with the mouse
UPDATE: it appear that as part of the upgrade, FF3 has inherited my customised toolbars and that's why it was looking weird. So I right-clicked on the toolbar -> customise, the clicked "Restore Default Set". All the buttons came back, then I rearranged the toolbar to my liking.
Following a question from NHibernate's users list:
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<log4net>
<appender name="rollingFile"
type="log4net.Appender.RollingFileAppender,log4net" >
<param name="File" value="log.txt" />
<param name="AppendToFile" value="true" />
<param name="DatePattern" value="yyyy.MM.dd" />
<layout type="log4net.Layout.PatternLayout,log4net">
<conversionPattern value="%d %p %m%n" />
</layout>
</appender>
<logger name="NHibernate.SQL">
<level value="ALL" />
<appender-ref ref="rollingFile" />
</logger>
</log4net>
and configuring your application to use Log4Net (if you hadn't done that anyway):
log4net.Config.XmlConfigurator.Configure();
If you wan't to know more about log4net and it's configuration options - look here or use your favorite search engine.
From the website:
Current version includes following features:
The coolest thing is the ability to spell check identifiers. I'd love it.
It's at http://www.agentsmithplugin.com/ and I found out about it on Castle's dev list (thx Victor)
As I'm trying to avoid xml files as much as possible, when I do find the need to xpath, I always need to refresh my memory on the matter.
Today I've been working with kml files, and the need for some simple xpath queries came up, forcing me to do some trial-and-error in an area I don't really like ...
Next time I'll have Visual XPath to help me with that.
the new stuff:
Examples:
Reusing clauses:
FromClause from = new FromClause(SQL.Blogs);
WhereClause where = new WhereClause(SQL.Blogs.Id == 2);
SQLQuery q1 = SQLQuery
.Select(SQL.Blogs.Id)
.From(from)
.Where(where);
SQLQuery q2 = SQLQuery
.Select(SQL.Blogs.Name)
.From(from)
.Where(where);
Console.WriteLine(q1);
Console.WriteLine(q2);
makes
SELECT
[dbo].[Blogs].[Id]
FROM
[dbo].[Blogs]
WHERE
([dbo].[Blogs].[Id] = 2)
SELECT
[dbo].[Blogs].[Name]
FROM
[dbo].[Blogs]
WHERE
([dbo].[Blogs].[Id] = 2)
Operators:
SQLQuery q1 = SQLQuery
.Select(SQL.Blogs.Id)
.From(SQL.Blogs)
.Where(SQL.Blogs.Id > 2 || SQL.Blogs.Name == "Ken");
Console.WriteLine(q1);
makes
SELECT
[dbo].[Blogs].[Id]
FROM
[dbo].[Blogs]
WHERE
(([dbo].[Blogs].[Id] > 2) OR ([dbo].[Blogs].[Name] = N'Ken'))
OrderBy Clause:
SQLQuery q = SQLQuery
.Select(SQL.Blogs.Id)
.From(SQL.Blogs)
.Where(SQL.Blogs.Id > 2)
.OrderBy(Order.By(SQL.Blogs.Id), Order.By(SQL.Blogs.Name).Desc);
Console.WriteLine(q);
makes
SELECT
[dbo].[Blogs].[Id]
FROM
[dbo].[Blogs]
WHERE
([dbo].[Blogs].[Id] > 2)
ORDER BY
[dbo].[Blogs].[Id],
[dbo].[Blogs].[Name] DESC
Didn't have time to upload a binary, but you can simply grab the source and build yourself. it has absolutely no dependencies but .NET 2.0
Where from?
http://svn.castleproject.org:8080/svn/castlecontrib/Castle.Tools.SQLQueryGenerator/trunk/
UPDATE (22/06/2008):
The source has slightly moved (to a sub folder):
http://svn.castleproject.org:8080/svn/castlecontrib/Tools/Castle.Tools.SQLQueryGenerator/
A tool that generates a strongly typed representation of a relational database, to be used for generating SQL queries in a type-safe fashion, with the aid of intellisense.
UPDATE (22/06/2008):
The source has slightly moved (to a sub folder):
http://svn.castleproject.org:8080/svn/castlecontrib/Tools/Castle.Tools.SQLQueryGenerator/
Usage sample (from Examples.cs in the test project:
SQLQuery q = SQLQuery
.Select(SQL.Blogs.Id, SQL.Blogs.Name)
.From(SQL.Blogs);
Console.WriteLine(q);
Would print out:
SELECT
[dbo].[Blogs].[Id],
[dbo].[Blogs].[Name]
FROM
[dbo].[Blogs]
Not impressed? Well,
dbo_ForumMessages Message = SQL.ForumMessages.As("Message");
dbo_ForumMessages Parent = SQL.ForumMessages.As("Parent");
SQLQuery q = SQLQuery
.Select(Message.Id, Message.ParentId, Message.Content)
.From(Message)
.Join(Parent, Message.ParentId == Parent.Id);
Console.WriteLine(q);
Will spit out
SELECT
[Message].[Id],
[Message].[ParentId],
[Message].[Content]
FROM
[dbo].[ForumMessages] AS [Message]
JOIN [dbo].[ForumMessages] AS [Parent] ON
([Message].[ParentId] = [Parent].[Id])
Need parameters?
Parameter<int> blogId = new Parameter<int>("BlogId");
SQLQuery q = SQLQuery
.Select(SQL.Blogs.Id, SQL.Blogs.Name)
.From(SQL.Blogs)
.Where(SQL.Blogs.Id == blogId);
Console.WriteLine(q);
would echo
SELECT
[dbo].[Blogs].[Id],
[dbo].[Blogs].[Name]
FROM
[dbo].[Blogs]
WHERE
([dbo].[Blogs].[Id] = @BlogId)
Nothing fancy.
With a little help from Moran Benisty, here's the script I use to get the metadata I need for the SQLQueryGenerator:
SELECT schemas.name AS [Schema],
tables.name AS [Table],
columns.name AS [Column],
CASE
WHEN columns.system_type_id = 34 THEN 'byte[]'
WHEN columns.system_type_id = 35 THEN 'string'
WHEN columns.system_type_id = 36 THEN 'System.Guid'
WHEN columns.system_type_id = 48 THEN 'byte'
WHEN columns.system_type_id = 52 THEN 'short'
WHEN columns.system_type_id = 56 THEN 'int'
WHEN columns.system_type_id = 58 THEN 'System.DateTime'
WHEN columns.system_type_id = 59 THEN 'float'
WHEN columns.system_type_id = 60 THEN 'decimal'
WHEN columns.system_type_id = 61 THEN 'System.DateTime'
WHEN columns.system_type_id = 62 THEN 'double'
WHEN columns.system_type_id = 98 THEN 'object'
WHEN columns.system_type_id = 99 THEN 'string'
WHEN columns.system_type_id = 104 THEN 'bool'
WHEN columns.system_type_id = 106 THEN 'decimal'
WHEN columns.system_type_id = 108 THEN 'decimal'
WHEN columns.system_type_id = 122 THEN 'decimal'
WHEN columns.system_type_id = 127 THEN 'long'
WHEN columns.system_type_id = 165 THEN 'byte[]'
WHEN columns.system_type_id = 167 THEN 'string'
WHEN columns.system_type_id = 173 THEN 'byte[]'
WHEN columns.system_type_id = 175 THEN 'string'
WHEN columns.system_type_id = 189 THEN 'long'
WHEN columns.system_type_id = 231 THEN 'string'
WHEN columns.system_type_id = 239 THEN 'string'
WHEN columns.system_type_id = 241 THEN 'string'
WHEN columns.system_type_id = 241 THEN 'string'
END AS [Type],
columns.is_nullable AS [Nullable]
FROM sys.tables tables
INNER JOIN sys.schemas schemas ON (tables.schema_id = schemas.schema_id )
INNER JOIN sys.columns columns ON (columns.object_id = tables.object_id)
WHERE tables.name <> 'sysdiagrams'
AND tables.name <> 'dtproperties'
ORDER BY [Schema], [Table], [Column], [Type]
Quick, Dirty, Working.
Anyone up to contributing a similar thing for SQL 2000 / MySql / Oracle / Postgres / MS-ACCESS ?
it's going to be subversion-ed really soon.
Imagine you could write that in your IDE:
SQLQuery q = SQLQuery
.Select(SQL.Blogs.Id, SQL.Blogs.Name)
.From(SQL.Blogs)
.Join(SQL.Posts, Join.On(SQL.Blogs.Id == SQL.Posts.BlogId))
.Where(SQL.Blogs.Name != "Ken's blog");
Console.WriteLine(q);
and getting that output :
SELECT [Blogs].[Id], [Blogs].[Name]
FROM ([Blogs] JOIN [Posts] ON ([Blogs].[Id]=[Posts].[BlogId]))
WHERE ([Blogs].[Name]<>'Ken''s blog')
Soon enough you would be able to to that.
After having fun creating the Static Sitemap Generator, today I've had a little free time (as my main machine is being reinstalled), so I came up with a SQL query generator.
It would be a tool to generate classes out of a database, that would make writing typed sql queries a breeze.
I have most of it working, except the part where I retrieve the metadata from the database ... No worries, my good friend and SQL guru Moran is about to send me the queries for that real soon.
First release would work with SQL Server 2005, and later on I'll add extension points to hook up other db engines.
It's funny. At the end of the day, I didn't use the tiny IoC in the StaticSiteMap for the testing.
It was fun however.
The Static SiteMap Generator's home is in Castle Contrib, and it's named Castle.Tools.StaticMapGenerator
I've just commited it to the repository, so it's at http://svn.castleproject.org:8080/svn/castlecontrib/Castle.Tools.StaticMapGenerator/trunk/
UPDATE (22/06/2008):
The source has slightly moved (to a sub folder):
http://svn.castleproject.org:8080/svn/castlecontrib/Tools/Castle.Tools.StaticMapGenerator/
I hope to have time soon to blog about the creation of this little tool, and of the usage. Also, expect a binary soon.
Last night I got frustrated with the fact that I have no intellisense (nor compile time check) for locating static files like .js, .css and image files.
So I sat up and created a simple console application that can generate exactly that, out of the site's filesystem.
usage:
D:\MyTools\StaticMapGenerator /site:D:\Dev\MySite
it generates a file called Static.Site.Generated.cs within the site's root folder, and then I go and include that file in my web project.
No I can do stuff like:
<script type="text/javascript" src="<%= Static.Site.Include.Scripts.myscript_js %>"> </script>
<link rel="stylesheet" href="<%= Static.Site.Include.CSS.master_css %>" />
<img alt="Ken Egozi" title="My Logo" src="<%= Static.Site.Include.Images.Logos.my_logo_png" />
How cool is that?
It works in every ASP.NET compatible web framework (MonoRail, ASP.NET MVC, even WebForms ...)
The only prequisite is .NET 2.0 runtime.
Sorry for keeping it out of reach for the moment. I need a little bit of time to setup a svn repository to make the source public (it would of course be BSD/Apache2/MIT thing) and to upload a binary. No promises given, I'll try to make it in the coming weekend, or even tonight, so stay tuned.
The code is somewhat naive, and certainly does not cover any edge cases, however it's enough to work cleanly on the largest project I'm currently involved in (Music Glue). Patches to make it more configurable and able to handle more edge cases would be gladly accepted once it's out.
One cool spot - as part of this, I have also implemented my tiny IoC container in 33 LoC.
Last night I've built a nice new tool called StaticMapGenerator which is used to generate a typed static resources site-map for ASP.NET sites (works for MonoRail, ASP.NET MVC and even WebForms).
I'll blog about it on a separate post in details.
Since I didn't want any dependency (but .NET 2.0 runtime) for the generator and the generated code, I couldn't use Windsor to IoC. That calls for a hand rolled simple IoC implementation
Ayende has already done it in 15 lines, but I wanted also to automagically set dependencies and have a simpler registration model.
so I've quickly hacked together a configurable DI resolver (a.k.a. IoC container) in 15 Minutes and 33 Lines Of Code. Call me a sloppy-coder, call me whadever-ya-like. It just works.
static class IoC
{
static readonly IDictionary<Type, Type>types = new Dictionary<Type, Type> ();
public static void Register<TContract, TImplementation>()
{
types[typeof(TContract)] = typeof(TImplementation);
}
public static T Resolve<T>()
{
return (T)Resolve(typeof(T));
}
public static object Resolve(Type contract)
{
Type implementation = types[contract];
ConstructorInfo constructor = implementation.GetConstructors()[0];
ParameterInfo[] constructorParameters = constructor.GetParameters();
if (constructorParameters.Length == 0)
return Activator.CreateInstance(implementation);
List<object> parameters = new List<object>(constructorParameters.Length);
foreach (ParameterInfo parameterInfo in constructorParameters)
parameters.Add(Resolve(parameterInfo.ParameterType));
return constructor.Invoke(parameters.ToArray());
}
}
Ok, I've cheated. You'd need using statements too, but you can see that I was generous enough with newlines ...
Usage:
Given those:
public interface IFileSystemAdapter { }
public class FileSystemAdapter : IFileSystemAdapter { }
public interface IBuildDirectoryStructureService { }
public class BuildDirectoryStructureService : IBuildDirectoryStructureService
{
IFileSystemAdapter fileSystemAdapter;
public BuildDirectoryStructureService(IFileSystemAdapter fileSystemAdapter)
{
this.fileSystemAdapter = fileSystemAdapter;
}
}
You can do that:
IoC.Register<IFileSystemAdapter, FileSystemAdapter>();You need not worry about supplying the BuildDirectoryStructureService with an implementation for the service it depends on, but only to register an implementation for that service.
IoC.Register<IBuildDirectoryStructureService, BuildDirectoryStructureService>();
IBuildDirectoryStructureService service = IoC.Resolve<IBuildDirectoryStructureService>();
From time to time you'd want some of your markup rendered only on 'real' scenarios. For example, you wouldn't want google analytics to track visits you do on your dev machine. Sometime you'd even develop while your machine is not even connected to the internet, and every page would try get the analytics script and will behave strangely.
In Monorail, the Request has a property named IsLocal, just for that. I've wrapped it in a nice ViewComponent.
public class GoogleAnalyticsComponent : ViewComponent
{public override void Render()
{
if (Request.IsLocal)
return;
RenderView("AnalyticsCode");
}
}
Accompanied by the AnalyticsCode view template:
<%@ Page Language="C#" Inherits="Castle.MonoRail.Views.AspView.ViewAtDesignTime" %>
<script src="https://ssl.google-analytics.com/urchin.js" type="text/javascript"></script>
<script type="text/javascript">
_uacct = "MY_URCHIN_CODE";
urchinTracker();
</script>
, that can easily be extensible to set the urchin code with a parameter.
Have just read Ayende's post about C#/Java vs Boo/Ruby.
Tried to comment, but then I decided it's worth a post.
I'd say that the difference is MAF - Management Acceptance Factor
Boo is also a way too cool/strange/creepy name for a distinguished suit to grasp.
It's like when you're a collage girl, and you want to introduce your new boyfriend to your mama. It doesn't matter that he has a BSc and MBA plus 3 castles in the Swiss alps. If he'd first show up to the family on his way-too-cool motorcycle, then you're going to be grounded.
When I approached my last manager about MonoRail, and told him that the views will be written in 'Boo', he got all scared. Then I wrote AspView, views to be written in c#, and he gave consent to go MonoRail.
Even though, at least at that time, Brail was way more mature than AspView.
The 'cooler' languages needs to be marketed to management.
Ruby works in Eclipse. I wonder who is going to start an OSS effort to create a decent Boo plugin for VS2008 (based on the VS2008 shell).
Make it demoable, make it look 'official', and MAF would go way higher.
Following users requests, I have just posted two documents to using.castleproject.org.
The first is an explanation about the CodeGenerator (from Contrib), and another one, on using the DictionaryAdapter.
Here are the links:
Related stuff:
Problem:
Possible causes:
Setting XHTML output manually:
Thanks Mr. Joe Chang, from the Windows Live Writer team, who have pointed that out for me.
Although about three weeks too late, I present thee:
AspView, built for Castle RC3 (release, debug, source)
I've also introduced a well due improvement to the engine. Now it supports the use of a 404 rescue view, that would get rendered in case of the url mapping to a non-existent controller.
the commit comment (for revision 314) says it all:
Handling view creation for EmptyController, specifically when a controller is not found and a 404 rescue exists
Next improvement will include an option for doing AutoRecompilation in memory, as sometimes the IIS process gets hold on the CompiledViews assembly files (dll and pdb) and failing the automatic recompilation process.
I certainly need that as it happens on my machine too much, and building the Web project takes a solid 10-15 seconds, while running vcompile is a milliseconds thing only.
Soon ...
That's a great news for everyone who build websites and web applications.
IE7 would be installable even to XP users without the Genuine Check.
That means that in short time, the IE7 adoption rate would increase so much, that hopefully the annoying IE6 would become as obsolete as Netscape 4 and IE 5.5 ...
No more dirty CSS hacks (or at least, a lot less)
No more buggy box-model
Finally we can use input[type=text] and the likes
I've kept IE6 on my box for so long only to be able to test what I write. Even though I use Firefox for day-to-day browsing, I still need IE for some crappy israeli sites that would just not work on non IE (and by not work - I mean that you get an alert box saying:
For people who knows not Hebrew:
"This site supports IE browsers, from version 5.5 and up. Support to other browsers is planned for next release"
Ha Ha.
This message is there for at least a year.
And it's not even dependant on ActiveX or other IE magic. It's only some laziness regarding JS and CSS compatibility.
look at http://www.codeplex.com/xunit
Quite interesting. I might give that a shot soon.
You can read about it at http://jamesnewkirk.typepad.com/posts/2007/09/announcing-xuni.html
The upside for that is the simplification of things by removing some attributes, and having a more consistent model regarding assertions on exceptions.
Main reason - I want to reduce traffic to my blog (I do have a gazzilion a million few hundreds subscribers, just like you, my dear reader.).
Plus, since feed-burner has gone Google-d, they give the PRO services for free, so I'd be able to enjoy the stats - which means I'd be able to know exactly how many people are reading me, and then can arrange the kenegozi-readers-party (thought about the Madison Square Garden, but I guess my living room will do just fine).
So, please update your favorite reader to point to http://feeds.feedburner.com/kenegozi.
Seriously, it's Google. What took them so long?
Anyway - Google Reader remains my feed reader of choice. I do not use my laptop offline much, so it's ok like that, plus the offline mode in reader kinda works, so for the occasional offline sessions I do have it's more than enough.
It took me almost a week to notice, though ...
I'm using VS2005 (with SP1, like duhh) and have had R# 3.0.1
Now, I'm not a fan of the default font and color scheme, as I like better the slicker mono-fonts, like Consolas. I am also becoming a Black-Background type, not for the WouldSaveTheRainForests==true reason (in LCD the light is static no matter what color it shows) but for the implements IDLikeToKeepMyEyeSightForALongTime reason.
So, started with importing a color scheme from some internet-found-place, don't remember where, and then tried to change those Resharper coloring options (like, a variable name that is being used an odd amount of times, by internal classes, however not in an explicit-interface implemented method, that returns a struct), just to find out the the Fonts-And-Colors menu miss those lovely Resharper entries).
Okay, so what should I do? Export the settings, edit the xml, and re-import. Not much fun there.
Hmm. Googled it (I may use the term, as I actually use Google as a search engine), and found a post on jetbrains support site, with the same problem.
no solution though.
However - this is how I solved it eventually:
1. Export the current settings to a file
2. Reset all settings
3. Re-install R# (hey - now it's 3.0.2 !!)
4. Import back my settings.
Assuming you have a main "trunk" in your subversion repository, and that you are actually working on a different branch.
You'd need to merge your changes from your branch to the trunk so other team members would be able to use your code. You'd also want to be able to merge from the trunk to your branch, to be able to use your teammate's code.
The thing you should bear in mind while you merge, is that the actual merge process is actually working by generating a patch (using diff) and applying this patch on the target.
a quick note: It is very much recommended that you have committed all changes to the target of the merge, into the repository, so it would be easy to revert if something went wrong.
So:
a. Go to the trunk folder on your filesystem, right-click->tortoise->merge.
b. You want the changes between the current trunk revision and your branch's current revision to be applied on the trunk, so you choose:
From: your trunk, revision HEAD
To: your branch, revision HEAD.
I know, the terminology is confusing, as you want to "update" from the trunk to the branch's state, but remember that you want the diff(erence), or in other words, the changes that will take the trunk FROM it's current state, TO your branch's state.
screenshot:
now you have a merged trunk on your workstation. Make sure that everything compiles and that tests are green, and commit.
a) Go to your branch's folder, right-click->tortoise->merge;
Now, you want the changes between the last trunk revision that you have on your branch, to the newest revision of the trunk. To find out that last trunk revision that you have on your branch, go to your branch's folder, right-click->tortoise->show-log, and look for it. If you are a good reader you'd easily find it since you have mentioned the revision numbers of your merges in the commit remarks, as you are kindly recommended)
A screenshot from the branch's log:
I need to check if I have merged my branch to the trunk on a later point. I'll do that using the Trunk's log (trunk folder, right-click->tortoise->show-log):
Indeed. It seams that my branch is in sync with the trunk at revision 918
b) Now you fill
From: your trunk, revision "last revision you have"
To: your trunk, revision "new, wanted state" (usually HEAD).
in my example, the last trunk version I have merged into my branch is 902, so that's the screenshot:
I know, terminology sucks again. You probably thing "from trunk to trunk? Is he crazy?" well, again, you want to get the changes that was made TO THE TRUNK, and apply them to your branch. Remembering that this is actually a patch that will get applied make anything clear again.
now you have a merged branch on your workstation. Make sure that everything compiles and that tests are green, and commit.
Recommendation: write down in the commit's remark, the revision number of the trunk (the current HEAD before the merge) for next time.
My thanks to this page, and to Lee Henson who have pointed it out for me, and helped my grasp the whole merge==diff'n'patch thing.
Today I noticed that piece of code on my working copy:
Repository.Blog.FindOne(Where.Blog.Id == blogId)
Check out this nice tool from Omer Rauchwerger.
It could help a team to manage a coding convention. Should be very useful in Open Source environments. For example, when committing changes to castle project (or sending a patch) there is a coding standard than needs to be followed. Regionerate could help a lot with that effort.
I need to see if it can select methods and properties by attributes. It could then help making MonoRail controllers and ActiveRecord decorated classes more readable (region of all actions with a "SkipFilterAttribute", region of "Property" and region of "HasMany", etc.)
UPDATE:
Silly me, I forgot to mention that I found about this great tool at Roy Osherov's blog. A very good one, that is. Many Agile related stuff, and funny little things, too. So go on and subscribe to it's feed.
Checkout the latest post of Scott Guthrie.
Is the long awaited JS IDE will be VS2008?
Now it's a matter of adding ///<summery> tags to prototype.js and maybe people would really stop being afraid of developing javascript code.
Now that's a good reason to switch to VS2008, combined with the fact than you can hold to your current .NET distribution.
After all, even VS2005 was actually calling csc.exe rather that calling some magical inner stuff as in 2002/2003.
I hope that this also means better addin development support, so great projects like CVSI and ActiveWriter, could become even better.
Do you think they'd enable a "Compile for Mono" option?
If you are an AspView user you might have noticed a problem.
If you setup a nullable-value-type parameter with a default value other than null, then you'd get a casting error.
example:
<%
int? someInt = default(int);
%>
some markup
<% if (someInt == default(int)) DoSomething();%>
it happened because of the way GetParameter worked
GetParameter is a method that gets a view parameter value from the view's properties collection (PropertyBag, Flash, Request.Params, etc.). It's located in the AspViewBase class (the base class for each and every view in the AspView world).
So, now it's fixed, and a test was added to make sure it'll stay that way.
As soon as google.com will be accesible again, you'd be able to check out and build.
UPDATE:
I'm too tired (3am here). The sources are on castle contrib and not on google, so you'd find them here
Wow.
Another great tool from Google.
Works on Win/Mac/Linux, for IE and FF.
In a few words - it can give you offline browsing, plus local storage using SQLite (so you can run SQL queries strait from your javascript to query the local store)
I wonder what secutiry issues can come up. However, it looks very cool, and can help bring power to existing DHTML/Ajax apps.
Makes me think. Now that you do SQL from javascript, isn't it time for JsHibernate? and what about an ActiveRecord inplementation in javascript?
So, in the Flex/Silverlight war, it seams that Google is gonna win again ...
(from Scott Hanselman's Blog)
I needed to manually Castle today, for the first time.
The need is for Castle.MonoRail.TestSupport.BaseControllerTest only, so I do not really care about all the rest.
Opened "How to build.txt"
I know that the builds in the CI server are failing due to some filing tests on DP2, so I add "-D:common.run-tests=false".
no brainer.
I am also targeting .net2 only, so I add "-t:net-2.0"
baboom. This fails.
The nant exe is telling me that I can only build to .net 1.1, or .net compact framework 1.0.
So I went to nant's config file, and found out to my surprise, that the frameworks that are present there are:
.net 1.1,
.net compact framework 1.0
.net 2.0 BETA 1
hmmm.
So I've edited the config, changed the existing .net 2.0 config name to .net2.0Beta1,
copy&pasted the .net node to another one, now switching version number from
sdkdirectory="${path::combine(sdkInstallRoot, 'bin')}"
frameworkdirectory="${path::combine(installRoot, 'v2.0.40607')}"
frameworkassemblydirectory="${path::combine(installRoot, 'v2.0.40607')}"
clrversion="2.0.40607"
to
sdkdirectory="${path::combine(sdkInstallRoot, 'bin')}"
frameworkdirectory="${path::combine(installRoot, 'v2.0.50727')}"
frameworkassemblydirectory="${path::combine(installRoot, 'v2.0.50727')}"
clrversion="2.0.50727"
voila. Now the build is starting.
However, the Castle.Components.Validator.Tests dll refuse to build. I'll disable it, too.
UPDATE:
I'm an idiot. Did not notice that NAnt has gone far beyond rc3 a long time ago ...
just added a blogroll.
To the DB, to the Domain, to the controller and to the view.
Took me (all in all) 30 minutes, including all the coding, CSS-ing, uploading to the webserver, setting up the DB table on the hosted server, adding a few entries, clearing the browser's cache, and viewing it.
ah, and committing changes to Google code.
All of that was made in the Budapest Airport cafeteria, while waiting for my flight home (was a great trip. Photos, though not many of them, will be posted later on).
Rest assure that the DB access code is tested, and that the calls to the DB and to the cached data from the Controller and View are all typed.
I'd like to thank NHibernate, Castle and AspView (hey - that's me !), who made this possible.
I bet Ayende would have done it in 20 ...
Since this blog is running on an engine that I wrote (available on Google code site, here), it lack some features that more mature blog engines already have. (the other engines lacks the combined power of ActiveRecord/MonoRail/AspView ...)
So, that's currently my list:
1. Blogroll, for obvious reasons.
2. Email alert for me when anyone posts a comment for one of my posts.
3. Comments feed (via ATOM).
UPDATE - Done
4. Email subscriptions for new posts, or new comments on specific posts.
5. I have a problem with the font. I should fix the CSS but the Internet connection here (I'm at a Budapest hotel) is quite poor. Will be fixed next week.
UPDATE - Done
Any other suggestions?
note that I do not intent on implementing Pingbacks and Trackbacks, since those were littering my blog in the past.
So if you wanna download it, you should go directry to the NUnit's page on sourceforge
I've just commited to the repository a new version of AspView.
The main addition is "Auto Recompilation" feature.
This means that when you change one of the view sources, the application will automatically recompile the views upon the following request.
You enable the feature by adding the next attribure to the aspview config section in web.config:
<aspview .... autoRecompilation="true" ... > ... </aspview>
Breaking change:
If you happen to reference an assembly from the GAC (using the aspview configuration in the web.config) you need to add a hint for the engine, like this:
<reference assembly="MyAssemblyFromGAC.dll" isFromGac="true" />
Known issues:
1. You need to let ASPNET user (or the Application Pool user) a modify access on the bin folder.
Note that if you use the inner WebServer of Visual Studio this should not be a problem, since in that case the web application runs with your user, that has the needed peremissions on th