Are there any interesting custom loggers for MSBuild already written? I am especially interested in loggers that would record system load (CPU/Memory/IO) data during the build and relate that to actions performed by the build.
Checkout the MSBuild Extension pack. This contains a lot of extra custom tasks and loggers.
I don't know about your specific needs for the logger. Remember that the purpose of the logger is only to report on different steps of the build. It only accepts a message and an importance property. You would need to add system load collection by yourself. But again, I don't think this kind of code would belong in a custom logger.
Related
Suppose we have sequential build, i.e. a single node. msbuild parses the solution file, examines all the project dependencies and decides to build the projects in a certain order.
Is it possible to instruct msbuild just to output this order without actually building anything?
P.S.
I realize I can implement this logic myself using MSBuild API. I can read the solution file and all the projects and build the dependency graph myself. I am specifically curious if msbuild can do it, since it does this logic anyway already.
There are various diagnostic features in MSBuild but currently there isn't a feature that is like reporting a SQL execution plan or like PowerShell's -WhatIf parameter.
You could submit a feature request at dotnet/msbuild.
If you do submit a feature request, provide the link here.
I'm really impressed with OpenTest project. Found it highly intriguing how many ideas this project is sharing with some projects I created and worked on. Like your epic architecture with actors pulling tasks.. and many others :)
Did you think about including other automation technologies to base Actors on?
I could see two main groups:
1 Established test automation tooling like TestCafe (support for non-selenium gui testing could leverage the whole solution a lot)
2 Custom tooling needed for specific tasks. Would be great to have an actor with some domain-specific capabilities. Now as I can see this could be achieved by introducing another layer of execution worker called by an actor using rest api. What I mean is the possibility of using/including them as new 'actor types' with custom keywords releted.
Thank you for your nice words. We spent a lot of time thinking through the architecture and implementation of OpenTest and it's very rewarding to see that people understand and appreciate the design.
Implementing new keywords (test actions) can be done without creating custom test actors, by creating a new Java class that inherits from the TestAction base class and override its run method. For a simple example, you can take a look at the implementation of the Delay test action. You can then package the new test action in a JAR and drop it (along with any dependencies) in the user-jars subdirectory in your test actor's working directory. The test actor will dynamically load all the JARs it finds in there and will find the new test action class (using reflection) so you can make use of it in your tests. Some useful info and things to look out for:
Your Java project is going to have to define a dependency on the opentest-base project (which is where the TestAction base class is implemented).
When you copy the JAR to where your test actor is, make sure to copy any dependency JARs along with it. Please note that a lot of the dependencies that you might need are already included with the core test actor binaries (you can have a look at the POM.xml to see what they are).
If you happen to have any dependencies that conflict with the other JARs that included with the core test actor binaries, you can apply a technique called shading to "hide" the conflicting classes under a different package name. Most of the times you're not going to need this, but if you do and you get stuck let me know and I'll give you some pointers.
Here's sample project that demonstrates how to build an OpenTest extension that creates a couple of custom keywords: https://github.com/adrianth/opentest-extension-sample
And here's an extensive video tutorial about creating custom OpenTest keywords: https://getopentest.org/tutorials/custom-keywords.html
What are msbuild tasks and what situations should you be using them or not using them? What are the alternatives? What advantages or disadvantages do they offer?
A task implements the Task class and as such can be called from msbuild code. Usually this is done by e.g. writing some C# code implementing the class and building it into a dll which is passed to the UsingTask element to make it available. There's also a shorter way to do this: using Inline Tasks. This allows writing the code directlry in the msbuild file.
Sctrictly speaking there is no alternative since a Task has the definition given above and there is only one such thing with exactly those properties in msbuild. There is also a Target though which is used to call Tasks (and has a bunch of other functionality like expressing dependencies to other targets, defining it's in/outputs, ...). So it's an alternative considering there is some overlap, and I assume this is what you're asking about: you can create functionality either by calling multiple Tasks consecutively in a Target (or having targets depend on other targets etc), or by writing your own Task which performs all or some of those actions.
By example: suppose you want to list a directory and copy all .c files to another directory then zip the directory. Either you write a Target in which you list the files (using an ItemGroup), then call Copy and Zip tasks. Or you write a custom task which uses C# calls like Directory.GetFiles/File.Copy/ZipFile.CreateDirectory and have the target call just your custom task.
Advantages of custom tasks: they can contain arbitrary code so you can basically do anything you can imagine. Disadvantage: needs to be built, maintained and shipped with the msbuild code using them (either as a dll or else as source code in which case they need to be built on the fly before they can be used).
Advantages of targets with existing (built-in) tasks: most common functionality found in build systems is readily available in tried and tested code with ample documentation and/or SO questions as additional resources, no reinventing of wheels, others know that code already as well, no maintainance of custom code. Disadvantage: not every single piece of functionality is available, number of composed tasks to achieve functionality might be too high or impractical.
When to use tasks is basically answered by the two paragraphs above. I can't possibly tell you how much custom tasks you'll be writing in practice as I don't know your usecases. Looking at all msbuild code I have myself (for dealing with a mix of C/C++/C#/Python projects) I'd say it's about 95% built-in tasks and 5% custom tasks. Of those 5% most is from tasks written by others ike MSBuild Community Tasks and MSBuild Extension Pack.
POST 1: theoretical question
We use some software, that is actually a Web Module with its own Tomcat and shell scripts for controlling it. It has also a Plugin System, which allows you to upload a .jar file with a certain structure to add new functionality to the Application.
Question:
I would like to control&actually change the responses to different calls in the main system/application (not in my jar). Could I use AspectJ to do that? Why or why not? What would be the other general possibilities, except changing the code of the Main Application.
POST 2: the try
I tried to do it this way (in Eclipse):
In the AspectJ Project I added the jar file, where the classes to be woven are (actually I added it to the INPATH).
Exported the Project as "Jar with AspectJ support"
Deployed the jar file exported at the step 2: No result.
Questions:
In the exported aspect-jar, there are only the .class files of the AspectJ project, no .class files for the INPATH-Jar.
Should there be other classes, from the imported INPATH-jar?
In the exported aspect-jar there is no jar with the aspectj-runtime (aspectj-rt.jar). Should it be there, or how to configure the virtual machine to have it?
Yes, why not? If you could extend your question and explain (maybe with an example) which actors and actions there are in the system, we might be able to help you in a more conrete fashion. But basically I see no problem. The JAR modules might be loaded dynamically, but if you know which calls in the Tomcat app you want to intercept, you can easily instrument them either statically by reweaving the existing classes or dynamically via LTW (load-time weaving) during JVM start-up. There is no need to touch your uploaded JAR modules, which is, as I understand you, what you want to avoid.
You probably want to weave your main application's target classes via
execution(<methodsToBeChecked>) pointcut in combination with
around() advice.
The other details depend on your specific use case, the package, class and method names, parameters etc. The around advice can do one or several of the following things:
determine caller,
check call paramaters,
manipulate call parameters,
call original target with original or changed parameters,
alternatively not perform the original call at all,
pass back the result of the original call to the caller,
pass back a manipulated version of the result to the caller,
pass any synthetic value with the correct return type to the caller,
catch exceptions raised by the original call,
throw your own exceptions
etc.
Your fantasy (and AspectJ's few limitations) are the limit. :-)
So far I have two short questions:
1) What precisely are the benefits of creating custom nature?
2) Is it possible to somehow programmatically read files in [project]/.setting or [workspace]/.metadata/.plugins?
I'm using Eclipse Helios (3.6).
Ad 1. I've read that you can't have two natures ofthe same set, that you can use it to associate certain perspectives/tools (ex. builder) with it but well.. anyting else I can't do easily without nature? Ex. I can easily add a builder by modifying an IProject variable.
Ad 2. I tried to find a way to read project specific settings or plugin settings but failed. No specs, different file types, inconsistent XML tags... Is it at all possible without parsing them manually?
Thanks for your help!
Paweł
Think of a nature as a flag. All project-related functionality in Eclipse is triggered by natures. Project properties pages, context menu items, etc. appear based on presence of natures. Third parties can check for presence of nature to tell if the project is of certain "type". A nature also has install/uninstall methods. This gives you a convenient place to implement all actions that need to happen on the project when your technology is enabled. Why is that convenient? Because a third party can simply add the nature without knowing what else is necessary to configure and your code takes care of the rest.
Plugins write to [project]/.setting or [workspace]/.metadata/.plugins locations in different ways. The file formats are never documented as they aren't meant to be manipulated directly. Some plugins re-use the common ProjectScope and InstanceScope classes to read/write the data. Some read/write on their own. I would start with what information you are trying to read, figure out which plugin it belongs to and then see if there is public API in that plugin for accessing that information. Reading these settings directly is almost never going to be the correct approach.