Attached is a modified version of the resgen task that I need some 
second (third,forth,etc...) opinions on.

I re-wrote portions to handle two different issues that I encountered.

Currently the resgen task handles single files well, but breaks on 
filesets.  The biggest issue with the filesets, was the NeedsCompiling 
routine.  It only checked the single file properties, so would break if 
those were null.  I re-wrote that to handle the checking of filesets.

The second problem was one of needing to prepend namespaces on to the 
.resx files.  For instance, at our project at work, we needed to run our
Form1.resx, Form2.resx files through resgen and have them come out 
"Viper.Form1.resources, Viper.Form2.resources".  This was also a problem 
that could be handled if you were using resgen on a file by file basis, 
but not with filesets.  So I added a "prepend" property.  This property 
will prepend anything you put in there to each outputed .resources file.

Another problem, which I have not tackled, is the culture one.  Some may 
want to resgen a file name form3.resx and have it come out 
"Project.form3.en.resources".  This case is not handled in my modified 
version.

Anyway, here is my file for someone else to critique.  I have not 
prettied the code much (in fact haven't even bounced it against the 
standards, I will do that), I also have not written any new tests for this.

It defintely works for our project (82 forms, in six different 
projects), but I coded it for my use so I don't know if it fits 
everybody elses issues, if i can make it better, etc...

I would appreciate any feedback.  Thanks.

JT
// NAnt - A .NET build tool
// Copyright (C) 2001-2002 Gerry Shaw
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Joe Jones ([EMAIL PROTECTED])
// Gerry Shaw ([EMAIL PROTECTED])


using System;
using System.IO;
using System.Text;
using SourceForge.NAnt.Attributes;

namespace SourceForge.NAnt.Tasks 
{

        /// <summary>Converts files from one resource format to another (wraps 
Microsoft's resgen.exe).</summary>
        /// <example>
        ///   <para>Convert a resource file from the .resx to the .resources 
format</para>
        ///   <code>
        /// <![CDATA[
        /// <resgen input="translations.resx" output="translations.resources" />
        /// ]]>
        ///   </code>
        /// </example>
        [TaskName("resgen")]
        public class ResGenTask : ExternalProgramBase 
        {

                string _arguments;
                string _input = null; 
                string _output = null;
                bool _compile = false;
                string _prepend = null;
                FileSet _resources = new FileSet();

                /// <summary>Input file to process.</summary>
                [TaskAttribute("input", Required=false)]
                public string Input { get { return _input; } set { _input = value;} }

                /// <summary>Name of the resource file to output.</summary>
                [TaskAttribute("output", Required=false)]
                public string Output {
                        get 
                        { 
                                if (_prepend == null || _prepend == "")
                                {
                                        return _output; 
                                } 
                                else
                                {
                                        int slash;
                                        slash = _output.LastIndexOf(@"\");
                                        if (slash == -1) {slash = 
_output.LastIndexOf(@"/");}
                                        if (slash != -1)
                                        {
                                                StringBuilder outf = new 
StringBuilder();
                                                outf.Append(_output.Substring(0,slash 
+ 1));
                                                outf.Append(_prepend);
                                                outf.Append(_output.Substring(slash + 
2, _output.Length + 1));
                                                return outf.ToString();
                                        }
                                        else
                                        {
                                                return _prepend + _output;
                                        }
                                }
                        }
                        set { _output = value; } 
                }

                /// <summary>Any namespace information that needs to be appended to 
the output.</summary>
                [TaskAttribute("prepend", Required=false)]
                public string Prepend { get { return _prepend; } set {_prepend = value 
;} }

        /// <summary>If true use the fileset to determine the list of files to convert 
(<c>/compile</c> flag).</summary>
        [TaskAttribute("compile")]
        [BooleanValidator()]
        public bool Compile { get { return _compile; } set {_compile = value;} }

        /// <summary>Takes a list of .resX or .txt files to convert to .resources 
files.</summary>
        [FileSet("resources")]
        public FileSet Resources { get { return _resources; } }

        public override string ProgramFileName { get { return Name; } }

        public override string ProgramArguments { get { return _arguments; } }
                
        protected virtual void WriteOptions(TextWriter writer) {
        }

        protected string GetOutputPath() {
            return Path.GetFullPath(Path.Combine(BaseDirectory, Output));
        }

        protected string GetInputPath() {
            return Path.GetFullPath(Path.Combine(BaseDirectory, Input));
        }

        protected virtual bool NeedsCompiling() {
            // return true as soon as we know we need to compile
                        bool needs = false;
                        if (!Compile)
                        {
                                FileInfo outputFileInfo = new 
FileInfo(GetOutputPath());
                                if (!outputFileInfo.Exists) 
                                {
                                        needs = true;
                                }

                                FileInfo inputFileInfo = new FileInfo(GetInputPath());
                                if (!inputFileInfo.Exists) 
                                {
                                        needs = true;
                                }

                                if (outputFileInfo.LastWriteTime < 
inputFileInfo.LastWriteTime) 
                                {
                                        needs =  true;
                                }
                        }
                        else
                        {

                                FileInfo outputFileInfo;
                                FileInfo inputFileInfo;
                                StringBuilder outsb;

                                needs = false;
                                foreach (string fileName in Resources.FileNames) 
                                {
                                        outsb = new StringBuilder();
                                        
                                        outsb = new StringBuilder();
                                        int dirpos = fileName.LastIndexOf(@"\");
                                        if (dirpos == -1){dirpos = 
fileName.LastIndexOf(@"/");}
                                        string newname = fileName.Substring(dirpos + 
1);
                                        outsb.Append(fileName.Substring(0,dirpos + 1));
                                        //outsb.Append(@"/");
                                        if (_prepend != null) { 
outsb.Append(_prepend); }
                                        int posresx = newname.IndexOf(".resx");
                                        if (posresx == -1) {posresx = 
newname.IndexOf(".txt");}
                                        if (posresx != -1) 
                                        {
                                                outsb.Append(newname.Substring(0, 
posresx));
                                        }
                                        else
                                        {
                                                outsb.Append(newname);
                                        }
                                        outsb.Append(@".resources");
                                        //System.Console.WriteLine(outsb.ToString());
                                        
                                        outputFileInfo = new 
FileInfo(outsb.ToString());
                                        inputFileInfo = new FileInfo(fileName);
                                        if (!outputFileInfo.Exists) 
                                        {
                                                needs = true;
                                        }
                                        if (!inputFileInfo.Exists) 
                                        {
                                                needs = true;
                                        }
                                        if (outputFileInfo.LastWriteTime < 
inputFileInfo.LastWriteTime) 
                                        {
                                                needs =  true;
                                        }
                                }
                        }
                                                        return needs;
        }

        protected override void ExecuteTask() {
            if (NeedsCompiling()) {
                // create temp response file to hold compiler options
                StringBuilder sb = new StringBuilder ();
                StringWriter writer = new StringWriter ( sb );
                                string quote = "\"";
                try {
                    //Log.WriteLine(LogPrefix + "Compiling {0} to {1}", 
GetInputPath(), GetOutputPath());

                    // specific compiler options
                    WriteOptions(writer);

                    // Microsoft common compiler options
                    if (!Compile) {
                        writer.Write(" \"{0}\"", Input );
                                                writer.Write(" \"{0}\"", Output );

                                                // Make sure to close the response 
file otherwise contents
                                                // will not be written to disc and 
EXecuteTask() will fail.
                                                writer.Close();
                                                _arguments = sb.ToString ();

                                                // display response file contents
                                                Log.WriteLineIf(Verbose, _arguments);

                                                // call base class to do the work
                                                base.ExecuteTask();
                    } else {
                        
                                                StringBuilder outsb;
                                                //bool addComma = false;
                                                //writer.Write(" /compile" );

                                                foreach (string fileName in 
Resources.FileNames) 
                                                {
                                                        outsb = new StringBuilder();
                                                        sb = new StringBuilder ();
                                                        writer = new StringWriter ( sb 
);

                                                        
                                                        //outsb.Append(quote);
                                                        int dirpos = 
fileName.LastIndexOf(@"\");
                                                        if (dirpos == -1){dirpos = 
fileName.LastIndexOf(@"/");}
                                                        string newname = 
fileName.Substring(dirpos + 1);
                                                        
outsb.Append(fileName.Substring(0,dirpos + 1));
                                                        //outsb.Append(@"/");
                                                        if (_prepend != null) { 
outsb.Append(_prepend); }
                                                        int posresx = 
newname.IndexOf(".resx");
                                                        if (posresx == -1) {posresx = 
newname.IndexOf(".txt");}
                                                        if (posresx != -1) 
                                                        {
                                                                
outsb.Append(newname.Substring(0, posresx));
                                                        }
                                                        else
                                                        {
                                                                outsb.Append(newname);
                                                        }
                                                        outsb.Append(@".resources");
                                                        //outsb.Append(quote);
                                                        //      
System.Console.WriteLine(outsb.ToString());
                                                        
                                                        writer.Write(" \"{0}\"", 
fileName );
                                                        writer.Write(" \"{0}\"", 
outsb.ToString() );

                                                        // Make sure to close the 
response file otherwise contents
                                                        // will not be written to disc 
and EXecuteTask() will fail.
                                                        writer.Close();
                                                        _arguments = sb.ToString ();

                                                        // display response file 
contents
                                                        Log.WriteLineIf(Verbose, 
_arguments);
                                                        
System.Console.WriteLine(_arguments);
                                                        // call base class to do the 
work
                                                        base.ExecuteTask();
                                                }
                    }

                    
                } finally {
                    // make sure we delete response file even if an exception is thrown
                    writer.Close(); // make sure stream is closed or file cannot be 
deleted
                }
            }
        }
    }
}

Reply via email to