C#->Python SVN Pre-Commit Hook: How to access svn:keywords? - c#

I've been asked to re-add an extra check to our pre-commit hook to ensure svn:keywords are set on certain paths in our repos (e.g. scripts that need the Revision and URL values injecting). We had a clunky pre-commit hook written in C# using SharpSvn doing this originally, but we've migrated our SVN server to Linux, so I rewrote the hook in Python. It has most of the functionality, but I missed out the keyword checking.
In C#, the code used is like so:
SvnPropertyCollection propCollection;
svnLookClient.GetPropertyList(svnHookArgs.LookOrigin, item.Path, out propCollection);
....
if (item.Path.Contains("some path") && !propCollection.Contains("svn:keywords"))
{ /*Fail the commit here*/ }
I've found out the hard way that the transaction properties do not contain svn:keywords, even when I make a commit where all I have done is set them; calling svn.fs.svn_fs_txn_proplist on the transaction gives me the following properties:
svn:log
svn:txn-client-compat-version
svn:txn-user-agent
svn:author
svn:date
My Python code looks like this:
def check_keywords_are_set(transaction, repos_name):
commit_has_source_files = False
source_extensions = ('.sql', '.hlr') #Only care about source files
transaction_root = svn.fs.svn_fs_txn_root(transaction)
changed_paths = svn.fs.paths_changed(transaction_root)
for path, change in changed_paths.iteritems():
if repos_name == 'repo1' or (repos_name == 'repo2' and ('some path' in path): #These are the paths I want to enforce keywords being set on
if path.endswith(source_extensions):
commit_has_source_files = True
if not commit_has_source_files:
return True
#debugging code here:
transaction_props = svn.fs.svn_fs_txn_proplist(transaction)
sys.stdout.write('Transaction prop list:\n{0}\n'.format(transaction_props))
#end debugging
keywords = svn.fs.svn_fs_txn_prop(transaction, 'svn:keywords')
#keywords is always None
Looking back at the C# code, I can see references to svnlook, so I guess I'll have to use this. However, I'm getting confused between 'revision properties' and all other 'properties'. I'm also not sure how to write this so that if a developer is adding the missing keywords to files within a folder that should have them, or we're creating a new folder where this will later be enforced, it won't throw a false negative. The documentation for doing this in Python is quite poor and generally requires reading the C API source, which unfortunately I cannot get my head around (I am not a C developer), let alone translate into Python. Any assistance would be greatly appreciated.

Related

FileVersionInfo.GetVersionInfo alternative

I have an application that checks for updates. To check for updates I need to get the version of the file on the user's computer.
I used this code:
if (File.Exists(dataFile))
{
var verLocal = Version.Parse(FileVersionInfo.GetVersionInfo(dataFile).FileVersion);
if (verSite > verLocal)
{
needToAdd = true;
}
}
Today I found out that the method FileVersionInfo.GetVersionInfo(String) may not get the file version! Here is a description from the help:
If the file did not contain version information, the FileVersionInfo
contains only the name of the file requested.
So that there was no error, I did like this:
if (File.Exists(dataFile))
{
if (Version.TryParse(FileVersionInfo.GetVersionInfo(dataFile).FileVersion, out var verLocal))
{
if (verSite > verLocal)
{
needToAdd = true;
}
}
}
But now there is a problem - if the user this method will never return the version of the file, then the user will never receive updates! So I need a way to get the version of the file that always works.
Are there alternatives to this method in c#?
That Version info metadata really only applies the Executeables or DLL's. It is supposed to be set during compilation. I have not seen it apply (be written) to any word document, image or similar non-executeable file.
A pretty dated approach for archiving, would be the old Archive Bit/Atribute. Just throwing it out there for completeness.
Usually for a "did it change?" check, it is sufficient to just check the file Size and LastUpdated dates of the file for changes. If you pick any backup maker, it will not do more advanced checks then this (plus the archive bit thing as a option). That one of those two values does not change can happen. But both of them is to unlikely to bother with.
The only 100%* reliable way to check for changes is to calculate a files hash-value. But that usually is something you only do during stuff like install verifications, not as a basic backup.
*Technically not even that is 100%. Hash Colissions are a thing, but are realistically impossible if you already check size and change date.

Reading a text file and perform the conditional statements manually

I have a text file - a template file, which has all the imports, parameters, constants, class name, methods etc.
I need to read it manually and wherever needed, need to replace the corresponding value from excel file.
In this within the method we have if, else statements too.
Where i need to read the statement, if the condition statisfies, enter the loop and proceed further. The corresponding else part needs to be ignored.
Any idea\suggestions on how this can be done? the if else needs to be executed manually.
Sample code Example:
if(0==0) {
if(1==0) {
value=0;
} else {
value=1;
}
return value;
} else {
return 0;
}
So in this case, if the first if part returns, I need to skip the last else. Im counting the condition satisfaction by counting the braces.
For those purpose i like to use IronPython. It is a language based on the Dynamic Language Runtime (DLR). This should give you a nice tool to do what you want. More information can be found here: Home of IronPython
To complete the answer, also IronRuby should be a solution for you. But with this i have no experiance...
EDIT
Even with the newest .net framework and Roslyn you have a big amount of possibilities to do what you want. Just read a litte bit about c#-scripting with roslyn.
If IronPython/Ruby aren't desirable options, you may want to look at Roslyn. If that's not an option there's always the System.Reflection.Emit namespace.

T4 Code Generation In the Abstract (No Automatic Compilation, No Automatic File Management)

We have a circumstance where we basically want to generate string representation of a code file by passing in arguments for the template contents and information the template needs to build itself:
//*** PSEUDO CODE *** //
//loaded from an embedded resource file in a .dll. no physical file on file system
string templateContents = ...;
//has properties used by the template
object complexParameter = ...;
string generatedCode = generator.MakeCode(templateContents, complexParameter);
However, we're currently running into problems trying to get the T4 template generation to do what we want. The actual code we're using is:
var templatingEngine = new Engine();
//T4TextTemplateHost is our own class implementing ITextTemplatingEngineHost & IServiceProvider
var templateHost = new T4TextTemplateHost(references, imports)
{
Properties = parameters,
//this is supposed to be a file path? the generation bombs if this is left null
TemplateFile = "Dummy Value"
};
var templateContents = GetTemplateFileContents();
var retVal = templatingEngine.ProcessTemplate(templateContents, templateHost);
//if a CompilerError occurs, we get NO code, just a "ErrorGeneratingOutput" message
foreach (CompilerError error in templateHost.Errors)
//this information is pretty worthless: a compile error with line number for a
//non-existant code file
retVal += String.Format("{0}{2}Line: {1}{2}{2}", error.ErrorText,
error.Line, Environment.NewLine);
The problem is that the code generator seems to expect a physical file somewhere, and when things go wrong, we don't get code back, we get useless error messages back. It is our strong preference not NOT have the code automatically compiled, especially when the generated code has an error (we want a full, broken file to examine when troubleshooting).
We also want the output as a string, that we can take and do with whatever we wish.
Is there a way to make T4 code generation work more like the pseudo code example? We're on the verge of abandoning the T4 tool in favor of something like CodeSmith because T4 seems like it's too limited/geared toward a very specific way of managing templates and processing output.
I don't think it is possible to get T4 to generate anything if there are errors in the template you pass in. T4 will try to convert your template into codedom with extra statements that write out to a stringwriter, the final stringwriter is then returned as the result. If there are any errors in the template, the code will not complie and thus it will have nothing to return to you. The errors you get back should resolve to the lines in the template you passed in, at least that has been my experience.
I am not sure if Code Smith works in a different way but depending on the complexity of what you are trying to render you might have some luck using Nustache if it's simple enough. It's a dot net version of mustache templates. It supports basic looping and if/then type control blocks. I have successfully used it with embedded text files to generate simple templates for emailing and reports.

Seeing Trends in Code Metrics with NDepend

I have a version of NDepend for build servers and have automated the NDepend report generation. So, every night the build does its thing and NDepend reports/XML are generated. What I now want to do is track some metrics as a function of time.
So, for instance, it might be nice to have a graph of a particular type or namespace's, say, afferent coupling, on the y axis with time on the x axis. I know that I can compare two NDepend builds and have code and metric diffs, but what I'm looking to do is compare the same single metric or metrics over N builds to see ongoing trends.
I'm sort of assuming that there isn't a tool that does this currently and that I'll have to roll my own, but if there is one out there, I'd sure love to hear about it before investing the time. So, does NDepend itself support anything like this, or is there some sort of utility that already exists that I could use?
I'm also open to suggestions for other technologies that would accomplish this besides NDepend, though I have a strong preference for NDepend due to already having invested in it and being familiar with how it works.
Thanks in advance.
With NDepend, you can write a Code Query over LINQ (CQLinq) to match evolution through any code metrics. For example you could start with the query:
from t in JustMyCode.Types
where t.IsPresentInBothBuilds() &&
t.CodeWasChanged()
let tOld = t.OlderVersion()
let newLoC = t.NbLinesOfCode
let oldLoC = tOld.NbLinesOfCode
let newCC = t.CyclomaticComplexity
let oldCC = tOld.CyclomaticComplexity
let newCov = t.PercentageCoverage
let oldCov = tOld.PercentageCoverage
where newLoC > oldLoC || newCC > oldCC || newCov < oldCov
select new { t, newLoC, oldLoC, newCC, oldCC, newCov, oldCov }
...and get an instant result in Visual Studio. Such rule is integrable into your CI TFS build process and can also be shown in a HTML+javascript report.
Several default code rules are provided to restrict over code metric trending:
Avoid making complex methods even more complex
Types that used to be 100% covered but not anymore
From now, all types added or refactored should respect basic quality principles
Avoid adding methods to a type that already had many methods
Avoid making large methods even larger

adding stock data to amibroker using c#

I have had a hard time getting and answer to this and i would really , really appreciate some help on this.
i have been on this for over 2 weeks without headway.
i want to use c# to add a line of stock data to amibroker but i just cant find a CLEAR response on how to instantiate it in C#.
In VB , I would do it something like;
Dim AmiBroker = CreateObject("Broker.Application")
sSymbol = ArrayRow(0).ToUpper
Stock = AmiBroker.Stocks.Add(sSymbol)
iDate = ArrayRow(1).ToLower
quote = Stock.Quotations.Add(iDate)
quote.Open = CSng(ArrayRow(2))
quote.High = CSng(ArrayRow(3))
quote.Low = CSng(ArrayRow(4))
quote.Close = CSng(ArrayRow(5))
quote.Volume = CLng(ArrayRow(6))
The problem is that CreateObject will not work in C# in this instance.
I found the code below somewhere online but i cant seem to understand how to achieve the above.
Type objClassType;
objClassType = Type.GetTypeFromProgID("Broker.Application");
// Instantiate AmiBroker
objApp = Activator.CreateInstance(objClassType);
objStocks = objApp.GetType().InvokeMember("Stocks", BindingFlags.GetProperty,null, objApp, null);
Can anyone help me here?
Thanks
The VB code uses something called late binding against a "COM IDispatch" compatible component. Late binding is not supported by C# (up to C# version 3). The C# compiler only compiles code it knows how bind to (called early bind).
To do what you want to do, it would be easier to generate a proxy dll via Visual Studio - select add reference on a project, then select the tab COM, and then search for that ami broker component in the list. This will generate a proxy dll which you can program against using similar code as the one you have showed for VB.
In C# 3.0, you'll discover that you sometimes have to use Type.Missing and that you have to do some additional explicit casting, even though you'd think that it doesn't seem logical.
C# 4.0 has something called dynamic, which allows you to write much cleaner code when accessing COM components.
See my answer here for the code:
https://stackoverflow.com/a/20101274/1581495
I actually use this method now. I save text files from MetaTrader then import them realtime into AmiBroker. Doing it this way is essentially like importing quotes using the ASCII import, so you'll need to make sure that you prepare your import format file. For me, a line of sample data looks like this:
EURAUD,20170607,00:00:00.4885,1.50174,1.50231,1 //Symbol, Date, Time (HH:MM:SS.tttt), Bid, Ask, Volume
I use the default.format file, which looks like this:
$FORMAT TICKER,DATE_YMD,TIME,CLOSE,AUX1,VOLUME
$SEPARATOR ,
$AUTOADD 0
$BREAKONERR 0
$SKIPLINES 0
Find the guide and some examples here on importing and formats:
https://www.amibroker.com/guide/d_ascii.html
EDIT: this might also help with importing
http://www.amibroker.com/kb/2016/01/23/how-to-create-custom-import-definition-for-ascii-importer/

Categories