~ubuntu-branches/debian/sid/nunit/sid

« back to all changes in this revision

Viewing changes to src/ClientUtilities/util/NUnitProject.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2014-09-16 13:43:36 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20140916134336-kjxz48tty6lx2ja5
Tags: 2.6.3+dfsg-1
* [c7bd1b5] Imported Upstream version 2.6.3+dfsg
* [bcb4bf8] Move nunit-console-runner to GAC-installed libnunit2.6, 
  don't treat it as a private lib. This lib is signed, and treated 
  as a GAC lib by consumers such as MonoDevelop.
* [7f08e99] Bump version to 2.6.3 as required
* [84535eb] Refreshed patches
* [8479f61] Split package up into per-assembly packages. This makes 
  ABI tracking easier in the future, as we can meaningfully have GAC 
  policy for cases where ABI isn't truly bumped, and no policy for 
  cases where it is. For example, if nunit.framework bumps ABI but 
  nunit.core does not, previously we would need to rebuild everything 
  using NUnit, but under the new split packaging, that rebuild would 
  not be needed for apps only using nunit.core.
* [17a7dc7] Add missing nunit.mocks.dll to nunit.pc

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// ****************************************************************
2
 
// This is free software licensed under the NUnit license. You
3
 
// may obtain a copy of the license as well as information regarding
4
 
// copyright ownership at http://nunit.org.
5
 
// ****************************************************************
6
 
 
7
 
using System;
8
 
using System.Collections;
9
 
using System.Xml;
10
 
using System.Xml.Schema;
11
 
using System.IO;
12
 
using System.Threading;
13
 
using NUnit.Core;
14
 
 
15
 
namespace NUnit.Util
16
 
{
17
 
        /// <summary>
18
 
        /// Class that represents an NUnit test project
19
 
        /// </summary>
20
 
        public class NUnitProject
21
 
    {
22
 
        #region Constants
23
 
        public static readonly string Extension = ".nunit";
24
 
        #endregion
25
 
 
26
 
        #region Instance variables
27
 
 
28
 
        /// <summary>
29
 
                /// Path to the file storing this project
30
 
                /// </summary>
31
 
                private string projectPath;
32
 
 
33
 
                /// <summary>
34
 
                /// Application Base for the project. Since this
35
 
                /// can be null, always fetch from the property
36
 
                /// rather than using the field directly.
37
 
                /// </summary>
38
 
                private string basePath;
39
 
 
40
 
                /// <summary>
41
 
                ///  Whether the project is dirty
42
 
                /// </summary>
43
 
                private bool isDirty = false;
44
 
 
45
 
        /// <summary>
46
 
        /// Whether canges have been made requiring a reload
47
 
        /// </summary>
48
 
        private bool reloadRequired = false;
49
 
                
50
 
                /// <summary>
51
 
                /// Collection of configs for the project
52
 
                /// </summary>
53
 
                private ProjectConfigCollection configs;
54
 
 
55
 
        /// <summary>
56
 
        /// True for NUnit-related projects that follow the config
57
 
        /// of the NUnit build under which they are running.
58
 
        /// </summary>
59
 
        private bool autoConfig;
60
 
 
61
 
                /// <summary>
62
 
                /// The currently active configuration
63
 
                /// </summary>
64
 
                private ProjectConfig activeConfig;
65
 
 
66
 
                /// <summary>
67
 
                /// Flag indicating that this project is a
68
 
                /// temporary wrapper for an assembly.
69
 
                /// </summary>
70
 
                private bool isAssemblyWrapper = false;
71
 
 
72
 
        /// <summary>
73
 
        /// The ProcessModel to be used in loading this project
74
 
        /// </summary>
75
 
        private ProcessModel processModel;
76
 
 
77
 
        /// <summary>
78
 
        /// The DomainUsage setting to be used in loading this project
79
 
        /// </summary>
80
 
        private DomainUsage domainUsage;
81
 
 
82
 
                #endregion
83
 
 
84
 
                #region Constructor
85
 
 
86
 
                public NUnitProject( string projectPath )
87
 
                {
88
 
                        this.projectPath = Path.GetFullPath( projectPath );
89
 
                        configs = new ProjectConfigCollection( this );
90
 
                }
91
 
 
92
 
                #endregion
93
 
 
94
 
                #region Properties and Events
95
 
 
96
 
                /// <summary>
97
 
                /// The path to which a project will be saved.
98
 
                /// </summary>
99
 
                public string ProjectPath
100
 
                {
101
 
                        get { return projectPath; }
102
 
                        set 
103
 
                        {
104
 
                                projectPath = Path.GetFullPath( value );
105
 
                                isDirty = true;
106
 
                        }
107
 
                }
108
 
 
109
 
                public string DefaultBasePath
110
 
                {
111
 
                        get { return Path.GetDirectoryName( projectPath ); }
112
 
                }
113
 
 
114
 
                /// <summary>
115
 
                /// Indicates whether a base path was specified for the project
116
 
                /// </summary>
117
 
                public bool BasePathSpecified
118
 
                {
119
 
                        get
120
 
                        {
121
 
                                return basePath != null && basePath != string.Empty;
122
 
                        }
123
 
                }
124
 
 
125
 
                /// <summary>
126
 
                /// The base path for the project. Constructor sets
127
 
                /// it to the directory part of the project path.
128
 
                /// </summary>
129
 
                public string BasePath
130
 
                {
131
 
                        get 
132
 
                        { 
133
 
                                if ( !BasePathSpecified )
134
 
                                        return DefaultBasePath; 
135
 
                                return basePath;
136
 
                        }
137
 
            set
138
 
            {
139
 
                basePath = value;
140
 
 
141
 
                if (basePath != null && basePath != string.Empty
142
 
                    && !Path.IsPathRooted(basePath))
143
 
                {
144
 
                    basePath = Path.Combine(
145
 
                        DefaultBasePath,
146
 
                        basePath);
147
 
                }
148
 
 
149
 
                basePath = PathUtils.Canonicalize(basePath);
150
 
                HasChangesRequiringReload = IsDirty = true;
151
 
            }
152
 
                }
153
 
 
154
 
                /// <summary>
155
 
                /// The name of the project.
156
 
                /// </summary>
157
 
                public string Name
158
 
                {
159
 
                        get { return Path.GetFileNameWithoutExtension( projectPath ); }
160
 
                }
161
 
 
162
 
        public bool AutoConfig
163
 
        {
164
 
            get { return autoConfig; }
165
 
            set { autoConfig = value; }
166
 
        }
167
 
 
168
 
                public ProjectConfig ActiveConfig
169
 
                {
170
 
                        get 
171
 
                        { 
172
 
                                // In case the previous active config was removed
173
 
                                if ( activeConfig != null && !configs.Contains( activeConfig ) )
174
 
                                        activeConfig = null;
175
 
                                
176
 
                                // In case no active config is set or it was removed
177
 
                if (activeConfig == null && configs.Count > 0)
178
 
                    activeConfig = configs[0];
179
 
                                
180
 
                                return activeConfig; 
181
 
                        }
182
 
                }
183
 
 
184
 
                // Safe access to name of the active config
185
 
                public string ActiveConfigName
186
 
                {
187
 
                        get
188
 
                        {
189
 
                                ProjectConfig config = ActiveConfig;
190
 
                                return config == null ? null : config.Name;
191
 
                        }
192
 
                }
193
 
 
194
 
                public bool IsLoadable
195
 
                {
196
 
                        get
197
 
                        {
198
 
                                return  ActiveConfig != null &&
199
 
                                        ActiveConfig.Assemblies.Count > 0;
200
 
                        }
201
 
                }
202
 
 
203
 
                // A project made from a single assembly is treated
204
 
                // as a transparent wrapper for some purposes until
205
 
                // a change is made to it.
206
 
                public bool IsAssemblyWrapper
207
 
                {
208
 
                        get { return isAssemblyWrapper; }
209
 
                        set { isAssemblyWrapper = value; }
210
 
                }
211
 
 
212
 
                public string ConfigurationFile
213
 
                {
214
 
                        get 
215
 
                        { 
216
 
                                // TODO: Check this
217
 
                                return isAssemblyWrapper
218
 
                                          ? Path.GetFileName( projectPath ) + ".config"
219
 
                                          : Path.GetFileNameWithoutExtension( projectPath ) + ".config";
220
 
                        }
221
 
                }
222
 
 
223
 
                public bool IsDirty
224
 
                {
225
 
                        get { return isDirty; }
226
 
                        set 
227
 
            { 
228
 
                isDirty = value;
229
 
 
230
 
                if (isAssemblyWrapper && value == true)
231
 
                {
232
 
                    projectPath = Path.ChangeExtension(projectPath, ".nunit");
233
 
                    isAssemblyWrapper = false;
234
 
                    HasChangesRequiringReload = true;
235
 
                }
236
 
            }
237
 
                }
238
 
 
239
 
        public bool HasChangesRequiringReload
240
 
        {
241
 
            get { return reloadRequired; }
242
 
            set { reloadRequired = value; }
243
 
        }
244
 
 
245
 
        public ProcessModel ProcessModel
246
 
        {
247
 
            get { return processModel; }
248
 
            set
249
 
            {
250
 
                processModel = value;
251
 
                HasChangesRequiringReload = IsDirty = true;
252
 
            }
253
 
        }
254
 
 
255
 
        public DomainUsage DomainUsage
256
 
        {
257
 
            get { return domainUsage; }
258
 
            set
259
 
            {
260
 
                domainUsage = value;
261
 
                HasChangesRequiringReload = IsDirty = true;
262
 
            }
263
 
        }
264
 
 
265
 
                public ProjectConfigCollection Configs
266
 
                {
267
 
                        get { return configs; }
268
 
                }
269
 
                #endregion
270
 
 
271
 
        #region Static Methods
272
 
        public static bool IsNUnitProjectFile(string path)
273
 
        {
274
 
            return Path.GetExtension(path) == Extension;
275
 
        }
276
 
 
277
 
        public static string ProjectPathFromFile(string path)
278
 
        {
279
 
            string fileName = Path.GetFileNameWithoutExtension(path) + NUnitProject.Extension;
280
 
            return Path.Combine(Path.GetDirectoryName(path), fileName);
281
 
        }
282
 
        #endregion
283
 
 
284
 
        #region Instance Methods
285
 
 
286
 
        public void SetActiveConfig( int index )
287
 
                {
288
 
                        activeConfig = configs[index];
289
 
            HasChangesRequiringReload = IsDirty = true;
290
 
                }
291
 
 
292
 
                public void SetActiveConfig( string name )
293
 
                {
294
 
                        foreach( ProjectConfig config in configs )
295
 
                        {
296
 
                                if ( config.Name == name )
297
 
                                {
298
 
                                        activeConfig = config;
299
 
                    HasChangesRequiringReload = IsDirty = true;
300
 
                    break;
301
 
                                }
302
 
                        }
303
 
                }
304
 
 
305
 
                public void Add( VSProject vsProject )
306
 
                {
307
 
                        foreach( VSProjectConfig vsConfig in vsProject.Configs )
308
 
                        {
309
 
                                string name = vsConfig.Name;
310
 
 
311
 
                                if ( !configs.Contains( name ) )
312
 
                                        configs.Add( name );
313
 
 
314
 
                                ProjectConfig config = this.Configs[name];
315
 
 
316
 
                                foreach ( string assembly in vsConfig.Assemblies )
317
 
                                        config.Assemblies.Add( assembly );
318
 
                        }
319
 
                }
320
 
 
321
 
                public void Load()
322
 
                {
323
 
                        XmlTextReader reader = new XmlTextReader( projectPath );
324
 
 
325
 
                        string activeConfigName = null;
326
 
                        ProjectConfig currentConfig = null;
327
 
                        
328
 
                        try
329
 
                        {
330
 
                                reader.MoveToContent();
331
 
                                if ( reader.NodeType != XmlNodeType.Element || reader.Name != "NUnitProject" )
332
 
                                        throw new ProjectFormatException( 
333
 
                                                "Invalid project format: <NUnitProject> expected.", 
334
 
                                                reader.LineNumber, reader.LinePosition );
335
 
 
336
 
                                while( reader.Read() )
337
 
                                        if ( reader.NodeType == XmlNodeType.Element )
338
 
                                                switch( reader.Name )
339
 
                                                {
340
 
                                                        case "Settings":
341
 
                                                                if ( reader.NodeType == XmlNodeType.Element )
342
 
                                                                {
343
 
                                                                        activeConfigName = reader.GetAttribute( "activeconfig" );
344
 
 
345
 
                                    string autoConfig = reader.GetAttribute("autoconfig");
346
 
                                    if (autoConfig != null)
347
 
                                        this.AutoConfig = autoConfig.ToLower() == "true";
348
 
                                    if (this.AutoConfig)
349
 
                                                                                activeConfigName = NUnitConfiguration.BuildConfiguration;
350
 
                                                                        
351
 
                                    string appbase = reader.GetAttribute( "appbase" );
352
 
                                                                        if ( appbase != null )
353
 
                                                                                this.BasePath = appbase;
354
 
 
355
 
                                    string processModel = reader.GetAttribute("processModel");
356
 
                                    if (processModel != null)
357
 
                                        this.ProcessModel = (ProcessModel)Enum.Parse(typeof(ProcessModel), processModel);
358
 
 
359
 
                                    string domainUsage = reader.GetAttribute("domainUsage");
360
 
                                    if (domainUsage != null)
361
 
                                        this.DomainUsage = (DomainUsage)Enum.Parse(typeof(DomainUsage), domainUsage);
362
 
                                }
363
 
                                                                break;
364
 
 
365
 
                                                        case "Config":
366
 
                                                                if ( reader.NodeType == XmlNodeType.Element )
367
 
                                                                {
368
 
                                                                        string configName = reader.GetAttribute( "name" );
369
 
                                                                        currentConfig = new ProjectConfig( configName );
370
 
                                                                        currentConfig.BasePath = reader.GetAttribute( "appbase" );
371
 
                                                                        currentConfig.ConfigurationFile = reader.GetAttribute( "configfile" );
372
 
 
373
 
                                                                        string binpath = reader.GetAttribute( "binpath" );
374
 
                                                                        currentConfig.PrivateBinPath = binpath;
375
 
                                                                        string type = reader.GetAttribute( "binpathtype" );
376
 
                                                                        if ( type == null )
377
 
                                                                                if ( binpath == null )
378
 
                                                                                        currentConfig.BinPathType = BinPathType.Auto;
379
 
                                                                                else
380
 
                                                                                        currentConfig.BinPathType = BinPathType.Manual;
381
 
                                                                        else
382
 
                                                                                currentConfig.BinPathType = (BinPathType)Enum.Parse( typeof( BinPathType ), type, true );
383
 
 
384
 
                                    string runtime = reader.GetAttribute("runtimeFramework");
385
 
                                    if ( runtime != null )
386
 
                                        currentConfig.RuntimeFramework = RuntimeFramework.Parse(runtime);
387
 
 
388
 
                                    Configs.Add(currentConfig);
389
 
                                                                        if ( configName == activeConfigName )
390
 
                                                                                activeConfig = currentConfig;
391
 
                                                                }
392
 
                                                                else if ( reader.NodeType == XmlNodeType.EndElement )
393
 
                                                                        currentConfig = null;
394
 
                                                                break;
395
 
 
396
 
                                                        case "assembly":
397
 
                                                                if ( reader.NodeType == XmlNodeType.Element && currentConfig != null )
398
 
                                                                {
399
 
                                                                        string path = reader.GetAttribute( "path" );
400
 
                                                                        currentConfig.Assemblies.Add( 
401
 
                                                                                Path.Combine( currentConfig.BasePath, path ) );
402
 
                                                                }
403
 
                                                                break;
404
 
 
405
 
                                                        default:
406
 
                                                                break;
407
 
                                                }
408
 
 
409
 
                                this.IsDirty = false;
410
 
                this.reloadRequired = false;
411
 
                        }
412
 
                        catch( FileNotFoundException )
413
 
                        {
414
 
                                throw;
415
 
                        }
416
 
                        catch( XmlException e )
417
 
                        {
418
 
                                throw new ProjectFormatException(
419
 
                                        string.Format( "Invalid project format: {0}", e.Message ),
420
 
                                        e.LineNumber, e.LinePosition );
421
 
                        }
422
 
                        catch( Exception e )
423
 
                        {
424
 
                                throw new ProjectFormatException( 
425
 
                                        string.Format( "Invalid project format: {0} Line {1}, Position {2}", 
426
 
                                        e.Message, reader.LineNumber, reader.LinePosition ),
427
 
                                        reader.LineNumber, reader.LinePosition );
428
 
                        }
429
 
                        finally
430
 
                        {
431
 
                                reader.Close();
432
 
                        }
433
 
                }
434
 
 
435
 
                public void Save()
436
 
                {
437
 
                        projectPath = ProjectPathFromFile( projectPath );
438
 
 
439
 
                        XmlTextWriter writer = new XmlTextWriter(  projectPath, System.Text.Encoding.UTF8 );
440
 
                        writer.Formatting = Formatting.Indented;
441
 
 
442
 
                        writer.WriteStartElement( "NUnitProject" );
443
 
                        
444
 
                        if ( configs.Count > 0 || this.BasePath != this.DefaultBasePath )
445
 
                        {
446
 
                                writer.WriteStartElement( "Settings" );
447
 
                                if ( configs.Count > 0 )
448
 
                                        writer.WriteAttributeString( "activeconfig", ActiveConfigName );
449
 
                                if ( this.BasePath != this.DefaultBasePath )
450
 
                                        writer.WriteAttributeString( "appbase", this.BasePath );
451
 
                if (this.AutoConfig)
452
 
                    writer.WriteAttributeString("autoconfig", "true");
453
 
                if (this.ProcessModel != ProcessModel.Default)
454
 
                    writer.WriteAttributeString("processModel", this.ProcessModel.ToString());
455
 
                if (this.DomainUsage != DomainUsage.Default)
456
 
                    writer.WriteAttributeString("domainUsage", this.DomainUsage.ToString());
457
 
                                writer.WriteEndElement();
458
 
                        }
459
 
                        
460
 
                        foreach( ProjectConfig config in Configs )
461
 
                        {
462
 
                                writer.WriteStartElement( "Config" );
463
 
                                writer.WriteAttributeString( "name", config.Name );
464
 
                                string appbase = config.BasePath;
465
 
                                if ( !PathUtils.SamePathOrUnder( this.BasePath, appbase ) )
466
 
                                        writer.WriteAttributeString( "appbase", appbase );
467
 
                                else if ( config.RelativeBasePath != null )
468
 
                                        writer.WriteAttributeString( "appbase", config.RelativeBasePath );
469
 
                                
470
 
                                string configFile = config.ConfigurationFile;
471
 
                                if ( configFile != null && configFile != this.ConfigurationFile )
472
 
                                        writer.WriteAttributeString( "configfile", config.ConfigurationFile );
473
 
                                
474
 
                                if ( config.BinPathType == BinPathType.Manual )
475
 
                                        writer.WriteAttributeString( "binpath", config.PrivateBinPath );
476
 
                                else
477
 
                                        writer.WriteAttributeString( "binpathtype", config.BinPathType.ToString() );
478
 
 
479
 
                if (config.RuntimeFramework != null)
480
 
                    writer.WriteAttributeString("runtimeFramework", config.RuntimeFramework.ToString());
481
 
 
482
 
                                foreach( string assembly in config.Assemblies )
483
 
                                {
484
 
                                        writer.WriteStartElement( "assembly" );
485
 
                                        writer.WriteAttributeString( "path", PathUtils.RelativePath( config.BasePath, assembly ) );
486
 
                                        writer.WriteEndElement();
487
 
                                }
488
 
 
489
 
                                writer.WriteEndElement();
490
 
                        }
491
 
 
492
 
                        writer.WriteEndElement();
493
 
 
494
 
                        writer.Close();
495
 
                        this.IsDirty = false;
496
 
 
497
 
                        // Once we save a project, it's no longer
498
 
                        // loaded as an assembly wrapper on reload.
499
 
                        this.isAssemblyWrapper = false;
500
 
                }
501
 
 
502
 
                public void Save( string projectPath )
503
 
                {
504
 
                        this.ProjectPath = projectPath;
505
 
                        Save();
506
 
                }
507
 
                #endregion
508
 
        }
509
 
}
 
1
// ****************************************************************
 
2
// This is free software licensed under the NUnit license. You
 
3
// may obtain a copy of the license as well as information regarding
 
4
// copyright ownership at http://nunit.org.
 
5
// ****************************************************************
 
6
 
 
7
using System;
 
8
using System.Collections;
 
9
using System.Xml;
 
10
using System.Xml.Schema;
 
11
using System.IO;
 
12
using System.Threading;
 
13
using NUnit.Core;
 
14
 
 
15
namespace NUnit.Util
 
16
{
 
17
        /// <summary>
 
18
        /// Class that represents an NUnit test project
 
19
        /// </summary>
 
20
        public class NUnitProject
 
21
    {
 
22
        #region Constants
 
23
        public static readonly string Extension = ".nunit";
 
24
        #endregion
 
25
 
 
26
        #region Instance variables
 
27
 
 
28
        /// <summary>
 
29
                /// Path to the file storing this project
 
30
                /// </summary>
 
31
                private string projectPath;
 
32
 
 
33
                /// <summary>
 
34
                /// Application Base for the project. Since this
 
35
                /// can be null, always fetch from the property
 
36
                /// rather than using the field directly.
 
37
                /// </summary>
 
38
                private string basePath;
 
39
 
 
40
                /// <summary>
 
41
                ///  Whether the project is dirty
 
42
                /// </summary>
 
43
                private bool isDirty = false;
 
44
 
 
45
        /// <summary>
 
46
        /// Whether canges have been made requiring a reload
 
47
        /// </summary>
 
48
        private bool reloadRequired = false;
 
49
                
 
50
                /// <summary>
 
51
                /// Collection of configs for the project
 
52
                /// </summary>
 
53
                private ProjectConfigCollection configs;
 
54
 
 
55
        /// <summary>
 
56
        /// True for NUnit-related projects that follow the config
 
57
        /// of the NUnit build under which they are running.
 
58
        /// </summary>
 
59
        private bool autoConfig;
 
60
 
 
61
                /// <summary>
 
62
                /// The currently active configuration
 
63
                /// </summary>
 
64
                private ProjectConfig activeConfig;
 
65
 
 
66
                /// <summary>
 
67
                /// Flag indicating that this project is a
 
68
                /// temporary wrapper for an assembly.
 
69
                /// </summary>
 
70
                private bool isAssemblyWrapper = false;
 
71
 
 
72
        /// <summary>
 
73
        /// The ProcessModel to be used in loading this project
 
74
        /// </summary>
 
75
        private ProcessModel processModel;
 
76
 
 
77
        /// <summary>
 
78
        /// The DomainUsage setting to be used in loading this project
 
79
        /// </summary>
 
80
        private DomainUsage domainUsage;
 
81
 
 
82
                #endregion
 
83
 
 
84
                #region Constructor
 
85
 
 
86
                public NUnitProject( string projectPath )
 
87
                {
 
88
                        this.projectPath = Path.GetFullPath( projectPath );
 
89
                        configs = new ProjectConfigCollection( this );
 
90
                }
 
91
 
 
92
                #endregion
 
93
 
 
94
                #region Properties and Events
 
95
 
 
96
                /// <summary>
 
97
                /// The path to which a project will be saved.
 
98
                /// </summary>
 
99
                public string ProjectPath
 
100
                {
 
101
                        get { return projectPath; }
 
102
                        set 
 
103
                        {
 
104
                                projectPath = Path.GetFullPath( value );
 
105
                                isDirty = true;
 
106
                        }
 
107
                }
 
108
 
 
109
                public string DefaultBasePath
 
110
                {
 
111
                        get { return Path.GetDirectoryName( projectPath ); }
 
112
                }
 
113
 
 
114
                /// <summary>
 
115
                /// Indicates whether a base path was specified for the project
 
116
                /// </summary>
 
117
                public bool BasePathSpecified
 
118
                {
 
119
                        get
 
120
                        {
 
121
                                return basePath != null && basePath != string.Empty;
 
122
                        }
 
123
                }
 
124
 
 
125
                /// <summary>
 
126
                /// The base path for the project. Constructor sets
 
127
                /// it to the directory part of the project path.
 
128
                /// </summary>
 
129
                public string BasePath
 
130
                {
 
131
                        get 
 
132
                        { 
 
133
                                if ( !BasePathSpecified )
 
134
                                        return DefaultBasePath; 
 
135
                                return basePath;
 
136
                        }
 
137
            set
 
138
            {
 
139
                basePath = value;
 
140
 
 
141
                if (basePath != null && basePath != string.Empty
 
142
                    && !Path.IsPathRooted(basePath))
 
143
                {
 
144
                    basePath = Path.Combine(
 
145
                        DefaultBasePath,
 
146
                        basePath);
 
147
                }
 
148
 
 
149
                basePath = PathUtils.Canonicalize(basePath);
 
150
                HasChangesRequiringReload = IsDirty = true;
 
151
            }
 
152
                }
 
153
 
 
154
                /// <summary>
 
155
                /// The name of the project.
 
156
                /// </summary>
 
157
                public string Name
 
158
                {
 
159
                        get { return Path.GetFileNameWithoutExtension( projectPath ); }
 
160
                }
 
161
 
 
162
        public bool AutoConfig
 
163
        {
 
164
            get { return autoConfig; }
 
165
            set { autoConfig = value; }
 
166
        }
 
167
 
 
168
                public ProjectConfig ActiveConfig
 
169
                {
 
170
                        get 
 
171
                        { 
 
172
                                // In case the previous active config was removed
 
173
                                if ( activeConfig != null && !configs.Contains( activeConfig ) )
 
174
                                        activeConfig = null;
 
175
                                
 
176
                                // In case no active config is set or it was removed
 
177
                if (activeConfig == null && configs.Count > 0)
 
178
                    activeConfig = configs[0];
 
179
                                
 
180
                                return activeConfig; 
 
181
                        }
 
182
                }
 
183
 
 
184
                // Safe access to name of the active config
 
185
                public string ActiveConfigName
 
186
                {
 
187
                        get
 
188
                        {
 
189
                                ProjectConfig config = ActiveConfig;
 
190
                                return config == null ? null : config.Name;
 
191
                        }
 
192
                }
 
193
 
 
194
                public bool IsLoadable
 
195
                {
 
196
                        get
 
197
                        {
 
198
                                return  ActiveConfig != null &&
 
199
                                        ActiveConfig.Assemblies.Count > 0;
 
200
                        }
 
201
                }
 
202
 
 
203
                // A project made from a single assembly is treated
 
204
                // as a transparent wrapper for some purposes until
 
205
                // a change is made to it.
 
206
                public bool IsAssemblyWrapper
 
207
                {
 
208
                        get { return isAssemblyWrapper; }
 
209
                        set { isAssemblyWrapper = value; }
 
210
                }
 
211
 
 
212
                public string ConfigurationFile
 
213
                {
 
214
                        get 
 
215
                        { 
 
216
                                // TODO: Check this
 
217
                                return isAssemblyWrapper
 
218
                                          ? Path.GetFileName( projectPath ) + ".config"
 
219
                                          : Path.GetFileNameWithoutExtension( projectPath ) + ".config";
 
220
                        }
 
221
                }
 
222
 
 
223
                public bool IsDirty
 
224
                {
 
225
                        get { return isDirty; }
 
226
                        set 
 
227
            { 
 
228
                isDirty = value;
 
229
 
 
230
                if (isAssemblyWrapper && value == true)
 
231
                {
 
232
                    projectPath = Path.ChangeExtension(projectPath, ".nunit");
 
233
                    isAssemblyWrapper = false;
 
234
                    HasChangesRequiringReload = true;
 
235
                }
 
236
            }
 
237
                }
 
238
 
 
239
        public bool HasChangesRequiringReload
 
240
        {
 
241
            get { return reloadRequired; }
 
242
            set { reloadRequired = value; }
 
243
        }
 
244
 
 
245
        public ProcessModel ProcessModel
 
246
        {
 
247
            get { return processModel; }
 
248
            set
 
249
            {
 
250
                processModel = value;
 
251
                HasChangesRequiringReload = IsDirty = true;
 
252
            }
 
253
        }
 
254
 
 
255
        public DomainUsage DomainUsage
 
256
        {
 
257
            get { return domainUsage; }
 
258
            set
 
259
            {
 
260
                domainUsage = value;
 
261
                HasChangesRequiringReload = IsDirty = true;
 
262
            }
 
263
        }
 
264
 
 
265
                public ProjectConfigCollection Configs
 
266
                {
 
267
                        get { return configs; }
 
268
                }
 
269
                #endregion
 
270
 
 
271
        #region Static Methods
 
272
        public static bool IsNUnitProjectFile(string path)
 
273
        {
 
274
            return Path.GetExtension(path) == Extension;
 
275
        }
 
276
 
 
277
        public static string ProjectPathFromFile(string path)
 
278
        {
 
279
            string fileName = Path.GetFileNameWithoutExtension(path) + NUnitProject.Extension;
 
280
            return Path.Combine(Path.GetDirectoryName(path), fileName);
 
281
        }
 
282
        #endregion
 
283
 
 
284
        #region Instance Methods
 
285
 
 
286
        public void SetActiveConfig( int index )
 
287
                {
 
288
                        activeConfig = configs[index];
 
289
            HasChangesRequiringReload = IsDirty = true;
 
290
                }
 
291
 
 
292
                public void SetActiveConfig( string name )
 
293
                {
 
294
                        foreach( ProjectConfig config in configs )
 
295
                        {
 
296
                                if ( config.Name == name )
 
297
                                {
 
298
                                        activeConfig = config;
 
299
                    HasChangesRequiringReload = IsDirty = true;
 
300
                    break;
 
301
                                }
 
302
                        }
 
303
                }
 
304
 
 
305
                public void Add( VSProject vsProject )
 
306
                {
 
307
                        foreach( VSProjectConfig vsConfig in vsProject.Configs )
 
308
                        {
 
309
                                string name = vsConfig.Name;
 
310
 
 
311
                                if ( !configs.Contains( name ) )
 
312
                                        configs.Add( name );
 
313
 
 
314
                                ProjectConfig config = this.Configs[name];
 
315
 
 
316
                                foreach ( string assembly in vsConfig.Assemblies )
 
317
                                        config.Assemblies.Add( assembly );
 
318
                        }
 
319
                }
 
320
 
 
321
                public void Load()
 
322
                {
 
323
                        XmlTextReader reader = new XmlTextReader( projectPath );
 
324
 
 
325
                        string activeConfigName = null;
 
326
                        ProjectConfig currentConfig = null;
 
327
                        
 
328
                        try
 
329
                        {
 
330
                                reader.MoveToContent();
 
331
                                if ( reader.NodeType != XmlNodeType.Element || reader.Name != "NUnitProject" )
 
332
                                        throw new ProjectFormatException( 
 
333
                                                "Invalid project format: <NUnitProject> expected.", 
 
334
                                                reader.LineNumber, reader.LinePosition );
 
335
 
 
336
                                while( reader.Read() )
 
337
                                        if ( reader.NodeType == XmlNodeType.Element )
 
338
                                                switch( reader.Name )
 
339
                                                {
 
340
                                                        case "Settings":
 
341
                                                                if ( reader.NodeType == XmlNodeType.Element )
 
342
                                                                {
 
343
                                                                        activeConfigName = reader.GetAttribute( "activeconfig" );
 
344
 
 
345
                                    string autoConfig = reader.GetAttribute("autoconfig");
 
346
                                    if (autoConfig != null)
 
347
                                        this.AutoConfig = autoConfig.ToLower() == "true";
 
348
                                    if (this.AutoConfig)
 
349
                                                                                activeConfigName = NUnitConfiguration.BuildConfiguration;
 
350
                                                                        
 
351
                                    string appbase = reader.GetAttribute( "appbase" );
 
352
                                                                        if ( appbase != null )
 
353
                                                                                this.BasePath = appbase;
 
354
 
 
355
                                    string processModel = reader.GetAttribute("processModel");
 
356
                                    if (processModel != null)
 
357
                                        this.ProcessModel = (ProcessModel)Enum.Parse(typeof(ProcessModel), processModel);
 
358
 
 
359
                                    string domainUsage = reader.GetAttribute("domainUsage");
 
360
                                    if (domainUsage != null)
 
361
                                        this.DomainUsage = (DomainUsage)Enum.Parse(typeof(DomainUsage), domainUsage);
 
362
                                }
 
363
                                                                break;
 
364
 
 
365
                                                        case "Config":
 
366
                                                                if ( reader.NodeType == XmlNodeType.Element )
 
367
                                                                {
 
368
                                                                        string configName = reader.GetAttribute( "name" );
 
369
                                                                        currentConfig = new ProjectConfig( configName );
 
370
                                                                        currentConfig.BasePath = reader.GetAttribute( "appbase" );
 
371
                                                                        currentConfig.ConfigurationFile = reader.GetAttribute( "configfile" );
 
372
 
 
373
                                                                        string binpath = reader.GetAttribute( "binpath" );
 
374
                                                                        currentConfig.PrivateBinPath = binpath;
 
375
                                                                        string type = reader.GetAttribute( "binpathtype" );
 
376
                                                                        if ( type == null )
 
377
                                                                                if ( binpath == null )
 
378
                                                                                        currentConfig.BinPathType = BinPathType.Auto;
 
379
                                                                                else
 
380
                                                                                        currentConfig.BinPathType = BinPathType.Manual;
 
381
                                                                        else
 
382
                                                                                currentConfig.BinPathType = (BinPathType)Enum.Parse( typeof( BinPathType ), type, true );
 
383
 
 
384
                                    string runtime = reader.GetAttribute("runtimeFramework");
 
385
                                    if ( runtime != null )
 
386
                                        currentConfig.RuntimeFramework = RuntimeFramework.Parse(runtime);
 
387
 
 
388
                                    Configs.Add(currentConfig);
 
389
                                                                        if ( configName == activeConfigName )
 
390
                                                                                activeConfig = currentConfig;
 
391
                                                                }
 
392
                                                                else if ( reader.NodeType == XmlNodeType.EndElement )
 
393
                                                                        currentConfig = null;
 
394
                                                                break;
 
395
 
 
396
                                                        case "assembly":
 
397
                                                                if ( reader.NodeType == XmlNodeType.Element && currentConfig != null )
 
398
                                                                {
 
399
                                                                        string path = reader.GetAttribute( "path" );
 
400
                                                                        currentConfig.Assemblies.Add( 
 
401
                                                                                Path.Combine( currentConfig.BasePath, path ) );
 
402
                                                                }
 
403
                                                                break;
 
404
 
 
405
                                                        default:
 
406
                                                                break;
 
407
                                                }
 
408
 
 
409
                                this.IsDirty = false;
 
410
                this.reloadRequired = false;
 
411
                        }
 
412
                        catch( FileNotFoundException )
 
413
                        {
 
414
                                throw;
 
415
                        }
 
416
                        catch( XmlException e )
 
417
                        {
 
418
                                throw new ProjectFormatException(
 
419
                                        string.Format( "Invalid project format: {0}", e.Message ),
 
420
                                        e.LineNumber, e.LinePosition );
 
421
                        }
 
422
                        catch( Exception e )
 
423
                        {
 
424
                                throw new ProjectFormatException( 
 
425
                                        string.Format( "Invalid project format: {0} Line {1}, Position {2}", 
 
426
                                        e.Message, reader.LineNumber, reader.LinePosition ),
 
427
                                        reader.LineNumber, reader.LinePosition );
 
428
                        }
 
429
                        finally
 
430
                        {
 
431
                                reader.Close();
 
432
                        }
 
433
                }
 
434
 
 
435
                public void Save()
 
436
                {
 
437
                        projectPath = ProjectPathFromFile( projectPath );
 
438
 
 
439
                        XmlTextWriter writer = new XmlTextWriter(  projectPath, System.Text.Encoding.UTF8 );
 
440
                        writer.Formatting = Formatting.Indented;
 
441
 
 
442
                        writer.WriteStartElement( "NUnitProject" );
 
443
                        
 
444
                        if ( configs.Count > 0 || this.BasePath != this.DefaultBasePath )
 
445
                        {
 
446
                                writer.WriteStartElement( "Settings" );
 
447
                                if ( configs.Count > 0 )
 
448
                                        writer.WriteAttributeString( "activeconfig", ActiveConfigName );
 
449
                                if ( this.BasePath != this.DefaultBasePath )
 
450
                                        writer.WriteAttributeString( "appbase", this.BasePath );
 
451
                if (this.AutoConfig)
 
452
                    writer.WriteAttributeString("autoconfig", "true");
 
453
                if (this.ProcessModel != ProcessModel.Default)
 
454
                    writer.WriteAttributeString("processModel", this.ProcessModel.ToString());
 
455
                if (this.DomainUsage != DomainUsage.Default)
 
456
                    writer.WriteAttributeString("domainUsage", this.DomainUsage.ToString());
 
457
                                writer.WriteEndElement();
 
458
                        }
 
459
                        
 
460
                        foreach( ProjectConfig config in Configs )
 
461
                        {
 
462
                                writer.WriteStartElement( "Config" );
 
463
                                writer.WriteAttributeString( "name", config.Name );
 
464
                                string appbase = config.BasePath;
 
465
                                if ( !PathUtils.SamePathOrUnder( this.BasePath, appbase ) )
 
466
                                        writer.WriteAttributeString( "appbase", appbase );
 
467
                                else if ( config.RelativeBasePath != null )
 
468
                                        writer.WriteAttributeString( "appbase", config.RelativeBasePath );
 
469
                                
 
470
                                string configFile = config.ConfigurationFile;
 
471
                                if ( configFile != null && configFile != this.ConfigurationFile )
 
472
                                        writer.WriteAttributeString( "configfile", config.ConfigurationFile );
 
473
                                
 
474
                                if ( config.BinPathType == BinPathType.Manual )
 
475
                                        writer.WriteAttributeString( "binpath", config.PrivateBinPath );
 
476
                                else
 
477
                                        writer.WriteAttributeString( "binpathtype", config.BinPathType.ToString() );
 
478
 
 
479
                if (config.RuntimeFramework != null)
 
480
                    writer.WriteAttributeString("runtimeFramework", config.RuntimeFramework.ToString());
 
481
 
 
482
                                foreach( string assembly in config.Assemblies )
 
483
                                {
 
484
                                        writer.WriteStartElement( "assembly" );
 
485
                                        writer.WriteAttributeString( "path", PathUtils.RelativePath( config.BasePath, assembly ) );
 
486
                                        writer.WriteEndElement();
 
487
                                }
 
488
 
 
489
                                writer.WriteEndElement();
 
490
                        }
 
491
 
 
492
                        writer.WriteEndElement();
 
493
 
 
494
                        writer.Close();
 
495
                        this.IsDirty = false;
 
496
 
 
497
                        // Once we save a project, it's no longer
 
498
                        // loaded as an assembly wrapper on reload.
 
499
                        this.isAssemblyWrapper = false;
 
500
                }
 
501
 
 
502
                public void Save( string projectPath )
 
503
                {
 
504
                        this.ProjectPath = projectPath;
 
505
                        Save();
 
506
                }
 
507
                #endregion
 
508
        }
 
509
}