How to reorganize the folder structure of my units in Delphi? - delphi

I started a prototype with Delphi with all source files under one single directory.
Now, I want to reorganize everything with folders.
I found two way to do this.
1/ First is to open each unit in Delphi IDE and Save as the new folder. Then delete the old unit file.
2/ Under windows explorer, reorganize everything, then open the project in Delphi IDE, remove reference to old (unknown) units, and then add each unit folder by folder.
As I have 100+ units, it is really painful, whatever method I use (1 or 2).
How are you doing such reorganization ?
Did I miss a feature ?

I didn't check for XE, but in XE2 this is quite easy to do inside the IDE:
in case of multiple projects have all projects in one project group
in the project manager for each unit do
rename the unit by pressing F2 or use the context menu
while renaming place the subfolder in front of the unit name (e.g test\Unit1.pas)
The IDE will move the unit (removing the old one) and promote this change to all projects in the project group.

Do you really need all 100+ units to be named in the project? Are not some of them simply common functions which could be placed in a folder on the search path? Delete all the less frequently needed units from the project and place them in folders to suit your logic. The IDE will find them, and you can also right-click open them in the IDE when you need to, without their being named in the project with a fixed path.

The simplest way is:
Copy project files to folders where you want them to be;
Edit project *.dpr file to remove all in ..;
Edit project options and add paths to project folders to search path option (not global IDE default project options, but your project's options).

Only 2nd option. Move files to new directories using TotalCommander, Windows Explorer etc. I think your source layout should look like:
myutils
libs
crypto
database
network
and then add those directories:
myutils;libs\crypto;libs\database;libs\network
to your Unit Search Path

Related

Adding existent files to Delphi Project and switch them between branches

I have more than one branch of my source code (Dev - Tst - Main) for each Delphi project, but also, I have the same structure for the folder where I have my base files. The base files are units that I share in most of my projects.
The problem I´m facing, is that I need to change between branches of this folder, and its really tedious to change the path manually.
For example:
The folder Main contains all the units from my Main branch.
If I want switch to the Tst branch, I need to change the folder from Main to Tst.
For this, I have to remove ..\Main\ATestUnit.pas from my project and add ..\Tst\ATestUnit.pas.
The issue I´m facing is that I have lots of units in this folder, and some of them, have dependency between them. Adding these by hand, becomes a really tedious task.
I was thinking that there might be some other solution. Using some predefined configuration in the Delphi IDE where I can switch between directories easily.
Is there any way to do this? Like setting paths in the configuration of the program? The kind of configuration that we do in debug or release options.

How to keep dcu files in per project folder (e.g.: .\$(Platform)\$(Config)\$(ProjectFilename)?

I have lot of Delphi projects in a project group. I can set Unit output directory to .\$(Platform)\$(Config) and all dcu files will keep in the directory according to platform and config value.
In my build environment, I would like to set the Unit output directory to something like .\$(Platform)\$(Config)\$(ProjectFilename) so all DCU files shall keep in it's own directory identified by current project file.
The Build Events in Project | Options has $(ProjectFilename) macro but I can't use it in Unit output directory.
I want to set .\$(Platform)\$(Config)\$(ProjectFilename) to all projects' Unit output directory and it will keep all DCU files in unique project directory.
I found this answer coincidentally. I pick one project and (ms)build with verbosity of diagnostic. By studying the output of msbuild, I simply pick a variable: MSBuildProjectName and specify in my optset file shared by 300 projects:
<DCC_DcuOutput>.\$(Platform)\$(Config)\$(MSBuildProjectName)</DCC_DcuOutput>
And I try build all projects in IDE. Amazingly, Delphi create folders for each project built and keep the DCU files in the folders respectively.
The Build Events pre-processors supports a range of macros, some of which are equivalent to some environment variables.
The DCU Output folder setting supports only environment variables and not these macros.
Possible Alternative Approach
To get a per-project DCU folder you can take a different approach, making dcu a subfolder of the current project, e.g.:
Unit Output Directory: .\dcu
(or perhaps just "dcu", but I prefer to include the ".\" if only to make it clear that the relative setting is intentional)
This achieves the objective of keeping the DCU's for each project separate from each other, but means you no longer have all DCU's in a separate location outside of the project folder.
You can of course still use the $(platform) and $(config) variables in this relative path, if this is important to you:
Unit Output Directory: .\dcu\$(platform)\$(config)
Whether this is an acceptable compromise only you can say in your situation.
Often the intention of keeping DCU's in a location other than the project folder is to:
keep the project folder "clean"
avoid having to maintain a long list of "ignore" entries for each dcu file in VCS (SubVersion/Git etc)
Keeping DCU's in a project subfolder achieves the first of these, and the second issue is much simplified by being able to add just the DCU subfolder to the VCS ignore list, to ignore any file in that DCU folder.

How to rename C++ source files in Visual Studio 2003?

I have several C++ projects in a few separate solutions in Visual Studio 2003.
I need to rename several of the directories and source-code files in these projects.
How do I rename directories and source files such that VS will recognise the new names?
If I change file names in the OS, VS ignores them. It still shows the old file names in the Solution Explorer, and double-clicking those produces an error message (something like "Could not complete the operation").
The Solution Explorer doesn't seem to provide any way to rename files.
I can select a file and see properties such as what file-system path it points to, but I can't change any of those properties.
I'm not using integrated source control.
I solved the problem in a few ways.
If I rename a directory containing a project used in a solution, I can either edit the SLN file directly, or open the solution in Visual Studio, then remove and re-add affected projects.
If I rename a source file used by a project, I can edit the VCPROJ file, as this contains the paths of all source files in that project.
I also had to check all projects for "Additional Include Directories" and "Additional Library Directories". Some of these referenced renamed directories.
I eventually fixed most of these using a separate text editor's "Find in Files" function to find directory references. This was faster than using the VS UI to check properties of each project.

TFS Linked Files Not Found

I have a core project and several sub projects. I link to files in the core project for the sub ones. I righted clicked my csproj and said existing file > add > link. Here is how my project looks:
Here is a picture of my Windows Explorer:
When I check in, I receive this error:
Could not find file C:\Users\joe_a84\Documents\JMASoftware\QuickBooks\Main\Source\Platform Support\NOP\Source\Versions\nop265\Nop265\Module\QuickBooksSettings.cs
The file does not exist there because it is linked. How can I tell TFS that it's a linked file?
There is the following question which states that symbolic links are not supported in TFS 2008 or TFS 2010. Symbolic links in TFS 2010 Source Control?
However, I did find the following ancient blog post which seems to show how to do it for TFS 2005: http://blogs.msdn.com/b/ericlee/archive/2006/07/20/sharing-files-in-team-foundation-server.aspx
That said I would highly recommend that you simply don't do this.
If you really need to share a file between projects then you should be using the branching functionality built into TFS. Typically you don't want just a single code file due to namespace and assembly generation concerns. It is much cleaner, and certainly easier to maintain, by having a separate project for those artifacts that are passed around. This way you either branch the entire assembly project; or just refer to it in it's normal place.
This is a local file level linking by another project. There is only one file at a specific subfolder. Other projects can link to the file via this approach. The problem with this approach is that from TFS viewpoint, you cannot tell if a file is shared by other projects. A good practice will be to keep such files in separate folder with name like Common or Shared etc.
People who have been using File linking across branches in Source Control would have to change their approach quite differently.
Linking between files in TFS is pretty simple. You just open the "Add existing item" dialog and search for the file you want to link in your local workspace. If you would click "Add" now Visual Studio would create a copy of the file in your projects directory. What you do instead is to choose the other option (you have a little drop down menu on the button) and add the item as a link. Thats it.
I faced the same problem. I just did undo on the file which was showing this error in the TFS Pending Changes window and checked-in. This undo did not remove the link that was added in the project. Make sure you do not undo the project file.

How do you share scripts among multiple projects in one solution?

In case the question wasn't clear. I have 3 MVC projects in one Solution. Every time I create a new project it adds the "Scripts" folder with all the .js files I'll ever need. I don't want to have this created every time for every application. Is there a way to reference scripts from a central folder in the solution so all applications/projects can share one common script folder with all the scripts common among them?
Edit:
Please explain the pros and cons of doing this if there are any...now I'm curious.
Here is what I would recommend:
Right click the solution and create a New Solution Folder called Common Javascript Files (or whatever you feel like calling it.
Right click on the Solution, click Open Folder in Windows Explorer,
or navigate there manually for other versions of Visual Studio :(
In the solution directory, create a directory with the same name as the solution folder (solution folders do not normally match directories at the source code level but this will for sanity sake).
In this new directory, add files that need to be shared between solutions.
In Visual Studio, click the solution folder and select Add - Existing Item.
In the file selection dialog, navigate to the directory previous created, select the file(s) added to the directory and click Add.
In each Project that needs a shared file, right click on the project (or directory within the project) and click Add - Existing Item.
Navigate to the shared Directory, Select the files and click the drop down arrow then click Add As Link.
Now the files in the projects are essentially short cuts to the files in the Solution Folder. But they are treated as actual files in the project (this includes .CS or Visual Basic files, they will be compiled as files that actually exist in the project).
PROS
Files are truly shared across projects at Design time
Only the files needed for each project can be added, it's not all or nothing
Does not require any configuration in IIS (virtual directory etc)
If the solution is in TFS Source control, you can add the Directory to the TFS Source and the shared files will be source controlled.
Editing a file by selecting it in the Project, will edit the actual file.
Deleting a Linked file does not delete the file.
This is not limited to JS files, linked files can be ANY file you might need (Images, Css, Xml, CS, CSHTML, etc)
CONS
Each deployment gets it's own file.
There is a small learning curve when understanding that Solution Folders are not Directories that exist in a Solution Directory.
The best thing to do, imo, is to roll your own CDN... Basically just create another site in IIS and give it it's own binding, e.g. "http://cdn.somedomain.com"
Then store all of your css/js/fonts/shared images etc on the CDN site and link to them from your other sites.
Doing so solves 2 problems,
All of your stuff is shared when it needs to be and you only have to manage 1 revision per file.
Your users browsers can cache them in 1 single location instead of downloading copies of your stuff for every site that uses them..
I added this answer because I see a lot of people referrencing creating virtual directories. While that does indeed share the files, it creates multiple download paths for them which is an extreme waste of bandwidth. Why make your users download jquery.js (1 * number of sites) when you can allow them to download it once on (cdn.somedomain.com).
Also when I say waste of bandwidth, I'm not just talking about server bandwidth, I'm talking about mobile users on data plans... As an example, I hit our companies HR site (insuance etc) on my phone the other day and it consumed 25mb right out the gate, downloaded jquery and a bunch of stuff 5 times each... On a 2gb a month data plan, websites that do that really annoy me.
Here it goes, IMO the best and easiest solution, I spent a week trying to find best and easiest way which always had more cons than pros:
Resources(DLL)
Shared
images
image.png
css
shared.css
scripts
jquery.js
MvcApp1
Images
Content
Shared <- We want to get files from above dll here
...
MvcApp2
Images
Content
Shared <- We want to get files from above dll here
...
Add following to MvcApp1 -> Project -> MvcApp1 Properties -> Build events -> post build event:
start xcopy "$(SolutionDir)Resources\Shared\*" "$(SolutionDir)MvcApp1\Shared" /r /s /i /y
Here is explanation on what it does: Including Build action content files directory from referenced assembly at same level as bin directory
Do the same for MvcApp2. Now after every build fresh static files will be copied to your app and you can access files like "~/Shared/css/site.css"
If you want you can adjust the above command to copy scripts from .dll to scripts folder of every app, that way you could move some scripts to .dll without having to change any paths,here is example:
If you want to copy only scripts from Resources/Shared/scripts into MvcApp1/scripts after each build:
start xcopy "$(SolutionDir)Resources\Shared\Scripts\*" "$(SolutionDir)MvcApp1\Scripts" /r /s /i /y
This is a late answer but Microsoft has added a project type called Shared Project starting Visual Studio 2013 Update 2 that can do exactly what you wan't without having to link files.
The shared project reference shows up under the References node in the
Solution Explorer, but the code and assets in the shared project are
treated as if they were files linked into the main project.
"In previous versions of Visual Studio, you could share source code between projects by Add -> Existing Item and then choosing to Link. But this was kind of clunky and each separate source file had to be selected individually. With the move to supporting multiple disparate platforms (iOS, Android, etc), they decided to make it easier to share source between projects by adding the concept of Shared Projects."
https://blogs.msdn.microsoft.com/somasegar/2014/04/02/visual-studio-2013-update-2-rc-windows-phone-8-1-tools-shared-projects-and-universal-windows-apps/
Info from this thread:
What is the difference between a Shared Project and a Class Library in Visual Studio 2015?
https://stackoverflow.com/a/30638495/3850405
A suggestion that will allow you to debug your scripts without re-compiling the project:
Pick one "master" project (which you will use for debugging) and add the physical files to it
Use "Add As Link" feature as described in Eric's answer to add the script files to the other projects in solution
Use CopyLinkedContentFiles task on Build, as suggested in Mac's comment to copy the files over to the second over to your additional projects
This way you can modify the scripts in the "master" project without restarting the debugger, which to me makes the world of difference.
In IIS create a virtual folder pointing to the same scripts folder for each of the 3 applications. Then you'll only need to keep them in a single application. There are other alternatives, but it really depends on how your applications are structured.
Edit
A scarier idea is to use Areas. In a common area have a scripts directory with the scripts set to be compiled. Then serve them up yourself by getting them out of the dll. This might be a good idea if you foresee the common Area having more functionality later.
Most of the files that are included by default are also available via various CDN's.
If you're not adding your own custom scripts, you may not even need a scripts directory.
Microsoft's CDN for scripts: http://www.asp.net/ajaxlibrary/cdn.ashx

Resources