Automatic SVN revision number? - eclipse

I write Android stuff using Eclipse+the ADT plugin. For VCS I use SVN.
What I am trying to accomplish: have my program, in its 'About' screen, display the SVN revision number it was built from. Obviously, this better be automatic. We cannot assume the program will have network access when run so this info has to be known at compile time.
Today I've been researching this topic and seems like this seemingly common scenario is actually not so easy to do or I am missing something. Lets see:
1) first approach: write a 'pre-commit' SVN script that, on each commit, would update a little file, that would be named 'revision' and would be located in the root of my project. Then writing a function that would open this file, read the revision number and put it in the 'About' screen would be trivial.
This doesn't quite work as the file would be updated server-side. So imagine this scenario: I check out rev. 3708, modify, commit, pre-commit creates 'revision' with '3709' in it. I build - and my local 'revision' still contains '3708'. Not good.
2) I hear ( Getting SVN revision number into a program automatically ) that SVN has this clever feature that it is able to replace various magic strings in your files, one of then being 'Revision', if one sets appropriate SVN metadata on all files in a project under SVN control.
This does not quite work again, because of the problem mentioned by user 'Smashery' in the link above - namely, SVN will only replace the 'Revision' magic string in files that got changed during the last commit.
3) Write a 'pre-build' Eclipse script, and have it run 'svnversion /path/to/your/project' and save output of this in /path/to/your/project/revision.
This does not quite work again - I mean, I have tried and writing such script is actually surprisingly easy. If I were working on a single computer, it would have worked for me - but unfortunately I work on two computers, one Linux machine in home and another Windows machine at work. I keep switching machines every day (during the day Windows, in the evenings Linux at home).
The problem here is with Eclipse: as soon as you add a 'pre-build' script, it creates a new hidden directory in your project folder ( .externalToolBuilders ) , which, among other things, contains the absolute path to the script to run (obviously). This path cannot be the same on both of my machines (being Linux and Windows). In order for things to be automatic, I need to check this in to SVN, and as soon as I do, things will work only on one of my machines unless I keep manually correcting the path every day!
Any ideas?

Third way (slightly polished) can be and will be The Right Way, if you'll grok some things
Workplace specific settings must not be shared and stored in repository: ignore .externalToolBuilders on both locations but configure Eclipse differently according to your needs and settings
Except identical for all OSes svnversion (and don't forget ignore also /path/to/your/project/revision, because build-artifacts must not be part of repository) you may want to use more powerful somehow subwcrev (on Win-box) and svnrev (on Linux-box) in pre-build event - svnrev also contain some useful reading

Related

opening vscode to latest directory in specified path

Is it possible to have vscode automatically open the newest folder within a specific path?
For example, with this configuration:
{
"folders": [
{
"path": "\\\\FromABC\\Archive",
"name":"From ABC"
},
{
"path": "\\\\FromXYZ\\Archive",
"name":"From XYZ"
}
]
}
I would expect these folders in the workspace to be pointing to \07\07 because those were created today:
\\\\FromABC\\Archive\\2021\\07\\07
\\\\FromXYZ\\Archive\\2021\\07\\07
Is it possible to create a workspace where the folders are opened to the latest folder within each configured path?
There's not enough information in the original question to fully answer it, however, I can suggest a few avenues of attack
Custom Command (error-prone and picky)
Modify Upstream Process (likely the best overall)
Combining Both (perhaps the best for your immediate case)
Creating a Custom Command
Create a new command per https://code.visualstudio.com/api/extension-guides/command#creating-new-commands
VSCode Commands Listing: https://code.visualstudio.com/api/references/commands
new command
detect latest folder through whatever logic you like
call vscode.openFolder to navigate to it
call your custom command through Activation Events (activationEvents) at either onStartupFinished or * (Start Up; less-preferable, but may be required to avoid confusing the editor)
https://code.visualstudio.com/api/references/activation-events#Start-up
Check out Start app when opening project in VS Code? for a few answers related to this
Modifying the Upstream Process
Cutting the gordian knot, it's likely some process (perhaps a human) is creating the directories for you
Change the upstream process so when it creates the directories, it also creates/updates a link to the directory labeled something like latest
/FromABC/Archive/2021/06/03
/FromABC/Archive/2021/07/05
/FromABC/Archive/2021/07/07
/FromABC/Archive/latest --> /FromABC/Archive/2021/07/07
/FromXYZ/Archive/2020/04/12
/FromXYZ/Archive/2021/08/18
/FromXYZ/Archive/latest --> /FromXYZ/Archive/2021/08/18
Then you can always refer to the latest directory and it will always be correct
This is quite common when something can change frequently, but another process is expecting a static path and/or has no way to know the schedule of change
I don't have any Windows systems to try this out with and you may be able to create a regular shortcut for this .. however, you may need a Junction (soft-link) or Hard Link to convince VSCode that the directory is a real directory
https://learn.microsoft.com/en-us/windows/win32/fileio/hard-links-and-junctions
This also provides an opportunity to include more files, such a beta versions of some software, which it's desirable to package into the same directory structure, but not truly the latest stable!
Combining Both
If your upstream process is either not modifiable (or some manual process it's annoying or error-prone to add extras steps to) you can likely combine both solutions to get what you really want
Use the * Action Event to call a script to detect and create the new directory - create a binary or PowerShell script to make your link
In this and with the upstream change, just point VS Code to the latest directory and it shouldn't mind
Not sure on which platform you are, I assume windows, but essentially similar.
Instead of trying to get VSCode to open the latest folder, I would create a script that updates a softlink for each folder to the latest subfolder in it. Then you can point VSCode to the softlink, which can be updated whenever needed to the latest subfolders.

How to send my project to a colleague?

My colleague and myself are fairly new to RubyMine and to Ruby. We use WinXP Pro.
I want to zip a small Ruby (non-Rails) project and either email it to my colleague or copy it to a share. Note that we are not currently using a single repository for RubyMine projects.
Edited: Please ignore everything above the line. It seems to be causing some generous responders to waste their time. I apologize for that.
Assume the post starts below this line.
I have no internet connection. I want to zip a small Ruby (non-Rails) test project, copy it to a floppy, and deliver it by hand to a friend. My friend has no internet connection.
I would like to confirm that all I need to do is to zip everything including, and below, the project root in Windows Explorer. (I'm assuming that the "project root" is the folder that contains the "gemfile".)
I'm assuming that the gemfile.lock will force my colleague's gems to match mine, even if one of his gems is more up to date than mine.
I'm assuming that the contents of RM's "External Libraries" will be recreated on my colleague's RM, without my needing to include these files in the ZIP.
I would be grateful for any advice.
Use a version control system like git or svn.

Eclipse's local history...where are files saved?

Can someone explain how Eclipse's local history works?
I accidentally overwrote a file in a project but need to revert to an earlier version.
Is there a chance that Eclipse has the older file cached somewhere?
To complete CurtainDog's answer: from eclipse FAQ
Every time you modify a file in Eclipse, a copy of the old contents is kept in the local history. At any time, you can compare or replace a file with any older version from the history.
Although this is no replacement for a real code repository, it can help you out when you change or delete a file by accident.
Local history also has an advantage that it wasn’t really designed for: The history can also help you out when your workspace has a catastrophic problem or if you get disk errors that corrupt your workspace files.
As a last resort, you can manually browse the local history folder to find copies of the files you lost, which is a bit like using Google’s cache to browse Web pages that no longer exist.
Each file revision is stored in a separate file with a random file name inside the history folder. The path of the history folder inside your workspace is
.metadata/.plugins/org.eclipse.core.resources/.history/
You can use your operating system’s search tool to locate the files you are looking for.
Note, if your need to import your local history into a new workspace, you will need both:
.metadata/.plugins/org.eclipse.core.resources/.history
.metadata/.plugins/org.eclipse.core.resources/.project
to have a functional local history in that new workspace.
Try right-clicking on the file in eclipse, and choose Replace With->Local History.
If there's history available, it'll show up as a list of edit times.
But more importantly, as pointed out in other answers, be sure to put your files in version control! SVN is pretty easy to set up (you don't need a server; it can just use the file system); use it even if you aren't sharing with others.
A tip: whenever you hear yourself say "yes!", check in all of your code. 10 minutes later, you'll be saying "how did I mess that up?"
If you have lost a full package structure due to accidental deletion or svn/cvs override, select the project> right click> Restore from local history => select the files.
VonC's answer has all the information you need for finding the location of your code backups. I would simply add that if you are on a Mac or Linux, you can do something like this:
$ cd [WORKSPACE]/.metadata/.plugins/org.eclipse.core.resources/.history/
$ grep -rl "class Foo" . | xargs ls -lt
This will find all the versions of a file that contains a particular string (ie. "class Foo"), and sort them by date/time to easily find the most recent version.
You can use the link http://wiki.eclipse.org/FAQ_Where_is_the_workspace_local_history_stored%3F is very helpfull
Open the CVS view and you should see a filter for local history. You should then be able to right-click on the correct version and Get Contents or do a manual compare and merge. I'm not sure what the eclipse defaults are for keeping local history but there is a decent chance you'll be able to get your stuff back if you act quickly.

How to manage external dependencies which are constantly being modified

Our development uses lots of open-source code and I'm trying to figure out what the best way to manage these external dependencies.
Our current configuration:
we are developing for both linux and windows
We use svn for our own code
external dependencies (boost, log4cpp, etc) are not stored in svn. Instead I put them under ./extern (or c:\extern on windows). I don't want to put them in our repository because I will not be able to update them that way. Some of these are constantly being updated.
My questions
What to do if I need to modify external code?
Currently I have created a folder in my svn repository called extern_hacks and that is where I put the modified external code. I then link (or copy on windows) the files into the external directory structure. This solution is problematic since it is hard to keep track of copying the files, and very hard to update from svn when files are sitting in two repositories (mine for the modified files, and the original repository say sourceforge)
How to manage versions of external dependencies?
I'm interested to hear how others deal with these issues. Thanks.
I keep them in svn, and manage them as vendor branches. Keeping them loose externally makes it very hard to go back to a previous build, or fix bugs in a previous build (especially if the bug is from a change to the external dependency)
Keeping them in svn has saved me lots of headache, and also allows you to get a new workstation able to work on your codebase quickly.
I do not understand why you say
I don't want to put them in our repository because I will not be able to update them that way. Some of these are constantly being updated.
You really need to
include external dependencies in your source control and periodically update them and then tese, test, test.
Coordinate your build process with the updates for the external dependencies.
If your code depends upon something, then you really need to have control over when it gets updated/modified. Coding in a space where these dependencies can get updated at any time is too painful as you're no doubt finding out. I personally prefer option 1.
When I had to do something like this, I added the external source as external, and then applied a patch to it. The patch contains my modifications to the external source. So, I actually only version control my patches. Most of the times this works, if there are no "dramatic" changes in the external code.
Have you considered Maven? It's a build system that has excellent support for managing dependencies. For each project you can specify the required dependencies in an xml file as part of that project. The external libraries are held in a dependency repository (in our case Artifactory) this is separate from your version control system and can just be a network drive. It also allows managing different versions of projects.
I would be careful considering Maven because:
it is another repository in a system where you already have a repository with your current version control system;
it (Maven) is based on the only "common version control" every developer have, the file system (which means no metadata, or properties attached to the file, no proper history in term of who modified what and when)
Now when dealing with third-parties, you can consider having them in your version control system, but in a packaged way: that is in a very compact way, with sources and documentations zipped, in order to have the least possible number of files.
That way, you will manage the deployment of those (many) third-party libraries easily since the number of files to deploy is low.
Plus, having them under source control allows you to make a branch (say, a 'hack' branch), in which you will stored the packaged (or zipped) version of the hacked library.
What you can store in an external way is the un-zipped, complete set of files representing those libraries since there is no real development on them, or just a punctual hack: normally, your job is not to develop existing libraries, but to use them (even a bit modified) for implementing faster some features of your project.
If you need at some point to compare some hacked version with some official version, you will just pull out from svn the appropriate 'hacked' version number, unzip-it and compare-it with the official (and externally stored) version (with winmerge for instance)

Can you "ignore" a file in Perforce?

I sometimes use the feature 'Reconcile Offline Work...' found in Perforce's P4V IDE to sync up any files that I have been working on while disconnected from the P4 depot. It launches another window that performs a 'Folder Diff'.
I have files I never want to check in to source control (like ones found in bin folder such as DLLs, code generated output, etc.) Is there a way to filter those files/folders out from appearing as "new" that might be added. They tend to clutter up the list of files that I am actually interested in. Does P4 have the equivalent of Subversion's 'ignore file' feature?
As of version 2012.1, Perforce supports the P4IGNORE environment variable. I updated my answer to this question about ignoring directories with an explanation of how it works. Then I noticed this answer, which is now superfluous I guess.
Assuming you have a client named "CLIENT", a directory named "foo" (located at your project root), and you wish to ignore all .dll files in that directory tree, you can add the following lines to your workspace view to accomplish this:
-//depot/foo/*.dll //CLIENT/foo/*.dll
-//depot/foo/.../*.dll //CLIENT/foo/.../*.dll
The first line removes them from the directory "foo" and the second line removes them from all sub directories. Now, when you 'Reconcile Offline Work...', all the .dll files will be moved into "Excluded Files" folders at the bottom of the folder diff display. They will be out of your way, but can still view and manipulate them if you really need to.
You can also do it another way, which will reduce your "Excluded Files" folder to just one, but you won't be able to manipulate any of the files it contains because the path will be corrupt (but if you just want them out of your way, it doesn't matter).
-//depot/foo.../*.dll //CLIENT/foo.../*.dll
Yes, But.
Perforce version 2012.1 added a feature known as p4ignore, inspired by Git. However the Perforce developers made a change to the behaviour, without justification, that happens to make the feature a lot less useful.
Whilst Git takes rules from all .gitignore files, Perforce doesn't know where to look until you specify a filename in an environment variable P4IGNORE. This freedom is a curse. You can't hack on two repositories that use different names for their ignore files.
Also, Perforce's ignore feature doesn't work out the box. You can set it up easily enough for yourself, but others don't benefit unless they explicitly opt-in. A contributor who hasn't may accidentally commit unwelcome files (eg. a bin folder created by a build script).
Git's ignore feature is great because it works out the box. If the .gitignore files are added to the repository (everyone does this), they'll work out the box for everyone. No-one will accidentally publish their private key.
Amusingly, the Perforce docs shows '.p4ignore' as an example ignore rule, which is backwards! If the rules are useful, they should be shared as part of the repository.
Perforce could still make good on the feature. Choose a convention for the file names, say p4ignore.txt, so the feature works out the box. Drop the P4IGNORE environment variable, it's counterproductive. Edit the docs, to encourage developers to share useful rules. Let users write personal rules in a file in their home folder, as Git does.
If you know anyone at Perforce, please email them this post.
This works as of Perforce 2013.1, the new P4IGNORE mechanism was first added in release, 2012.1, described on the Perforce blog here:
https://www.perforce.com/blog/new-20121-p4ignore
As it's currently described, you set an environment variable "P4IGNORE" to a filename which contains a list of the files to ignore.
So you can check it out to see how you like it.
If you want a solution that will apply to all work-spaces without needing to be copied around, you (or your sysadmin) can refuse submission of those file-types through using lines like the below in the p4 protect table:
write user * * -//.../*.suo
write user * * -//.../*.obj
write user * * -//.../*.ccscc
I remember doing this before, but I don't have the necessary permissions to test this here. Check out Perforce's Sysadmin guide and try it out
Perforce Streams makes ignoring files much easier, as of version 2011.1. According to the documentation, you can ignore certain extensions or certain paths in your directory.
From p4 help stream
Ignored: Optional; a list of file or directory names to be ignored in
client views. For example:
/tmp # ignores files named 'tmp'
/tmp/... # ignores dirs named 'tmp'
.tmp # ignores file names ending in '.tmp'
Lines in the Ignored field may appear in any order. Ignored
names are inherited by child stream client views.
This essentially does what #raven's answer specifies, but is done easier with streams, as it automatically propagates to every work-space using that stream. It also applies to any streams inheriting from the stream in which you specify the ignore types.
You can edit the stream via p4 stream //stream_depot/stream_name or right-clicking the stream in p4v's stream view.
And as #svec noted, the ability to specify ignore files per workspace is coming soon, and is in fact in P4 2012.1 beta.
Will's suggestion of using .p4ignore only seems to work with the WebSphere Studio (P4WSAD) plugin. I just tried it on my local windows box and any files and directories that I listed were not ignored.
Raven's suggestion of modifying your client spec is the correct way under Perforce. Proper organization of your code/data/executables and generated output files will make the process of excluding files from being checked in much easier.
As a more draconian approach, you can always write a submit trigger which will reject submission of change-lists if they contain a certain file or files with a certain extension, etc.
HISTORICAL ANSWER - no longer correct. At the time this was written originally it was true;
You can not write and check in a file that the server will use to make ignore rules; general glob or regexp file pattern ignore in perforce.
Other answers have global server configurations that are global (and not per folder).
The other answers show things that might work for you, if you want one line in your view per folder times number of extensions you want to ignore in that single folder, or that provide this capability in WebSphere Studio plugins only, or provide capability for server administrators, but not available to users.
In short, I find Perforce really weak in this area. While I appreciate that those who use the Eclipse Plugin can use .p4ignore, and I think that's great, it leaves those of us that don't, out in the dark.
UPDATE: See accepted answer for new P4IGNORE capability added mid-2012.
I have found it easiest to reconcile offline work using a BASH script like this one:
#!/bin/bash
# reconcile P4 offline work, assuming P4CLIENT is set
if [ -z "$P4CLIENT" ] ; then echo "P4CLIENT is not set"; exit 1; fi
unset PWD # confuses P4 on Windows/CYGWIN
# delete filew that are no longer present
p4 diff -sd ... | p4 -x - delete
# checkout files that have been changed.
# I don't run this step. Instead I just checkout everything,
# then revert unchanged files before committing.
p4 diff -se ... | pr -x - edit
# Add new files, ignoring subversion info, EMACS backups, log files
# Filter output to see only added files and real errors
find . -type f \
| grep -v -E '(\.svn)|(/build.*/)|(/\.settings)|~|#|(\.log)' \
| p4 -x - add \
| grep -v -E '(currently opened for add)|(existing file)|(already opened for edit)'
I adapted this from this Perforce Knowledge Base article.
I'm looking for a .p4ignore like solution as well (and not one tied to a particular IDE). Thus far, the closest thing I've found is p4delta. It sounds like it will do exactly what the original poster was asking, albeit through another layer of indirection.
http://p4delta.sourceforge.net
Unfortunately, while this does seem to produce the proper list of files, I can't get "p4delta --execute" to work ("Can't modify a frozen string") and the project has not been updated in year. Perhaps others will have better luck.
If you are using the Eclipse Perforce plugin, then the plugin documentation lists several ways to ignore files.