Unlock Xcode Project File for Find and Replace - xcode

I make common use of Xcode's workspace Find and Replace. It's very powerful when combined with regex.
However, I've got a workspace with 30-40 projects and a large change to the build settings has just been required. I expected to hop into Xcode, and put some regex to use to change the build setting for all projects when I was hit with a block. All my Xcode project files are locked. So the regex find works great, but I have no way of replacing. I can't even preview it. It is only affecting project files that I can see. I opened Finder to check permissions and they are wide open and the OSX file lock is off on all of them. So this seems to be an Xcode locking issue. I tried to lock/unlock the project files the way you would a normal file (File > Unlock...) in Xcode but these options are grayed out for projects.
Anyone encounter this before? Any possible solutions before I have to hand update build settings for 30+ projects?

I did some more digging on this question to confirm or refute my hypothesis from the comments above. Xcode does indeed work directly against the on-disk data for the files involved in find/replace activities. Filesystem events suggest that the find/replace operation opens the .pbxproj file and begins regex activities from top to bottom working through the file and group references to the build configurations and settings sections ultimately applying the search to the on-disk data pointed to by each of the entries in the .pbxproj
Naturally, depending on the regex the user enters, it would be entirely possible to match content exactly at the cursor's current location in the search and trigger a replacement operation that would destroy the current search's context. This would have the most likely effect of terminating the search prematurely, but could also trigger an infinitely long find/replace operation (ex. find '.' replace with 'aa') if the search wasn't well contained. To stem off the entire class of 'self eating snake' problems when it comes to this Xcode find/replace behavior, it seems that Apple has elected to lock the .pbxproj for the duration of the search operation. While this does mean that you can't use Xcode's Find/Replace regex tools, there are a number of great text editors out there (even free ones!) that allow you to do regex find/replace via a Multi-file search (TextWrangler and BBEdit). These editors allow you to filter your search to a file pattern (say *.pbxproj) in subfolders of your master project. Depending on how your projects are organized on disk, pick a search starting at a common ancestor and you can walk your way through the find/replace operation just as you would in Xcode. In fact, the same regex strings you identified in Xcode can be used in these tools to affect the change(s) you need.
As with most massive or autonomous edits, make sure you keep backups of the files you intend to edit (this goes at least doubly so for you since your projects are entirely local, non-source controlled projects) just in case you need to rollback your changes. Good luck and let us know which avenue you wound up taking and how things went.

Related

Can you change per-file options for a group of files?

I have a nested group of dozens of files (as described in this question), and I'd like to apply some custom build settings to all and only those files.
This was trivial in Xcode 3.
In Xcode 4, although I couldn't find anything in the documentation, I found a workaround: if you can select all of the files you want to change in the Compile Sources list (which happens to work for me because all of the files in my group have the same namespace prefix, and only one other file in the project shares it, so I can search for the prefix, select all, then deselect the one extra file), then hit Return, it will pop up the compile settings dialog for all selected files. (Double-clicking, context menu, etc. doesn't work, only Return.) (From a quick search, I found the same workaround discussed in this question.)
In Xcode 5 and 6, that workaround no longer works; selecting the files and hitting Return (or Fn+Enter, or double-clicking, or right-clicking or anything else I can think of) has no effect.
I've tried using AppleScripting to do this, but, as with my previous problem, I can't get past the fact that any attempt to access the build files of a build phase object returns a generic -10000 error… So, unless there's actually a solution, it looks like I'll be writing a script to parse the pbxproj as a plist again, which I'd really like to avoid.
As of Xcode 6.1, Yes
I just tested this in Compile Sources in Xcode 6.1, and I can
custom select on a search
edit the compile settings for the selected files
But if not...
Your last line was about writing a parser for pbxproj, I thought I would recommend Ruby-based tool for that, Xcodeproj. In their own words,
Create and modify Xcode projects from Ruby.
It is an integral part of CocoaPods, and therefore very actively used and maintained.

Visual Studio Solution -- Any way to create a "special" folder?

Basically, I want one of my folders to appear above the other folders as a type of "special folder", similar to how Properties has it's own special place even though it's a folder, same with App_Data, etc.
Is this possible?
By default, Visual Studio doesn't support adding special project folders. The Properties folder is hard-coded to behave the way that it does.
However, anything is possible with code. You could build an extension to do this, but it wouldn't be simple. You'd probably need to mess around with the IVsHierarchy or even implement a project subtype.
Basically, I want one of my folders to
appear above the other folders as a
type of "special folder", similar to
how Properties has it's own special
place even though it's a folder, same
with App_Data, etc.
Is this possible?
Yes:
Do it manually through the IDE
Write your own script to
generate/modify your *.sln/*.vcproj
For (1) "manual" on solutions in the IDE: Solution Explorer, right-click on Solution node==>Add==>New Solution Folder.
While typically the folders are sorted alphabetically (I'd insert a leading underscore to force your special folder to the top), solution folders inserted manually on my MSVS2008 leave the new folder "at the top", even though it should have bumped down when alphabetically sorted. However, folders under a Project (which are called "Filters") are always sorted alphabetically, and added similarly from the right-click, and then you can modify their "filter properties" with file name globs for what you want in there (e.g., add a filter glob for "*.MY_EXTENSION1;*.MY_EXTENSION2").
We chose (2), and we generate our own *.sln and *.vcproj, adding our own folders/filters. I've not seen any utilities on the web to help with that (so we had to write our own). The formats are not too hard to reverse engineer, but it's largely undocumented XML, so you have to experiment. There are only a couple good web articles explaining what's in the file, like this one:
http://tim.oreilly.com/pub/a/dotnet/excerpt/vshacks_chap1/index.html?page=4
On the "bright side", the files are only XML, so in developing our scripts we merely made changes through the IDE, saved, and compared the "diffs" for what change we want. Those changes are what our scripts insert when we modify our files. So, if you modify the file manually, you can similarly just "diff" the file to see what changed, and make your own script. (IMHO, this is the fastest and easiest route, since tools generally do not exist to manipulate these files.)
Tools like CMake and QMake generate *.vcproj/*.sln, but don't really do the folder customization thing like you're talking. However, we look at their output too, because, "there's more than one way to do things" in these files, and the files seem to have many undocumented features for doing different clever things that somehow these tools have "discovered" (so you can try to copy their generated output).
We found the .NET APIs to work with these files as too much work, and not really designed for that type of manipulation, but YMMV.
VS 2012 has a feature that I just found, and it solved this problem for me. It may not be new to VS.
Create a folder under the project with a leading "_" (to get it sorted first).
On the folder's properties set "Namespace Provider" to false.
VS (or ReSharper?) code analysis then does not complain that "the namespace does not match file location", which was the source of irritation for me that would otherwise have kept me from going this route.
Although there is no easy way to add Custom Folder, there is an easy way to "steal" Properties custom folder.
Add a regular folder to the project. For example MyCustomerFolder.
Open proj file xml. Find line
<AppDesignerFolder>Properties</AppDesignerFolder>
replace with
<AppDesignerFolder>MyCustomFolder</AppDesignerFolder>
Reload the project.
Now you've got a custom folder, that will always stick to the top.

How do you keep Xcode project source files in sync with your file system directories?

I'm new to XCode and I find the file management a huge pain. In most IDEs, you can simply have the project source tree reference a directory structure on disk. This makes it easy to add new files to your project - you simply put them on disk, and they will get compiled automatically.
With XCode, it appears I have to both create the file and separately add it to the project (or be forced to manipulate the filesystem through the UI). But this means that sharing the .xcodeproj through source control is fraught with problems - often, we'll get merge conflicts on the xcodeproj file - and when we don't, we often get linker errors, because during the merge some of the files that were listed in the project get excised. So I have to go and re-add them to the project file until I can get it to compile, and then re-check in the project file.
I'm sure I must be missing something here. I tried using 'reference folders' but the code in them doesn't seem to get compiled. It seems insane to build an IDE that forces everyone to modify a single shared file whenever adding or removing files to a project.
Other answers notwithstanding, this is absolutely a departure from other IDEs, and a major nuisance. There's no good solution I know of.
The one trick I use a lot to make it a little more bearable — especially with resource directories with lots of files in them — is:
select a directory in the project tree,
hit the delete key,
choose "Remove References Only", then
drag the directory into the project to re-add it.
This clobbers any manual reordering of files, but it does at least make syncing an O(1) operation, instead of being O(n) in the number of files changed.
I'm intrigued which IDEs you're using that automatically compile everything in a directory, as no IDE I've ever used does that (at least for C++). I think it's pretty standard to have a project file containing a list of all the files. Often you may want to only include certain files for different targets, have per-file compiler settings, etc.
Anyway, given that that's how it does work, you really shouldn't have too many problems from merge conflicts. The best advice would be commit early and often so that you don't get out of step with other people's changes. Merely adding files to the project shouldn't result in a conflict unless they happen to be added at exactly the same point in the project tree. We've been using Xcode in our team for years and we very rarely get conflicts: only if someone has restructured the project.
Fortunately, because the Xcode file format is text, it's generally quite easy to resolve conflicts when they occur, unlike the Bad Old Days of Codewarrior with it's binary format.

How to deal with VB6 .vbp file references changing

Our VB6 guy was part of the last RIF (Reduction in Force). The work he did has been split between me and another developer. We often are both are making changes to projects at the same time. This isn't a problem with CVS since we are working in different areas. However VB6 seems to modify the Reference section and change the paths each time either of us touches a project. Since we don't have the exact same path setup for out source trees we run into merge conflicts on the vbp file all the time.
Is there any way around this other than the obvious method of changing our setup so we have the same directory structures?
I would suggest two things:
Don't commit the .vbp unless you add a file to the project.
Mark the .vbp as read-only and check it in as such into your repo. When users check it out, it should still be read-only which will prevent changes to reference paths (and seemingly random reordering of the file) from being saved. When you have to make a change to the project--make the file read-write, save the change and then make it read-only again before committing.
Depending on your version control system, it is possible to automate this problem away. Both Subversion and Mercurial support hooks - scripts that are triggered by certain events, like check out, update, or commit. We wrote a fairly simple script that was triggered on commit: it looked to see if there was a .vbp in the commit package, and if there was, ran a "normalisation" routine that
put all the .cls/.bas/.frm files at the top of the .vbp, in alphabetic order
put the references section in alphabetic order
lower-cased the reference paths
The rest of the file is left alone, since it's only the first three sections that VB seems to delight in messing about.
Consequently, most of the time when you commit, and haven't made any substantive changes to the .vbp, the hook script restores your .vbp file to a canonical, ordered, state (like a revert), which has the effect of removing it from the commit since it's no longer changed.
In the event that you do add a new file or reference to your project, the consistent alphabetical sorting of the VBP lines means that merge conflicts are avoided since your VC merge algorithm can easily and correctly detect the changes.
We wrote our script in Javascript and execute it using Windows Script Host since, for Windows boxes at least, this removes the dependency on an interpreter like Perl/Python.
Hooking up this script to new VB projects is a 30 second job. The advantage over other manual approaches is that you don't have make any conscious effort to deal with the VBP file. Just commit it with everything else and the script takes care of the rest.

Visual studio 2008 - Find in files : lists everything twice

In VS2008, I have a web-site project. When I use find in files and search for a string, the find results window will list every occurence twice.
What could be causing this?
[EDIT]
Below is the screen capture from VS. I was searching for the work CommissionBucketProductID within my website project. Notice that each line is returned twice.
[EDIT2]
In response to your questions. I am only searching within the project, not the whole solution. I currently don't have these files under VSS, although they were in the past.
I had the same issue which was annoying. I just fixed it. What I've done is to change "Entire solution" to "current project" in "Look in" field when doing search. Then I noticed the result would not be doubled. After I switched back to "entire solution" the problem was gone.
If you do find in "Entire Solution", it also searches in any loaded files, even if they're already in the solution. This means that they'll be listed twice.
Perhaps this is your problem?
I use VS2003, but I get this exact result when I have the same source file in multiple projects. Are you sure you aren't searching more than one project?
Here's your answer:
Find in Files searches same files twice
This seems to happen for files that are shared between multiple projects in the same solution, causing them to get searched twice. Since the problem exists in VS2010, it must have been inherited from VS2008, which probably means you're pretty much out of luck (unless you work around it, such as by separating the projects into multiple solutions).
But in the meantime, it sounds like it's not high enough on Microsoft's priority list to get this fixed.
Do you have any symbolic links to a directory/file within the same search scope? This could cause the file to be listed twice: once for the primary file, and once for the link to the file. Although from memory it should show the directory of the link for the 2nd occurrence, not the file pointed at by the link (and this is inconsistent with what is in your screenshot).
Try closing VS2008, renaming the file (USPostalApplciation.aspx and the code behind file too), then re-opening VS2008, refresh everything you can think of (project, solution, etc...) then try doing the search again.
I had a similar problem. VS would turn up find solution results from files I had loaded in the IDE just to view them and then closed again. So it would search through files that weren't even in the solution.
I scanned all files in the solution, but there was no reference to these phantom files stored anywhere. Finally I decided to scan the registry and found that they were stored in the MRU list. After deleting the MRU list entries, the expected behavior was restored.
Make sure your web project does NOT have any virtual directories that point back to other areas of the site.
Verify that VS2008 shows the same virtual directories (if any) that IIS has.
If you have mis-pointed or mis-configured Virtual directories, it will cause a HUGE performance hit, search result replication, etc.
This is an old thread, but this still happens.
As new info, I just found that the solution contains a Setup project, which naturally references some of the projects, besides the solution itself.
In that case, when searching the Entire Solution there are two routes to some files.

Resources