How to copy the XPO files out of version control...partial code working, bizarre issue - version-control

I began upgrading our layers to Roll Up 7 while we still were developing in another environment with TFS turned on. We were at say version 1850, and by the time I finished, we were at 1900. So the goal is to merge in the 50 different check-ins into the completed RU7 environment. Each check-in can contain many different objects, and each object is stored in TFS as an XPO somewhere.
My code is 90% of the way there, but the issue arrises when copying the files out of the temp directory. When I look in the temp directory, the files aren't there, but somehow they're able to be accessed.
static void Job33(Args _args)
{
#File
SysVersionControlSystem sysVersionControlSystem = versioncontrol.parmSysVersionControlSystem();
SysVersionControlTmpItem contents;
SysVersionControlTmpChange change;
SysVersionControlTmpChange changes;
int i;
SysVersionControlTmpItem contentsAddition;
SysVersionControlTmpItem contentsItem;
str writePath;
Set permissionSet = new Set(Types::Class);
str fileName;
int n;
;
change = versioncontrol.getChangesHistory();
// BP deviation documented
changes.setTmp();
changes.checkRecord(false);
changes.setTmpData(change);
while select changes
order by changes.ChangeNumber asc
where changes.ChangeNumber > 1850
{
writePath = #'C:\TEMP\' + int2str(changes.ChangeNumber) + #'\';
contentsAddition = versioncontrol.getChangeNumberContents(changes.ChangeNumber);
n = 0;
while select contentsAddition
{
// HOW DOES THIS LINE ACCESS THE FILE BUT MY METHOD CAN NOT??
contentsAddition.viewFile();
//?????????????
// Write to appropriate directory
if(!WinAPI::pathExists(writePath))
WinAPI::createDirectory(writePath);
n++;
fileName = int2str(changes.ChangeNumber) + '_' + int2str(n) + '.xpo';
if (WinAPI::fileExists(contentsAddition.fileName(), false))
{
// Write to appropriate directory
if(!WinAPI::pathExists(writePath))
WinAPI::createDirectory(writePath);
WinAPI::copyFile(contentsAddition.fileName(), writePath + fileName, true);
info(strfmt("|%1|%2|", contentsAddition.fileName(), writePath + fileName));
}
}
info(strfmt("%1", changes.ChangeNumber));
}
}

Buried in Classes\SysVersionControlFilebasedBackEndTfs there is a .Net assembly that is used. I was able to use this to extract what I needed mixed in with the upper code. After I used this...my code from above started working strangely enough??
Somehow there was a file lock on the folder that I copied TO, that just wouldn't let me delete it until I closed AX...no big deal, but it suggests there is a tfsProxy.close() method or something I should have called.
Microsoft.Dynamics.Morphx.TeamFoundationServer.Proxy tfsProxy = new Microsoft.Dynamics.Morphx.TeamFoundationServer.Proxy();
;
tfsProxy.DownloadFile(contentsAddition.InternalFilename, changes.ChangeNumber, writePath + fileName);

So you are trying to just get the objects that were changed so you can import them into the new RU7 environment? Why not do this within Visual Studio directly? You can pull the XPOs from there based on the history of changesets since you started the RU7 upgrade.
Also, you should use branching for this. It would have been easy to just branch the new code in that way. Something you should look into for the future.

Related

Protractor - Create a txt file as report with the "Expect..." result

I'm trying to create a report for my scenario, I want to execute some validations and add the retults in a string, then, write this string in a TXT file (for each validation I would like to add the result and execute again till the last item), something like this:
it ("Perform the loop to search for different strings", function()
{
browser.waitForAngularEnabled(false);
browser.get("http://WebSite.es");
//strings[] contains 57 strings inside the json file
for (var i = 0; i == jsonfile.strings.length ; ++i)
{
var valuetoInput = json.Strings[i];
var writeInFile;
browser.wait;
httpGet("http://website.es/search/offers/list/"+valuetoInput+"?page=1&pages=3&limit=20").then(function(result) {
writeInFile = writeInFile + "Validation for String: "+ json.Strings[i] + " Results is: " + expect(result.statusCode).toBe(200) + "\n";
});
if (i == jsonfile.strings.length)
{
console.log("Executions finished");
var fs = require('fs');
var outputFilename = "Output.txt";
fs.writeFile(outputFilename, "Validation of Get requests with each string:\n " + writeInFile, function(err) {
if(err)
{
console.log(err);
}
else {
console.log("File saved to " + outputFilename);
}
});
}
};
});
But when I check my file I only get the first row writen in the way I want and nothing else, could you please let me know what am I doing wrong?
*The validation works properly in the screen for each of string in my file used as data base
**I'm a newbie with protractor
Thank you a lot!!
writeFile documentation
Asynchronously writes data to a file, replacing the file if it already
exists
You are overwriting the file every time, which is why it only has 1 line.
The easiest way would probably (my opinion) be appendFile. It writes to a file without overwriting existing data and will also create the file if it doesnt exist in the first place.
You could also re-read that log file, store that data in a variable, and re-write to that file with the old AND new data included in it. You could also create a writeStream etc.
There are quite a few ways to go about it and plenty of other answers
on SO specifically on those functions that can provide more info.
Node.js Write a line into a .txt file
Node.js read and write file lines
Final note, if you are using Jasmine you can also create a custom jasmine reporter. They have methods that contain exactly what you want (status Pass/Fail, actual vs expected values etc) and it's fairly easy to set up with Protractor

Compute file content hash with Scala

In our app, we are in need to compute file hash, so we can compare if the file was updated later.
The way I am doing it right now is with this little method:
protected[services] def computeMigrationHash(toVersion: Int): String = {
val migrationClassName = MigrationClassNameFormat.format(toVersion, toVersion)
val migrationClass = Class.forName(migrationClassName)
val fileName = migrationClass.getName.replace('.', '/') + ".class"
val resource = getClass.getClassLoader.getResource(fileName)
logger.debug("Migration file - " + resource.getFile)
val file = new File(resource.getFile)
val hc = Files.hash(file, Hashing.md5())
logger.debug("Calculated migration file hash - " + hc.toString)
hc.toString
}
It all works perfectly, until the code get's deployed into different environment and file file is located in a different absolute path. I guess, the hashing take the path into account as well.
What is the best way to calculate some sort of reliable hash of a file content that well produce the same result for as log as the content of a file stays the same?
Thanks,
Having perused the source code https://github.com/google/guava/blob/master/guava/src/com/google/common/io/Files.java - only the file contents are hashed - the path does not come into play.
public static HashCode hash(File file, HashFunction hashFunction) throws IOException {
return asByteSource(file).hash(hashFunction);
}
Therefore you need not worry about locality of the file. Now why you end up with a different hash on a different fs .. maybe you should compare the size/contents to ensure eg no compound eol's were introduced.

Upload Servlet with custom file keys

I have built a Server that you can upload files to and download, using Eclipse, servlet and jsp, it's all very new to me. (more info).
Currently the upload system works with the file's name. I want to programmatically assign each file a random key. And with that key the user can download the file. That means saving the data in a config file or something like : test.txt(file) fdjrke432(filekey). And when the user inputs the filekey the servlet will pass the file for download.
I have tried using a random string generator and renameTo(), for this. But it doesn't work the first time, only when I upload the same file again does it work. And this system is flawed, the user will receive the file "fdjrke432" instead of test.txt, their content is the same but you can see the problem.
Any thoughts, suggestions or solutions for my problem?
Well Sebek, I'm glad you asked!! This is quite an interesting one, there is no MAGIC way to do this. The answer is indeed to rename the file you uploaded. But I suggest adding the random string before the name of the file; like : fdjrke432test.txt.
Try this:
filekey= RenameRandom();
File renamedUploadFile = new File(uploadFolder + File.separator+ filekey+ fileName);
item.write(renamedUploadFile);
//remember to give the user the filekey
with
public String RenameRandom()
{
final int LENGTH = 8;
StringBuffer sb = new StringBuffer();
for (int x = 0; x < LENGTH; x++)
{
sb.append((char)((int)(Math.random()*26)+97));
}
System.out.println(sb.toString());
return sb.toString();
}
To delete or download the file from the server you will need to locate it, the user will input the key, you just need to search the upload folder for a file that begins with that key:
filekey= request.getParameter("filekey");
File f = new File(getServletContext().getRealPath("") + File.separator+"data");
File[] matchingFiles = f.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.startsWith(filekey);
}
});
String newfilename = matchingFiles[0].getName();
// now delete or download newfilename

Get a folder / zip with files in changelist(s) in TFS with complete directory structure

Our team uses TFS to manage workflow in the following flow:
work item -> source control -> changelist -> manual deploy to servers
Is there any way to just get a list of files with complete directory structure for a given changelist? Ideally, I'd like to be able to select multiple changelists and/or work items to get all the changelists associated with a work item, and get a complete directory structure for files in the changelists/work items.
Any suggestions would be appreciated, thanks!
You can probably use the following code snippit to get started
Uri tfsUri = new Uri(#"http://server:8080/tfs");
string serverPath = #"$/Project";
//Connect to the project collection
var projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(
tfsUri, new UICredentialsProvider());
//Get the source code control service.
var sourceControl = projectCollection.GetService<VersionControlServer>();
var history = sourceControl.QueryHistory(
serverPath, //Source control path to the item. Like $/Project/Path ...
LatestVersionSpec.Instance, //Search latest version
0, //No unique deletion id.
RecursionType.Full, //Full recursion on the path
null, //All users
new ChangesetVersionSpec("9829"), //From the 7 days ago ...
LatestVersionSpec.Instance, //To the current version ...
Int32.MaxValue, //Include all changes. Can limit the number you get back.
true, //Include details of items, not just metadata.
false //Slot mode is false.
);
//Enumerate of the changesets.
foreach (Changeset changeset in history.OfType<Changeset>().Take(1))
{
foreach (var change in changeset.Changes)
{
change.Item.ServerItem.Dump();
}
}

How to execute the code generated by codeDom?

I just generated the .cs file using codeDom. Can someone explain how do I execute it?
The code below will allow you to compile the code using the codedom and then you can show the user if the code compiled correctly or not. It even creates a DLL as well.
Thanks
Alex
// Store provider from the method into a object, Default is CSharpCodeProvider**
CodeDomProvider provider = this.GetCurrentProvider();
// Configure a CompilerParameters that links System.dll**
String[] referenceAssemblies = { "System.dll", "System.Data.Linq.dll", "System.Web.dll","System.XML.dll","System.ComponentModel.DataAnnotations.dll", "System.Data.dll", _mvcLocation };
CompilerParameters cp = new CompilerParameters(referenceAssemblies, this.fileLocation + this.fileName + ".dll", false);
// Generate an executable rather than a DLL file.**
cp.GenerateExecutable = true;
// Invoke compilation.**
CompilerResults _results = provider.CompileAssemblyFromFile(cp, this.fileLocation + this.fileName + "." + this.extention);
It's not quite that simple. See here for a primer. Basically the CodeDom supports scenarios such as code generation and dynamic compilation. So .cs files created with the CodeDom are not executables in the usual sense.