Can anyone help me with the steps to download TFS code to local workspace using command line.
I tried below codes so far but got into multiple issues
var rv = ProcessHelper.Run(
LocalWorkspace,
#"C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\tf.exe",
$"get \"https://xxxx/tfs/xyz/Project/_versionControl?path=%24%2FProject\" \"{LocalWorkspace}\"");
For the above code, it says Path is not supported or specified
Firstly, for that sample, you need to add necessary assembly references to your project, then use them like this:
using System.IO;
using System.Net;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
You may install this package to your project: Microsoft.TeamFoundationServer.ExtendedClient
There is a sample: DownloadDemo
Secondly, for TF command, you could check detail commands in a build log (TFVC repository as source), for example (checkout task):
##[command]tf vc workspace /new /location:local /permission:Public ws_2_4 /collection:http://xxx:8080/tfs/DefaultCollection/ /loginType:OAuth /login:.,*** /noprompt
##[command]tf vc workfold /unmap /workspace:ws_2_4 $/ /collection:http://xxx:8080/tfs/DefaultCollection/ /loginType:OAuth /login:.,*** /noprompt
##[command]tf vc workfold /map /workspace:ws_2_4 $/ScrumStarain2019TFVC D:\AgentTest\vsts-agent-win-x86-2.144.2\_work\2\s /collection:http://xxx:8080/tfs/DefaultCollection/ /loginType:OAuth /login:.,*** /noprompt
##[command]tf vc get /version:7 /recursive /overwrite D:\AgentTest\vsts-agent-win-x86-2.144.2\_work\2\s /loginType:OAuth /login:.,*** /noprompt
I came up with a solution to download the TFS directory into local workspace. Hope this code will get future generations.
create a local workspace in some temp folder
LocalWorkspace = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid():n}");
if (!Directory.Exists(LocalWorkspace))
{
Directory.CreateDirectory(LocalWorkspace);
}
ProcessHelper.Run(
LocalWorkspace,
#"C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team
Explorer\tf.exe",
$"workspace /new /noprompt /collection:<your project url> /location:local
<workspace name>")
Get the latest version of TFS into that local workspace
ProcessHelper.Run(
LocalWorkspace,
#"C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team
Explorer\tf.exe",
$"get <TeamProject> /recursive"));
ProcessHelper.Run():
public sealed class ProcessHelper
{
private static string outputData;
public static string Run(string workingDirectory, string executable, string arguments)
{
outputData = string.Empty;
try
{
using Process proc = new Process();
proc.StartInfo.WorkingDirectory = Path.Combine(Directory.GetCurrentDirectory(), workingDirectory);
proc.StartInfo.FileName = executable;
proc.StartInfo.Arguments = arguments;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.CreateNoWindow = true;
proc.ErrorDataReceived += DataReceived;
proc.OutputDataReceived += DataReceived;
proc.EnableRaisingEvents = true;
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
proc.WaitForExit();
}
catch (Exception ex)
{
return $"{executable} | {workingDirectory} | {arguments}{Environment.NewLine}{Environment.NewLine}{ex}";
}
return $"{executable} | {workingDirectory} | {arguments}{Environment.NewLine}{Environment.NewLine}{outputData}";
}
static void DataReceived(object sender, DataReceivedEventArgs e)
{
string data = e.Data;
if (!String.IsNullOrEmpty(data))
{
Console.WriteLine(data);
outputData += data;
}
}
}
Related
I have a model in Enterprise Architect and I need to import some relationships (of already existing elements) that I have in an Excel. I tried running a JScript but wasn't able to run it (haven't still figured out why).
How can I import a massive amount of relationship into my model?
Thanks in advance.
My Script is:
!INC Local Scripts.EAConstants-JScript
var connectorArray = new Array(
['{870632BA-154F-4564-AD51-C508C1A7E537}','{4B291196-7B4B-490b-B51D-04B9925CAA2A}','Dependency','','RME1']
);
function main()
{
var source as EA.Element;
var target as EA.Element;
var connector as EA.Connector;
var sourceGUID,targetGUID,type,stereotype,alias;
for(var i = 0; i < connectorArray.length; i++) {
sourceGUID = connectorArray[i][0];
targetGUID = connectorArray[i][1];
type = connectorArray[i][2];
stereotype = connectorArray[i][3];
alias = connectorArray[i][4];
source = Repository.GetElementByGuid(sourceGUID);
target = Repository.GetElementByGuid(targetGUID);
Session.Output("Processing connector: " + alias);
if(source != null && target != null) {
connector = source.Connectors.AddNew("",type);
if(stereotype != "") {
connector.Stereotype = stereotype;
}
connector.SupplierID = target.ElementID;
connector.Alias = alias;
connector.Update();
}
source.Connectors.Refresh();
}
Session.Output("END OF SCRIPT");
}
main();
My errors are:
[423447640] Hilo de registro de pila establecido para marcos 3
[423447879] Default Directory is C:\Program Files (x86)\Sparx Systems\EA
[423447879] Agent dll found: C:\Program Files (x86)\Sparx Systems\EA\vea\x86\SSScriptAgent32.DLL
[423447879] Default Directory is C:\Program Files (x86)\Sparx Systems\EA
[423447879] Agent: Started
[423447967] Microsoft Process Debug Manager creation Failed: 0x80040154
[423447967] This is included as part of various Microsoft products.
[423447967] Download the Microsoft Script Debugger to install it.
[423447967] Failed to initialize JScript engine
[423447967] SesiĆ³n de depuraciĆ³n terminada
Thanks again.
Well, may be I'm wrong, but you can see the error Download the Microsoft Script Debugger to install it. I guess, that you're trying to run the script "Debug" button instead of "Run script".
If you want to debug your scrtipt, you"ll must to install any Microsoft product that contains debagger. Microsoft Script Debugger.
FYI Did you try the Excel Import \ Export feature of Sparx Systems in MDG Office Integration .
You can create \ update \ Synchronise model elements, connectors and other details inside enterprise architect in a single click.
Is there a simple way to write to file the mercurial version (or similar external command) in a gradle task:
I'm not yet groovy/gradle conversant, but my current effort looks like this:
task versionInfo(type:Exec){
commandLine 'hg id -i -b -t'
ext.versionfile = new File('bin/$baseName-buildinfo.properties')
doLast {
versionfile.text = 'build.revision=' + standardOutput.toString()
}
}
There are two issues with this build script:
the command line needs to be split; gradle's trying to execute a binary named hg id -i -b t instead of hg with arguments id, -i, -b and t
The standard output needs to be captured; you can make it a ByteOutputStream to be read later
Try this:
task versionInfo(type:Exec){
commandLine 'hg id -i -b -t'.split()
ext.versionfile = new File('bin/$baseName-buildinfo.properties')
standardOutput = new ByteArrayOutputStream()
doLast {
versionfile.text = 'build.revision=' + standardOutput.toString()
}
}
Here I have a little bit different approach, which uses javahg to get revision. And add task "writeRevisionToFile"
I wrote brief post on my blog Gradle - Get Hg Mercurial revision.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.aragost.javahg:javahg:0.4'
}
}
task writeRevisionToFile << {
new File(projectDir, "file-with-revision.txt").text = scmRevision
}
import com.aragost.javahg.Changeset
import com.aragost.javahg.Repository
import com.aragost.javahg.commands.ParentsCommand
String getHgRevision() {
def repo = Repository.open(projectDir)
def parentsCommand = new ParentsCommand(repo)
List<Changeset> changesets = parentsCommand.execute()
if (changesets == null || changesets.size() != 1) {
def message = "Exactly one was parent expected. " + changesets
throw new Exception(message)
}
return changesets[0].node
}
ext {
scmRevision = getHgRevision()
}
I'm creating my first gradle plugin. I'm trying to copy a file from the distribution jar into a directory I've created at the project. Although the file exists inside the jar, I can't copy it to the directory.
This is my task code:
import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.TaskAction;
class InitTask extends DefaultTask {
File baseDir;
private void copyEnvironment(File environments) {
String resource = getClass().getResource("/environments/development.properties").getFile();
File input = new File(resource);
File output = new File(environments, "development.properties");
try {
copyFile(input, output);
}
catch (IOException e) {
e.printStackTrace();
}
}
void copyFile(File sourceFile, File destFile) {
destFile << sourceFile.text
}
#TaskAction
void createDirectories() {
logger.info "Creating directory."
File environments = new File(baseDir, "environments");
File scripts = new File(baseDir, "scripts");
File drivers = new File(baseDir, "drivers");
[environments, scripts, drivers].each {
it.mkdirs();
}
copyEnvironment(environments);
logger.info "Directory created at '${baseDir.absolutePath}'."
}
}
And this is the error I'm getting:
:init
java.io.FileNotFoundException: file:/path-to-jar/MyJar.jar!/environments/development.properties (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:120)
at groovy.util.CharsetToolkit.<init>(CharsetToolkit.java:69)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.newReader(DefaultGroovyMethods.java:15706)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.getText(DefaultGroovyMethods.java:14754)
at org.codehaus.groovy.runtime.dgm$352.doMethodInvoke(Unknown Source)
at org.codehaus.groovy.reflection.GeneratedMetaMethod$Proxy.doMethodInvoke(GeneratedMetaMethod.java:70)
at groovy.lang.MetaClassImpl$GetBeanMethodMetaProperty.getProperty(MetaClassImpl.java:3465)
at org.codehaus.groovy.runtime.callsite.GetEffectivePojoPropertySite.getProperty(GetEffectivePojoPropertySite.java:61)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:227)
at br.com.smartcoders.migration.tasks.InitTask.copyFile(InitTask.groovy:29)
Just to emphasize, the development.properties is inside the environments directory inside the MyJar.jar
getClass().getResource() returns a URL. To access that URL, you'll have to read it directly (e.g. with url.text) rather than first converting it to a String/File. Or you can use getClass().getResourceAsStream().text, which is probably more accurate. In both cases you can optionally specify the file encoding.
Kotlin DSL answer!
For cases like this it is good to have extensions:
fun Any.getResource(filename: String): File? {
val input = this::class.java.classLoader.getResourceAsStream(filename) ?: return null
val tempFile = File.createTempFile(
filename.substringBeforeLast('.'),
"." + filename.substringAfterLast('.')
)
tempFile.deleteOnExit()
tempFile.writer().use { output ->
input.bufferedReader().use { input ->
output.write(input.readText())
}
}
return tempFile
}
I'm interested in getting the contents of a shelveset at the command prompt. Now, you would think that a cmdlet such as Get-TfsShelveset, available in the TFS Power Tools, would do this. You might also think that "tf.exe shelvesets" would do this.
However, unless I've missed something, I'm appalled to report that neither of these is the case. Instead, each command requires you to give it a shelveset name, and then simply regurgitates a single line item for that shelveset, along with some metadata about the shelveset such as creationdate, displayname, etc. But as far as I can tell, no way to tell what's actually in the shelf.
This is especially heinous for Get-TfsShelveset, which has the ability to include an array of file descriptors along with the Shelveset object it returns. I even tried to get clever, thinking that I could harvest the file names from using -WhatIf with Restore-TfsShelveset, but sadly Restore-TfsShelveset doesn't implement -WhatIf.
Please, someone tell me I'm wrong about this!
tf status /shelveset:name
will list out the content of the named shelveset (you can also supplier an owner: see tf help status).
With the TFS PowerToy's PowerShell snapin:
Get-TfsPendingChange -Shelveset name
for the same information.
It is possible to construct a small command-line application that uses the TFS SDK, which returns the list of files contained in a given shelveset.
The sample below assumes knowledge of the Shelveset name & it's owner:
using System;
using System.IO;
using System.Collections.ObjectModel;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
namespace ShelvesetDetails
{
class Program
{
static void Main(string[] args)
{
Uri tfsUri = (args.Length < 1) ? new Uri("TFS_URI") : new Uri(args[0]);
TfsConfigurationServer configurationServer = TfsConfigurationServerFactory.GetConfigurationServer(tfsUri);
ReadOnlyCollection<CatalogNode> collectionNodes = configurationServer.CatalogNode.QueryChildren(
new[] { CatalogResourceTypes.ProjectCollection },
false, CatalogQueryOptions.None);
CatalogNode collectionNode = collectionNodes[0];
Guid collectionId = new Guid(collectionNode.Resource.Properties["InstanceId"]);
TfsTeamProjectCollection teamProjectCollection = configurationServer.GetTeamProjectCollection(collectionId);
var vcServer = teamProjectCollection.GetService<VersionControlServer>();
Shelveset[] shelves = vcServer.QueryShelvesets(
"SHELVESET_NAME", "SHELVESET_OWNER");
Shelveset shelveset = shelves[0];
PendingSet[] sets = vcServer.QueryShelvedChanges(shelveset);
foreach (PendingSet set in sets)
{
PendingChange[] changes = set.PendingChanges;
foreach (PendingChange change in changes)
{
Console.WriteLine(change.FileName);
}
}
}
}
}
Invoking this console app & catching the outcome during execution of the powershell should be possible.
Try:
tfpt review
/shelveset:shelvesetName;userName
You may also need to add on the server option so something like:
tfpt review /shelveset:Code Review;jim
/sever:company-source
I think this is what you are looking for.
This is what I ended up with, based on pentelif's code and the technique in the article at http://akutz.wordpress.com/2010/11/03/get-msi/ linked in my comment.
function Get-TfsShelvesetItems
{
[CmdletBinding()]
param
(
[string] $ShelvesetName = $(throw "-ShelvesetName must be specified."),
[string] $ShelvesetOwner = "$env:USERDOMAIN\$env:USERNAME",
[string] $ServerUri = $(throw "-ServerUri must be specified."),
[string] $Collection = $(throw "-Collection must be specified.")
)
$getShelvesetItemsClassDefinition = #'
public IEnumerable<PendingChange> GetShelvesetItems(string shelvesetName, string shelvesetOwner, string tfsUriString, string tfsCollectionName)
{
Uri tfsUri = new Uri(tfsUriString);
TfsConfigurationServer configurationServer = TfsConfigurationServerFactory.GetConfigurationServer(tfsUri);
ReadOnlyCollection<CatalogNode> collectionNodes = configurationServer.CatalogNode.QueryChildren( new[] { CatalogResourceTypes.ProjectCollection }, false, CatalogQueryOptions.None);
CatalogNode collectionNode = collectionNodes.Where(node => node.Resource.DisplayName == tfsCollectionName).SingleOrDefault();
Guid collectionId = new Guid(collectionNode.Resource.Properties["InstanceId"]);
TfsTeamProjectCollection teamProjectCollection = configurationServer.GetTeamProjectCollection(collectionId);
var vcServer = teamProjectCollection.GetService<VersionControlServer>();
var changes = new List<PendingChange>();
foreach (Shelveset shelveset in vcServer.QueryShelvesets(shelvesetName, shelvesetOwner))
{
foreach (PendingSet set in vcServer.QueryShelvedChanges(shelveset))
{
foreach ( PendingChange change in set.PendingChanges )
{
changes.Add(change);
}
}
}
return changes.Count == 0 ? null : changes;
}
'#;
$getShelvesetItemsType = Add-Type `
-MemberDefinition $getShelvesetItemsClassDefinition `
-Name "ShelvesetItemsAPI" `
-Namespace "PowerShellTfs" `
-Language CSharpVersion3 `
-UsingNamespace System.IO, `
System.Linq, `
System.Collections.ObjectModel, `
System.Collections.Generic, `
Microsoft.TeamFoundation.Client, `
Microsoft.TeamFoundation.Framework.Client, `
Microsoft.TeamFoundation.Framework.Common, `
Microsoft.TeamFoundation.VersionControl.Client `
-ReferencedAssemblies "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.Client.dll", `
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.Common.dll", `
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.VersionControl.Client.dll" `
-PassThru;
# Initialize an instance of the class.
$getShelvesetItems = New-Object -TypeName "PowerShellTfs.ShelvesetItemsAPI";
# Emit the pending changes to the pipeline.
$getShelvesetItems.GetShelvesetItems($ShelvesetName, $ShelvesetOwner, $ServerUri, $Collection);
}
Spent a few days trying to do this as well, this always popped up on google so here is what I found to help future generations:
To get the contents of the shelveset (at least with Team Explorer Everywhere),
use the command: tf difference /shelveset:<Shelveset name>
That will print out the contents of the shelveset and give filenames in the form :
<Changetype>: <server file path>; C<base change number>
Shelved Change: <server file path again>;<shelveset name>
So if your file is contents/test.txt
in the shelveset shelve1 (with base revision 1), you will see :
edit: $/contents/file.txt;C1
Shelved Change: $/contents/file.txt;shelve1
After that, using the tf print command
(or view if not using TEE) on $/contents/file.txt;shelve1 should get you the contents :
tf print $/contents/file.txt;shelve1
Shows you what is in the file.txt in shelveset shelve1
If you want get shelveset changes from server by using tfs command
Using power shell:
Get-TfsPendingChange -Server http://example.com/org -Shelveset shelvsetName
Using vs commands:
c:\projects>tf shelvesets BuddyTest_23
more info about this please see here
https://learn.microsoft.com/en-us/azure/devops/repos/tfvc/shelvesets-command?view=azure-devops
I'm part of a team newly using mercurial and we've identified that when merges occur there are many more errors in files that are manually merged. Is it possible from the mercurial logs (i.e. after someone has done the merge and pushed the merge changeset to the central repository) to detect which files were manually merged?
Note, that I have no idea if this is foolproof. Also, it requires a copy of my as of yet unfinished Mercurial library for .NET, probably only runs on Windows, and is kinda rough around the edges.
Note: I'm assuming that by "were manually merged", you mean "files Mercurial didn't automatically merge for us"
Such a file could still be merged somewhat or completely automatic by an external tool, but if the above assumption is good enough, read on.
However, what I did was to effectively run through all the merges in a test repository, re-doing the merges and asking Mercurial to use only its internal merge tool, which leaves files unresolved if they cannot be automatically merged by Mercurial, and then report all unresolved files, clean up the merge, and move on to the next merge changeset.
The library you need (only in source code form at the moment, I told you it was unfinished):
Mercurial.Net (my open source project, hosted on CodePlex)
I've attached a zip file at the bottom with everything, test repository, script, and binary copy of library.
The script (I used LINQPad to write and test this, output from a test-repository follows):
void Main()
{
var repo = new Repository(#"c:\temp\repo");
var mergeChangesets = repo.Log(new LogCommand()
.WithAdditionalArgument("-r")
.WithAdditionalArgument("merge()")).Reverse().ToArray();
foreach (var merge in mergeChangesets)
{
Debug.WriteLine("analyzing merge #" + merge.RevisionNumber +
" between revisions #" + merge.LeftParentRevision +
" and #" + merge.RightParentRevision);
// update to left parent
repo.Update(merge.LeftParentHash);
try
{
// perform merge with right parent
var mergeCmd = new MergeCommand();
mergeCmd.WithRevision = merge.RightParentHash;
repo.Execute(mergeCmd);
// get list of unresolved files
var resolveCmd = new ResolveCommand();
repo.Execute(resolveCmd);
var unresolvedFiles = new List<string>();
using (var reader = new StringReader(resolveCmd.RawStandardOutput))
{
string line;
while ((line = reader.ReadLine()) != null)
if (line.StartsWith("U "))
unresolvedFiles.Add(line.Substring(2));
}
// report
if (unresolvedFiles.Count > 0)
{
Debug.WriteLine("merge changeset #" + merge.RevisionNumber +
" between revisions #" + merge.LeftParentRevision +
" and #" + merge.RightParentRevision + " had " +
unresolvedFiles.Count + " unresolved file(s)");
foreach (string filename in unresolvedFiles)
{
Debug.WriteLine(" " + filename);
}
}
}
finally
{
// get repository back to proper state
repo.Update(merge.LeftParentHash, new UpdateCommand().WithClean());
}
}
}
public class MergeCommand : MercurialCommandBase<MergeCommand>
{
public MergeCommand()
: base("merge")
{
}
[NullableArgumentAttribute(NonNullOption = "--rev")]
public RevSpec WithRevision
{
get;
set;
}
public override IEnumerable<string> Arguments
{
get
{
foreach (var arg in base.Arguments)
yield return arg;
yield return "--config";
yield return "ui.merge=internal:merge";
}
}
protected override void ThrowOnUnsuccessfulExecution(int exitCode,
string standardOutput, string standardErrorOutput)
{
if (exitCode != 0 && exitCode != 1)
base.ThrowOnUnsuccessfulExecution(exitCode, standardOutput,
standardErrorOutput);
}
}
public class ResolveCommand : MercurialCommandBase<MergeCommand>
{
public ResolveCommand()
: base("resolve")
{
}
public override IEnumerable<string> Arguments
{
get
{
foreach (var arg in base.Arguments)
yield return arg;
yield return "--list";
}
}
}
The sample output:
analyzing merge #7 between revisions #5 and #6
analyzing merge #10 between revisions #9 and #8
merge changeset #10 between revisions #9 and #8 had 1 unresolved file(s)
test1.txt
Zip-file with everything (LINQPad script, Mercurial.Net assembly, go compile it if you don't trust me, and the test repository I executed it against above):
here: zip-file
BIG CAVEAT: Run this only in a clone of your repository! I won't be held responsible if this corrupts your repository, however unlikely I think that would be.
Tis is the shell script variant of Lasses answer:
#!/bin/bash
test "$1" = "--destroy-my-working-copy" || exit
hg log -r 'merge()' --template '{parents} {rev}\n' | sed -e 's/[0-9]*://g' | while read p1 p2 commit
do
echo "-------------------------"
echo examine $commit
LC_ALL=C hg up -C -r $p1 >/dev/null
LC_ALL=C hg merge -r 26 --config ui.merge=internal:merge 2>&1 | grep failed
done
hg up -C -r tip > /dev/null
Example output:
> mergetest.sh --destroy-my-working-copy
-------------------------
examine 7
-------------------------
examine 11
-------------------------
examine 23
-------------------------
examine 31
-------------------------
examine 37
merging test.py failed!