├── .gitattributes
├── .gitignore
├── AutoT4MVC.sln
├── AutoT4MVC
├── AutoT4MVC.csproj
├── AutoT4MVC.dll.config
├── AutoT4MVC.vsct
├── AutoT4MVCPackage.cs
├── Controller.cs
├── GlobalSuppressions.cs
├── Guids.cs
├── Key.snk
├── LICENCE.txt
├── Options.cs
├── PkgCmdID.cs
├── ProjectEventArgs.cs
├── ProjectItemExtensions.cs
├── Properties
│ └── AssemblyInfo.cs
├── Resources.Designer.cs
├── Resources.resx
├── T4MVCSettings.cs
├── T4MVCSettingsBuilder.cs
├── T4MVCSettingsCache.cs
├── VSPackage.resx
├── noun_project_2223.png
├── packages.config
└── source.extension.vsixmanifest
├── LICENCE.txt
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # PDT-specific
29 | .buildpath
30 |
31 |
32 | #################
33 | ## Visual Studio
34 | #################
35 |
36 | ## Ignore Visual Studio temporary files, build results, and
37 | ## files generated by popular Visual Studio add-ons.
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.sln.docstates
43 |
44 | # Build results
45 | [Dd]ebug/
46 | [Rr]elease/
47 | *_i.c
48 | *_p.c
49 | *.ilk
50 | *.meta
51 | *.obj
52 | *.pch
53 | *.pdb
54 | *.pgc
55 | *.pgd
56 | *.rsp
57 | *.sbr
58 | *.tlb
59 | *.tli
60 | *.tlh
61 | *.tmp
62 | *.vspscc
63 | .builds
64 | *.dotCover
65 |
66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this
67 | packages/
68 |
69 | # Visual C++ cache files
70 | ipch/
71 | *.aps
72 | *.ncb
73 | *.opensdf
74 | *.sdf
75 |
76 | # Visual Studio profiler
77 | *.psess
78 | *.vsp
79 |
80 | # ReSharper is a .NET coding add-in
81 | _ReSharper*
82 |
83 | # Installshield output folder
84 | [Ee]xpress
85 |
86 | # DocProject is a documentation generator add-in
87 | DocProject/buildhelp/
88 | DocProject/Help/*.HxT
89 | DocProject/Help/*.HxC
90 | DocProject/Help/*.hhc
91 | DocProject/Help/*.hhk
92 | DocProject/Help/*.hhp
93 | DocProject/Help/Html2
94 | DocProject/Help/html
95 |
96 | # Click-Once directory
97 | publish
98 |
99 | # Others
100 | [Bb]in
101 | [Oo]bj
102 | sql
103 | TestResults
104 | *.Cache
105 | ClientBin
106 | stylecop.*
107 | ~$*
108 | *.dbmdl
109 | Generated_Code #added for RIA/Silverlight projects
110 |
111 | # Backup & report files from converting an old project file to a newer
112 | # Visual Studio version. Backup files are not needed, because we have git ;-)
113 | _UpgradeReport_Files/
114 | Backup*/
115 | UpgradeLog*.XML
116 |
117 | # NCrunch
118 | *.ncrunchsolution
119 |
120 | ############
121 | ## Windows
122 | ############
123 |
124 | # Windows image file caches
125 | Thumbs.db
126 |
127 | # Folder config file
128 | Desktop.ini
129 |
130 |
131 | #############
132 | ## Python
133 | #############
134 |
135 | *.py[co]
136 |
137 | # Packages
138 | *.egg
139 | *.egg-info
140 | dist
141 | build
142 | eggs
143 | parts
144 | bin
145 | var
146 | sdist
147 | develop-eggs
148 | .installed.cfg
149 |
150 | # Installer logs
151 | pip-log.txt
152 |
153 | # Unit test / coverage reports
154 | .coverage
155 | .tox
156 |
157 | #Translations
158 | *.mo
159 |
160 | #Mr Developer
161 | .mr.developer.cfg
162 |
163 | # Mac crap
164 | .DS_Store
165 |
--------------------------------------------------------------------------------
/AutoT4MVC.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26228.9
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoT4MVC", "AutoT4MVC\AutoT4MVC.csproj", "{E25F1D10-8F69-4FD8-8032-CAFDA99934CC}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {E25F1D10-8F69-4FD8-8032-CAFDA99934CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {E25F1D10-8F69-4FD8-8032-CAFDA99934CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {E25F1D10-8F69-4FD8-8032-CAFDA99934CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {E25F1D10-8F69-4FD8-8032-CAFDA99934CC}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/AutoT4MVC/AutoT4MVC.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 15.0
5 | 11.0
6 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
7 |
8 |
9 |
10 |
11 | 4.0
12 | false
13 | publish\
14 | true
15 | Disk
16 | false
17 | Foreground
18 | 7
19 | Days
20 | false
21 | false
22 | true
23 | 0
24 | 1.0.0.%2a
25 | false
26 | true
27 |
28 |
29 |
30 |
31 | Debug
32 | AnyCPU
33 | 2.0
34 | {E25F1D10-8F69-4FD8-8032-CAFDA99934CC}
35 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
36 | Library
37 | Properties
38 | AutoT4MVC
39 | AutoT4MVC
40 | True
41 | Key.snk
42 | v4.6
43 |
44 |
45 | true
46 | full
47 | false
48 | bin\Debug\
49 | DEBUG;TRACE
50 | prompt
51 | 4
52 | True
53 |
54 |
55 | pdbonly
56 | true
57 | bin\Release\
58 | TRACE
59 | prompt
60 | 4
61 | true
62 | True
63 |
64 |
65 |
66 | False
67 |
68 |
69 | True
70 |
71 |
72 | True
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | True
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 | ..\packages\Rx-Core.2.0.21114\lib\Net45\System.Reactive.Core.dll
95 |
96 |
97 | ..\packages\Rx-Interfaces.2.0.21114\lib\Net45\System.Reactive.Interfaces.dll
98 |
99 |
100 | ..\packages\Rx-Linq.2.0.21114\lib\Net45\System.Reactive.Linq.dll
101 |
102 |
103 | ..\packages\Rx-PlatformServices.2.0.21114\lib\Net45\System.Reactive.PlatformServices.dll
104 |
105 |
106 |
107 |
108 |
109 | True
110 |
111 |
112 |
113 |
114 | {1CBA492E-7263-47BB-87FE-639000619B15}
115 | 8
116 | 0
117 | 0
118 | primary
119 | False
120 | False
121 |
122 |
123 | {00020430-0000-0000-C000-000000000046}
124 | 2
125 | 0
126 | 0
127 | primary
128 | False
129 | False
130 |
131 |
132 |
133 |
134 |
135 |
136 | Component
137 |
138 |
139 |
140 |
141 |
142 | True
143 | True
144 | Resources.resx
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 | ResXFileCodeGenerator
156 | Resources.Designer.cs
157 | Designer
158 |
159 |
160 | true
161 | VSPackage
162 | Designer
163 |
164 |
165 |
166 |
167 | true
168 |
169 |
170 | Always
171 | true
172 |
173 |
174 | Designer
175 |
176 |
177 | Designer
178 |
179 |
180 |
181 |
182 | Menus.ctmenu
183 | Designer
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 | Always
192 | true
193 |
194 |
195 |
196 |
197 | False
198 | Microsoft .NET Framework 4.5 %28x86 and x64%29
199 | true
200 |
201 |
202 | False
203 | .NET Framework 3.5 SP1 Client Profile
204 | false
205 |
206 |
207 | False
208 | .NET Framework 3.5 SP1
209 | false
210 |
211 |
212 |
213 | true
214 |
215 |
216 |
217 |
224 |
--------------------------------------------------------------------------------
/AutoT4MVC/AutoT4MVC.dll.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/AutoT4MVC/AutoT4MVC.vsct:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/AutoT4MVC/AutoT4MVCPackage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.Design;
4 | using System.Linq;
5 | using System.Runtime.InteropServices;
6 | using EnvDTE;
7 | using EnvDTE80;
8 | using Microsoft.VisualStudio;
9 | using Microsoft.VisualStudio.Shell;
10 | using Microsoft.VisualStudio.Shell.Interop;
11 |
12 | namespace AutoT4MVC
13 | {
14 | [PackageRegistration(UseManagedResourcesOnly = true)]
15 | [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
16 | [Guid(GuidList.guidAutoT4MVCPkgString)]
17 | [ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string)]
18 | [ProvideOptionPage(typeof (Options), Options.CategoryName, Options.PageName, 1000, 1001, false)]
19 | [ProvideMenuResource("Menus.ctmenu", 1)]
20 | public sealed class AutoT4MVCPackage : Package
21 | {
22 | private BuildEvents _buildEvents;
23 | private Controller _controller;
24 | private DocumentEvents _documentEvents;
25 | private DTE _dte;
26 | private ProjectItemsEvents _projectItemsEvents;
27 | private SolutionEvents _solutionEvents;
28 |
29 | private Options Options
30 | {
31 | get { return (Options)GetDialogPage(typeof (Options)); }
32 | }
33 |
34 | protected override void Initialize()
35 | {
36 | base.Initialize();
37 |
38 | _dte = GetService(typeof (SDTE)) as DTE;
39 | if (_dte == null)
40 | return;
41 |
42 | _controller = new Controller();
43 |
44 | _buildEvents = _dte.Events.BuildEvents;
45 | _buildEvents.OnBuildBegin += OnBuildBegin;
46 |
47 | _documentEvents = _dte.Events.DocumentEvents;
48 | _documentEvents.DocumentSaved += DocumentSaved;
49 |
50 | var events2 = _dte.Events as Events2;
51 | if (events2 == null)
52 | return;
53 |
54 | _projectItemsEvents = events2.ProjectItemsEvents;
55 | _projectItemsEvents.ItemAdded += ItemAdded;
56 | _projectItemsEvents.ItemRemoved += ItemRemoved;
57 | _projectItemsEvents.ItemRenamed += ItemRenamed;
58 |
59 | _solutionEvents = _dte.Events.SolutionEvents;
60 | _solutionEvents.ProjectRemoved += ProjectRemoved;
61 |
62 | var menuCommandService = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
63 | if (null != menuCommandService)
64 | {
65 | var showOptionsCommandId = new CommandID(GuidList.guidAutoT4MVCCmdSet,
66 | (int) PkgCmdIDList.cmdidShowOptions);
67 | var showOptionsMenuCommand = new OleMenuCommand(ShowOptions, showOptionsCommandId);
68 | menuCommandService.AddCommand(showOptionsMenuCommand);
69 | showOptionsMenuCommand.BeforeQueryStatus += ShowOptionsMenuCommandOnBeforeQueryStatus;
70 | }
71 | }
72 |
73 | private void ProjectRemoved(Project project)
74 | {
75 | _controller.HandleProjectUnload(project);
76 | }
77 |
78 | private void DocumentSaved(Document document)
79 | {
80 | if (!Options.RunOnSave)
81 | return;
82 |
83 | _controller.HandleContentChange(document.ProjectItem);
84 | }
85 |
86 | private void ItemRenamed(ProjectItem projectItem, string oldName)
87 | {
88 | if (!Options.RunOnSave)
89 | return;
90 |
91 | _controller.HandleNameChange(projectItem);
92 | }
93 |
94 | private void ItemRemoved(ProjectItem projectItem)
95 | {
96 | if (!Options.RunOnSave)
97 | return;
98 |
99 | _controller.HandleNameChange(projectItem);
100 | }
101 |
102 | private void ItemAdded(ProjectItem projectItem)
103 | {
104 | if (!Options.RunOnSave)
105 | return;
106 |
107 | _controller.HandleNameChange(projectItem);
108 | }
109 |
110 | private void OnBuildBegin(vsBuildScope scope, vsBuildAction action)
111 | {
112 | if (!Options.RunOnBuild)
113 | return;
114 |
115 | IEnumerable projects;
116 | switch (scope)
117 | {
118 | case vsBuildScope.vsBuildScopeProject:
119 | case vsBuildScope.vsBuildScopeBatch:
120 | projects = ((object[]) _dte.ActiveSolutionProjects).OfType();
121 | break;
122 | case vsBuildScope.vsBuildScopeSolution:
123 | default:
124 | // Sometimes when you hit F5 to run a project, VS gives the undefined value 0 as vsBuildScope,
125 | // so in this case we default to running templates for all projects
126 | projects = _dte.Solution.Projects.OfType();
127 | break;
128 | }
129 |
130 | _controller.RunTemplates(projects);
131 | }
132 |
133 | private void ShowOptionsMenuCommandOnBeforeQueryStatus(object sender, EventArgs eventArgs)
134 | {
135 | var showOptionsMenuCommand = sender as OleMenuCommand;
136 | if (showOptionsMenuCommand == null)
137 | return;
138 |
139 | var monitorSelection = (IVsMonitorSelection)GetGlobalService(typeof(SVsShellMonitorSelection));
140 | IntPtr hierarchyPtr;
141 | IntPtr selectionContainerPtr;
142 | uint projectItemId;
143 | IVsMultiItemSelect mis;
144 | monitorSelection.GetCurrentSelection(out hierarchyPtr, out projectItemId, out mis, out selectionContainerPtr);
145 |
146 | var hierarchy = Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)) as IVsHierarchy;
147 | if (hierarchy == null)
148 | return;
149 |
150 | object value;
151 | hierarchy.GetProperty(projectItemId, (int)__VSHPROPID.VSHPROPID_Name, out value);
152 |
153 | showOptionsMenuCommand.Visible = string.Equals(value as string, "T4MVC.tt", StringComparison.OrdinalIgnoreCase);
154 | }
155 |
156 | private void ShowOptions(object sender, EventArgs e)
157 | {
158 | ShowOptionPage(typeof(Options));
159 | }
160 |
161 | protected override int QueryClose(out bool canClose)
162 | {
163 | int result = base.QueryClose(out canClose);
164 | if (!canClose)
165 | return result;
166 |
167 | if (_solutionEvents != null)
168 | {
169 | _solutionEvents.ProjectRemoved -= ProjectRemoved;
170 | _solutionEvents = null;
171 | }
172 | if (_buildEvents != null)
173 | {
174 | _buildEvents.OnBuildBegin -= OnBuildBegin;
175 | _buildEvents = null;
176 | }
177 | if (_documentEvents != null)
178 | {
179 | _documentEvents.DocumentSaved -= DocumentSaved;
180 | _documentEvents = null;
181 | }
182 | if (_projectItemsEvents != null)
183 | {
184 | _projectItemsEvents.ItemAdded -= ItemAdded;
185 | _projectItemsEvents.ItemRemoved -= ItemRemoved;
186 | _projectItemsEvents.ItemRenamed -= ItemRenamed;
187 | }
188 | if (_controller != null)
189 | _controller.Dispose();
190 |
191 | return result;
192 | }
193 | }
194 | }
--------------------------------------------------------------------------------
/AutoT4MVC/Controller.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using EnvDTE;
9 | using System.Reactive.Linq;
10 | using VSLangProj;
11 |
12 | namespace AutoT4MVC
13 | {
14 | public sealed class Controller : IDisposable
15 | {
16 | private event EventHandler Update;
17 |
18 | private IDisposable _projectSubscription;
19 | private readonly T4MVCSettingsCache _settingsCache;
20 |
21 | public Controller()
22 | {
23 | _settingsCache = new T4MVCSettingsCache();
24 |
25 | _projectSubscription = Observable.FromEventPattern(e => Update += e, e => Update -= e)
26 | .Select(e => e.EventArgs.Project)
27 | .GroupBy(p => p)
28 | .SelectMany(g => g.Throttle(TimeSpan.FromSeconds(1)))
29 | .Subscribe(RunTemplate);
30 | }
31 |
32 | public void HandleNameChange(ProjectItem item)
33 | {
34 | var reloadSettings = T4MVCSettings.RequiresCacheInvalidation(item);
35 |
36 | var settings = _settingsCache.GetSettings(item, reloadSettings);
37 |
38 | if (settings == null)
39 | return;
40 |
41 | if (settings.TriggerOnNameChange(item))
42 | Update(this, new ProjectEventArgs(item.ContainingProject));
43 | }
44 |
45 | public void HandleContentChange(ProjectItem item)
46 | {
47 | var reloadSettings = T4MVCSettings.RequiresCacheInvalidation(item);
48 |
49 | var settings = _settingsCache.GetSettings(item, reloadSettings);
50 |
51 | if (settings == null)
52 | return;
53 |
54 | if (settings.TriggerOnContentChange(item))
55 | Update(this, new ProjectEventArgs(item.ContainingProject));
56 | }
57 |
58 | public void HandleProjectUnload(Project project)
59 | {
60 | _settingsCache.InvalidateSettings(project);
61 | }
62 |
63 | public void RunTemplates(IEnumerable projects)
64 | {
65 | if (projects == null)
66 | return;
67 |
68 | var templates = projects.Where(p => p != null).FindProjectItems("T4MVC.tt");
69 | foreach (var template in templates)
70 | {
71 | var templateVsProjectItem = template.Object as VSProjectItem;
72 | if (templateVsProjectItem != null)
73 | {
74 | templateVsProjectItem.RunCustomTool();
75 | }
76 | else
77 | {
78 | if (!template.IsOpen)
79 | template.Open();
80 | template.Save();
81 | }
82 | }
83 | }
84 | public void RunTemplate(Project project)
85 | {
86 | if (project == null)
87 | return;
88 |
89 | RunTemplates(new[] { project });
90 | }
91 |
92 | public void Dispose()
93 | {
94 | if (_projectSubscription != null)
95 | {
96 | _projectSubscription.Dispose();
97 | _projectSubscription = null;
98 | }
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/AutoT4MVC/GlobalSuppressions.cs:
--------------------------------------------------------------------------------
1 | // This file is used by Code Analysis to maintain SuppressMessage
2 | // attributes that are applied to this project. Project-level
3 | // suppressions either have no target or are given a specific target
4 | // and scoped to a namespace, type, member, etc.
5 | //
6 | // To add a suppression to this file, right-click the message in the
7 | // Error List, point to "Suppress Message(s)", and click "In Project
8 | // Suppression File". You do not need to add suppressions to this
9 | // file manually.
10 |
11 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1017:MarkAssembliesWithComVisible")]
12 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Scope = "type", Target = "AutoT4MVC.AutoT4MVCPackage")]
13 |
--------------------------------------------------------------------------------
/AutoT4MVC/Guids.cs:
--------------------------------------------------------------------------------
1 | // Guids.cs
2 | // MUST match guids.h
3 | using System;
4 |
5 | namespace AutoT4MVC
6 | {
7 | static class GuidList
8 | {
9 | public const string guidAutoT4MVCPkgString = "c676817c-46cc-47d3-b03c-8a05f499d4a5";
10 | public const string guidAutoT4MVCCmdSetString = "3e7abe3a-4955-4c2f-aef7-4672394b69fd";
11 |
12 | public static readonly Guid guidAutoT4MVCCmdSet = new Guid(guidAutoT4MVCCmdSetString);
13 | };
14 | }
--------------------------------------------------------------------------------
/AutoT4MVC/Key.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennor/AutoT4MVC/c375e47736372a7409666f1b3ce68d52ce06d584/AutoT4MVC/Key.snk
--------------------------------------------------------------------------------
/AutoT4MVC/LICENCE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Bennor McCarthy
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/AutoT4MVC/Options.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using Microsoft.VisualStudio.Shell;
3 |
4 | namespace AutoT4MVC
5 | {
6 | public class Options : DialogPage
7 | {
8 | private bool _runOnSave = true;
9 | private bool _runOnBuild = true;
10 |
11 | public const string CategoryName = "AutoT4MVC";
12 | public const string PageName = "General";
13 |
14 | [Category("General")]
15 | [DisplayName("Run on save")]
16 | [Description("Run T4MVC templates when files in the Controllers, Views, Scripts and Content folders are saved, created or deleted.")]
17 | [DefaultValue(true)]
18 | public bool RunOnSave
19 | {
20 | get { return _runOnSave; }
21 | set { _runOnSave = value; }
22 | }
23 |
24 | [Category("General")]
25 | [DisplayName("Run on build")]
26 | [Description("Run T4MVC templates when building.")]
27 | [DefaultValue(true)]
28 | public bool RunOnBuild
29 | {
30 | get { return _runOnBuild; }
31 | set { _runOnBuild = value; }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/AutoT4MVC/PkgCmdID.cs:
--------------------------------------------------------------------------------
1 | namespace AutoT4MVC
2 | {
3 | static class PkgCmdIDList
4 | {
5 | public const uint cmdidShowOptions = 0x100;
6 | };
7 | }
--------------------------------------------------------------------------------
/AutoT4MVC/ProjectEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using EnvDTE;
4 |
5 | namespace AutoT4MVC
6 | {
7 | public class ProjectEventArgs : EventArgs
8 | {
9 | public Project Project { get; private set; }
10 |
11 | public ProjectEventArgs(Project project)
12 | {
13 | if (project == null)
14 | throw new ArgumentNullException("project");
15 |
16 | Project = project;
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/AutoT4MVC/ProjectItemExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices;
6 | using EnvDTE;
7 |
8 | namespace AutoT4MVC
9 | {
10 | public static class ProjectItemExtensions
11 | {
12 | public static IEnumerable FindProjectItems(this Project project, string name)
13 | {
14 | return project.ProjectItems.FindProjectItems(name);
15 | }
16 |
17 | public static IEnumerable FindProjectItems(this IEnumerable projects, string name)
18 | {
19 | return projects.SelectMany(project => project.ProjectItems.FindProjectItems(name));
20 | }
21 |
22 | private static IEnumerable FindProjectItems(this ProjectItems projectItems, string name)
23 | {
24 | foreach (ProjectItem projectItem in projectItems)
25 | {
26 | if (StringComparer.OrdinalIgnoreCase.Equals(projectItem.Name, name))
27 | yield return projectItem;
28 |
29 | if (projectItem.ProjectItems != null)
30 | {
31 | foreach (var subItem in projectItem.ProjectItems.FindProjectItems(name))
32 | yield return subItem;
33 | }
34 | if (projectItem.SubProject != null)
35 | {
36 | foreach (var subItem in projectItem.SubProject.ProjectItems.FindProjectItems(name))
37 | yield return subItem;
38 | }
39 | }
40 | }
41 |
42 | public static bool HasProject(this ProjectItem projectItem)
43 | {
44 | if (projectItem == null)
45 | throw new ArgumentNullException("projectItem");
46 |
47 | return projectItem.ContainingProject != null
48 | && !string.Equals(projectItem.ContainingProject.Name, "Miscellaneous Files",
49 | StringComparison.OrdinalIgnoreCase);
50 | }
51 |
52 | public static bool MatchesAnyPathFragment(this ProjectItem projectItem, IList pathFragments)
53 | {
54 | if (projectItem == null)
55 | throw new ArgumentNullException("projectItem");
56 |
57 | if (pathFragments == null)
58 | return false;
59 |
60 | return projectItem.GetFileNames()
61 | .Any(fileName =>
62 | pathFragments.Any(p =>
63 | fileName.IndexOf(p, StringComparison.OrdinalIgnoreCase) > -1));
64 | }
65 |
66 | public static IEnumerable GetFileNames(this ProjectItem item)
67 | {
68 | var projectFolderPath = item.HasProject()
69 | ? Path.GetDirectoryName(item.ContainingProject.FullName)
70 | : null;
71 |
72 | return Enumerable.Range(0, item.FileCount).Select(i =>
73 | {
74 | try
75 | {
76 | string fileName = item.FileNames[(short)i];
77 |
78 | if (projectFolderPath != null)
79 | fileName = fileName.Replace(projectFolderPath, "");
80 |
81 | return fileName;
82 | }
83 | catch (COMException) { return null; /* Ignore invalid exceptions */ }
84 | }).Where(f => !string.IsNullOrWhiteSpace(f));
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/AutoT4MVC/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using System.Resources;
4 | using System.Runtime.CompilerServices;
5 | using System.Runtime.InteropServices;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("AutoT4MVC")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("Bennor McCarthy")]
14 | [assembly: AssemblyProduct("AutoT4MVC")]
15 | [assembly: AssemblyCopyright("")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 | [assembly: ComVisible(false)]
19 | [assembly: CLSCompliant(false)]
20 | [assembly: NeutralResourcesLanguage("en-US")]
21 |
22 | // Version information for an assembly consists of the following four values:
23 | //
24 | // Major Version
25 | // Minor Version
26 | // Build Number
27 | // Revision
28 | //
29 | // You can specify all the values or you can default the Revision and Build Numbers
30 | // by using the '*' as shown below:
31 |
32 | [assembly: AssemblyVersion("1.5.3.0")]
33 | [assembly: AssemblyFileVersion("1.5.3.0")]
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/AutoT4MVC/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace AutoT4MVC {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AutoT4MVC.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/AutoT4MVC/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 | text/microsoft-resx
119 |
120 |
121 | 2.0
122 |
123 |
124 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
125 |
126 |
127 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
128 |
129 |
--------------------------------------------------------------------------------
/AutoT4MVC/T4MVCSettings.cs:
--------------------------------------------------------------------------------
1 | using EnvDTE;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 |
6 | namespace AutoT4MVC
7 | {
8 | public class T4MVCSettings
9 | {
10 | private static readonly string[] SettingsFileNames =
11 | {
12 | @"\T4MVC.tt.settings.xml",
13 | @"\T4MVC.tt.settings.t4"
14 | };
15 |
16 | public string ControllersFolder { get; set; }
17 | public string ViewsRootFolder { get; set; }
18 |
19 | public List NonQualifiedViewFolders { get; set; }
20 | public List StaticFilesFolders { get; set; }
21 | public List ExcludedStaticFileExtensions { get; set; }
22 | public List ExcludedViewExtensions { get; set; }
23 |
24 | private bool TriggerAlways(ProjectItem item)
25 | {
26 | return IsSettingsFile(item);
27 | }
28 |
29 | public bool TriggerOnNameChange(ProjectItem item)
30 | {
31 | if (TriggerAlways(item))
32 | return true;
33 |
34 | var contentType = GetContentType(item);
35 |
36 | switch (contentType)
37 | {
38 | case T4ContentType.Controller:
39 | case T4ContentType.View:
40 | case T4ContentType.StaticContent:
41 | return true;
42 | default:
43 | return false;
44 | }
45 | }
46 |
47 | public bool TriggerOnContentChange(ProjectItem item)
48 | {
49 | if (TriggerAlways(item))
50 | return true;
51 |
52 | var contentType = GetContentType(item);
53 |
54 | switch (contentType)
55 | {
56 | case T4ContentType.Controller:
57 | return true;
58 | default:
59 | return false;
60 | }
61 | }
62 |
63 | private static bool IsSettingsFile(ProjectItem item)
64 | {
65 | return item.GetFileNames()
66 | .Any(fileName => SettingsFileNames
67 | .Any(settingFilename => fileName.EndsWith(settingFilename, StringComparison.InvariantCultureIgnoreCase)));
68 | }
69 |
70 | public static bool RequiresCacheInvalidation(ProjectItem item)
71 | {
72 | return IsSettingsFile(item);
73 | }
74 |
75 | private enum T4ContentType
76 | {
77 | Controller,
78 | View,
79 | StaticContent,
80 | Unknown
81 | }
82 |
83 | private T4ContentType GetContentType(ProjectItem item)
84 | {
85 | var fileNames = item.GetFileNames();
86 |
87 | foreach (var fileName in fileNames)
88 | {
89 | if (fileName.IndexOf(this.ControllersFolder, StringComparison.InvariantCultureIgnoreCase) >= 0
90 | && fileName.EndsWith(".cs", StringComparison.InvariantCultureIgnoreCase))
91 | return T4ContentType.Controller;
92 |
93 | if (fileName.IndexOf(this.ViewsRootFolder, StringComparison.InvariantCultureIgnoreCase) >= 0
94 | && ExcludedViewExtensions.All(ee => !fileName.EndsWith(ee, StringComparison.InvariantCultureIgnoreCase))
95 | && NonQualifiedViewFolders.All(nq => fileName.IndexOf(nq, StringComparison.InvariantCultureIgnoreCase) < 0))
96 | return T4ContentType.View;
97 |
98 | if (StaticFilesFolders.Any(sff => fileName.StartsWith(sff, StringComparison.InvariantCultureIgnoreCase))
99 | && ExcludedStaticFileExtensions.All(ee => !fileName.EndsWith(ee, StringComparison.InvariantCultureIgnoreCase)))
100 | return T4ContentType.StaticContent;
101 | }
102 | return T4ContentType.Unknown;
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/AutoT4MVC/T4MVCSettingsBuilder.cs:
--------------------------------------------------------------------------------
1 | using EnvDTE;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Xml;
7 | using System.Xml.Linq;
8 |
9 | namespace AutoT4MVC
10 | {
11 | public static class T4MVCSettingsBuilder
12 | {
13 | public static T4MVCSettings BuildDefault()
14 | {
15 | return new T4MVCSettings()
16 | {
17 | ControllersFolder = @"\Controllers\",
18 | ViewsRootFolder = @"\Views\",
19 | NonQualifiedViewFolders = new List(){
20 | @"\DisplayTemplates\",
21 | @"\EditorTemplates\"
22 | },
23 | StaticFilesFolders = new List(){
24 | @"\Scripts\",
25 | @"\Content\"
26 | },
27 | ExcludedStaticFileExtensions = new List(){
28 | ".cs",
29 | ".cshtml",
30 | ".aspx",
31 | ".ascx"
32 | },
33 | ExcludedViewExtensions = new List()
34 | {
35 | ".master",
36 | ".js",
37 | ".css"
38 | }
39 | };
40 | }
41 |
42 | public static T4MVCSettings Build(Project settingsProject)
43 | {
44 | var t4MVCTemplate = settingsProject.FindProjectItems("T4MVC.tt").FirstOrDefault();
45 |
46 | // No T4MVC Template
47 | if (t4MVCTemplate == null)
48 | return null;
49 |
50 | // Find Settings XML
51 | var settingsProjectItem = settingsProject.FindProjectItems("T4MVC.tt.settings.xml").FirstOrDefault();
52 |
53 | // Return default settings if no XML settings file found
54 | if (settingsProjectItem == null)
55 | return BuildDefault();
56 | else
57 | return Build(settingsProjectItem);
58 | }
59 |
60 | public static T4MVCSettings Build(ProjectItem settingsProjectItem)
61 | {
62 | if (!settingsProjectItem.Name.Equals("T4MVC.tt.settings.xml", StringComparison.InvariantCultureIgnoreCase))
63 | throw new ArgumentException("Not a valid T4MVC Settings File", "SettingsProjectItem");
64 |
65 | var settingsFileName = settingsProjectItem.FileNames[0];
66 |
67 | if (settingsFileName == null
68 | || !File.Exists(settingsFileName))
69 | return null;
70 |
71 | XDocument xDocument;
72 | try
73 | {
74 | xDocument = XDocument.Load(settingsFileName);
75 | }
76 | catch (XmlException)
77 | {
78 | // Unable to load T4MVC XML Settings File
79 | return null;
80 | }
81 |
82 | var settings = T4MVCSettingsBuilder.BuildDefault();
83 |
84 | // Controllers Folder
85 | var controllersFolderValue = xDocument.Descendants("ControllersFolder").Select(e => string.Format(@"\{0}\", e.Value)).FirstOrDefault();
86 | if (controllersFolderValue != null)
87 | settings.ControllersFolder = controllersFolderValue;
88 |
89 | // Views Root Folder
90 | var viewsRootFolderValue = xDocument.Descendants("ViewsRootFolder").Select(e => string.Format(@"\{0}\", e.Value)).FirstOrDefault();
91 | if (viewsRootFolderValue != null)
92 | settings.ViewsRootFolder = viewsRootFolderValue;
93 |
94 | // Non Qualified View Folders
95 | var nonQualifiedViewFoldersNode = xDocument.Descendants("NonQualifiedViewFolders").FirstOrDefault();
96 | if (nonQualifiedViewFoldersNode != null)
97 | settings.NonQualifiedViewFolders = nonQualifiedViewFoldersNode.Elements("ViewFolder").Select(e => string.Format(@"\{0}\", e.Value)).ToList();
98 |
99 | // Static Files Folders
100 | var staticFilesFoldersNode = xDocument.Descendants("StaticFilesFolders").FirstOrDefault();
101 | if (staticFilesFoldersNode != null)
102 | settings.StaticFilesFolders = staticFilesFoldersNode.Elements("FileFolder").Select(e => string.Format(@"\{0}\", e.Value)).ToList();
103 |
104 | // Excluded Static File Extensions
105 | var excludedStaticFileExtensionsNode = xDocument.Descendants("ExcludedStaticFileExtensions").FirstOrDefault();
106 | if (excludedStaticFileExtensionsNode != null)
107 | settings.ExcludedStaticFileExtensions = excludedStaticFileExtensionsNode.Elements("Extension").Select(e => e.Value).ToList();
108 |
109 | // Excluded View Extensions
110 | var excludedViewExtensionsNode = xDocument.Descendants("ExcludedViewExtensions").FirstOrDefault();
111 | if (excludedViewExtensionsNode != null)
112 | settings.ExcludedViewExtensions = excludedViewExtensionsNode.Elements("Extension").Select(e => e.Value).ToList();
113 |
114 | return settings;
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/AutoT4MVC/T4MVCSettingsCache.cs:
--------------------------------------------------------------------------------
1 | using EnvDTE;
2 | using System.Collections.Concurrent;
3 |
4 | namespace AutoT4MVC
5 | {
6 | public class T4MVCSettingsCache
7 | {
8 | private readonly ConcurrentDictionary _projectT4MVCSettings;
9 |
10 | public T4MVCSettingsCache()
11 | {
12 | _projectT4MVCSettings = new ConcurrentDictionary();
13 | }
14 |
15 | public T4MVCSettings GetSettings(Project project)
16 | {
17 | T4MVCSettings settings;
18 |
19 | // Try from Cache
20 | if (_projectT4MVCSettings.TryGetValue(project, out settings))
21 | return settings;
22 |
23 | // Building Settings
24 | settings = T4MVCSettingsBuilder.Build(project);
25 |
26 | // Cache
27 | _projectT4MVCSettings.TryAdd(project, settings);
28 |
29 | return settings;
30 | }
31 | public T4MVCSettings GetSettings(Project project, bool forceReload)
32 | {
33 | if (forceReload)
34 | InvalidateSettings(project);
35 |
36 | return GetSettings(project);
37 | }
38 |
39 | public T4MVCSettings GetSettings(ProjectItem projectItem)
40 | {
41 | if (projectItem.HasProject())
42 | return GetSettings(projectItem.ContainingProject);
43 | else
44 | return null;
45 | }
46 | public T4MVCSettings GetSettings(ProjectItem projectItem, bool forceReload)
47 | {
48 | if (forceReload)
49 | InvalidateSettings(projectItem.ContainingProject);
50 |
51 | return GetSettings(projectItem);
52 | }
53 |
54 | public bool InvalidateSettings(Project project)
55 | {
56 | T4MVCSettings settings;
57 |
58 | return _projectT4MVCSettings.TryRemove(project, out settings);
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/AutoT4MVC/VSPackage.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | AutoT4MVC
122 |
123 |
124 | An extension for Visual Studio 2012/2013 which will automatically run your T4MVC templates at build time and when you create/remove/rename/save a file that T4MVC cares about.
125 |
126 |
--------------------------------------------------------------------------------
/AutoT4MVC/noun_project_2223.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennor/AutoT4MVC/c375e47736372a7409666f1b3ce68d52ce06d584/AutoT4MVC/noun_project_2223.png
--------------------------------------------------------------------------------
/AutoT4MVC/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AutoT4MVC/source.extension.vsixmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AutoT4MVC
6 | An extension for Visual Studio which automatically runs your T4MVC templates at build time and when you create/remove/rename/save a file that T4MVC cares about.
7 | http://bennor.github.io/AutoT4MVC/
8 | LICENCE.txt
9 | https://github.com/bennor/AutoT4MVC/releases
10 | noun_project_2223.png
11 | T4MVC
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/LICENCE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Bennor McCarthy
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # What's this for?
2 |
3 | There used to be [a really sweet macro](http://stackoverflow.com/questions/2341717/can-you-do-a-runcustomtool-with-envdte-as-a-pre-build-event) for Visual Studio that would automatically run [T4MVC](http://t4mvc.codeplex.com) templates on build. Unfortunately, macro support has been removed from Visual Studio 2012+, so this is an extension that will do the same thing (and more).
4 |
5 | T4MVC templates are run under the following conditions (all string comparisons are case-insensitive):
6 |
7 | * a project or solution containing the template is built
8 | * a file in a "Controllers" folder is saved (in the same project)
9 | * the settings file "T4MVC.tt.settings.xml" (or "T4MVC.tt.settings.t4") is saved (in the same project)
10 | * a file is added/removed/renamed in a folder named "Assets", "Content", "Controllers", "CSS", "Images", "JS", "Scripts", "Styles" or "Views" (in the same project)
11 |
12 | Note: Drag/drop in the Solution Explorer will not trigger the templates to re-run, as the added/removed events are not fired.
13 |
14 | [Chirpy](http://chirpy.codeplex.com/) and [AutoTT](https://github.com/MartinF/Dynamo.AutoTT) do similar things, but Chirpy is overkill if all you want is your T4MVC templates built and I think AutoTT requires configuration.
15 |
16 | Just build and install the template using the VSIX file, [grab it from the Visual Studio gallery](http://visualstudiogallery.msdn.microsoft.com/8d820b76-9fc4-429f-a95f-e68ed7d3111a) or **do it the easy way** and use the 'Extension & Updates' manager in Visual Studio 2012, 2013, 2015 or 2017.
--------------------------------------------------------------------------------