Question
Sean Connelly · Nov 16, 2018

Detecting Source Code Change?

Is there a responsive way to detect a source code change without using a source control hook?

Update

I have my own custom unit test tool which has lots of extra functions that I find useful such as Asserting HL7 Transformers and REST targets.

I have a studio hook that will send an event signal to my test runner that will automatically re-run a specific test class or test suite, for which I have a test runner viewing page that updates with the results.

There are some environments that already have a studio class registered and I don't want to shim something in-between the two.

I've been digging around for some other solutions, but all I can come up with is scanning the ^oddCOM global every second for items in my watch list, which actually only consumes a few milliseconds. If I can't find a more responsive alternative then I will probably go with this approach.

1
0 414
Discussion (8)3
Log in or sign up to continue

I think we don't have any other possibilities how to catch changes in source code. Do you know how to catch if any object in any class was changed, outside of this class, if you don't have any triggers there? No easy task. But I think it is possible to find some tricky ways if you don't care about just in time notifications. You can monitor any changes in the data, and filter by changing particular globals and subscripts. 

If you will describe what are you going to achieve exactly, it will be easier to help you.

Documentation is not too verbose about it, do you agree? A small sample would be very helpful. E.g., how can one use it to recognize which of his/her classes was changed sinse some <timestamp>?

Shame I can't see the code behind. I will do some benchmarks against a direct ^oddCOM scan, if its as fast then it looks like it might be a viable alternative.

The %System/%System/RoutineChange audit event is the only thing other than a source control hook that comes to mind. That's handy for detecting source code changes after the fact (when a class is compiled), but not intercepting attempts to change source code via an editor. What's your specific use case?

Yeah, there's not much info.

To create inventory scan call:

set in = ##class(Inventory.Scanner).RunScan("Version 1")
set dbU = ##class(Inventory.DatabaseComponent).%New()
do dbU.Init(in,"C:\InterSystems\Ensemble\mgr\db\CACHE.DAT")
do in.RootComponent.AddComponent(dbU)                 
set sc = in.%Save()
//do in.WriteToFile("c:\Temp\scanVersion"_$tr($zdt($h,8)," :","Z")_".xml")

And to get diff between two versions/times use SQL:

SELECT
  s1.Name,
  s1.scan->EndTimeStamp,
  s2.scan->EndTimeStamp
FROM Inventory.RoutineComponent s1
JOIN Inventory.RoutineComponent s2 ON s1.Name=s2.Name
WHERE s1.scan=1 AND s2.scan=2 AND NOT s1.SHA1Hash=s2.SHA1Hash

it would return items with hashes changed between scan 1 and 2. The same query can be further modified to accept timestamps, etc.

Well the fastest would probably be custom table into which you periodically write results of this query:

SELECT
ID, Hash
FROM %Dictionary.CompiledClass

Hash in %Dictionary.CompiledClass is calculated on each class change/compilation.

As in this case hashes are already calculated.

Inventory iterates ^rOBJ and calculates hash.

Use Inventory utility.

It records classes and their hashes. Compare two inventory scans to get changes.