-
Notifications
You must be signed in to change notification settings - Fork 9
Code History Script API
Scripts are written in Groovy and can use any Groovy classes/methods (If you are not familiar with Groovy, Language Specification and Working with collections can be particularly useful.)
Script can contain one or more implementations of Analyzer
interface or
just code with implicit data
, context
variables and will be implicitly converted into Analyzer
implementation.
import codehistoryminer.publicapi.analysis.Context
import codehistoryminer.publicapi.analysis.Analyzer
interface Analyzer<T> {
T analyze(List data, Context context)
}
data
parameter is a list of objects corresponding to a line in csv file.
There is no super-type for data objects. Fields can be accessed on objects using column names from csv file.
Note that existing attributes are modifiable and new fields can be assigned: o.newAttribute = 123
.
Since input data is read from csv file (which doesn't store information about types),
during deserialization there is an attempt to convert strings into more specific types.
There are attempts to convert csv string value into Date
, Time
, Integer
, Double
.
If non of the above works, value is assumed to be a String.
Note that Date and Time classes are located in codehistoryminer.publicapi.lang
package. See their interfaces below.
Each object in input data represents a file change (saved during VCS grabbing).
To make access to data more convenient, there is FileChange
class which wraps data object adding some methods.
Input data can be wrapped at once FileChange.wrap(data)
or each object data.collect{ new FileChange(it) }
.
See APIs section below for list of methods available in FileChange
class.
Value returned by the script of Analyzer
implementation will be displayed by the plugin.
If output is Collection
of Map
, FileChange
or input data objects,
the output will be converted into temporary csv file and opened in IDE.
Otherwise, output is displayed as popup messages using toString()
method on objects.
There are plans to include more types of output including visualizations.
There are several reasons to use Context
object:
- to log information from complex or long-running script, e.g.
context.log("hello")
. Logs are written to IDE log file, seeMain menu -> Help -> Show Log
action. - to cancel long-running scripts, e.g.
context.throwIfCancelled()
, - to report progress from long running scripts, e.g.
context.progress.set(percentComplete)
The simplest script which shows popup message.
"Hello world"
Show the amount of rows in input data.
data.size()
Filter data by author.
data.findAll{
it.author == "Kent Beck"
}
Wrap data as FileChange
object and filter by file type
import codehistoryminer.publicapi.analysis.filechange.FileChange
data.collect{ FileChange.wrap(it) }
.findAll{ it.fileExtension() == "txt" }
Find number of file modifications by author.
data.groupBy{ it.author }
.collect{ [author: it.key, fileModificationCount: it.value.size()] }
.sort{ -it.fileModificationCount }
package codehistoryminer.publicapi.analysis
class Context {
final Progress progress = new Progress(100)
void throwIfCancelled()
void log(String message)
}
package codehistoryminer.publicapi.lang
class Progress {
void setTotal(long total)
void set(long value)
void add(long value)
void complete()
}
package codehistoryminer.publicapi.analysis.filechange
class FileChange implements DataWrapper, Cloneable {
static FileChange wrap(data)
static Collection<FileChange> wrap(Collection collection)
FileChange(data)
ChangeType getFileChangeType()
void setFileChangeType(ChangeType changeType)
Date getCommitDate()
String fullFileName()
String nonEmptyPackageName()
String nonEmptyFileName()
String fileExtension()
@Override getData()
@Override FileChange clone()
static List<FileChange> useLatestNameForMovedFiles(List<FileChange> events, Context context = Context.none)
}
enum ChangeType {
ADDED,
MODIFIED,
DELETED,
MOVED
}
package codehistoryminer.publicapi.lang;
class Date implements Comparable<Date> {
Date(Time time)
Date(java.util.Date javaDate, TimeZone timeZone = TimeZone.getDefault())
static Date today(TimeZone timeZone = TimeZone.getDefault())
static Date zero(TimeZone timeZone = TimeZone.getDefault())
TimeZone timeZone()
Date withTimeZone(TimeZone timeZone)
java.util.Date javaDate()
boolean after(Date that)
boolean afterOrEqual(Date that)
boolean before(Date that)
boolean beforeOrEqual(Date that)
Date shiftDays(int value)
Date shift(int value, int calendarField)
long distance(Date date)
String format(Formatter formatter)
@Override int compareTo(@NotNull Date that)
@Override boolean equals(Object o)
@Override int hashCode()
static class Formatter {
static final Formatter ddMMyyyy = new Formatter("ddMMyyyy");
static final Formatter dd_MM_yyyy = new Formatter("dd/MM/yyyy");
static final Formatter d__MMM__yyyy = new Formatter("d MMM yyyy");
static final Formatter dd__MMM__yyyy = new Formatter("dd MMM yyyy");
static final Formatter ISO1806 = new Formatter("yyyy-MM-dd'T'HH:mm:ssZ");
}
}
package codehistoryminer.publicapi.lang;
class Time implements Comparable<Time> {
Time(java.util.Date javaDate, TimeZone timeZone = TimeZone.getDefault())
static Time now(TimeZone timeZone = TimeZone.getDefault())
static Time zero(TimeZone timeZone = TimeZone.getDefault())
Time withTimeZone(TimeZone timeZone)
TimeZone timeZone()
long millis()
java.util.Date javaDate()
Date toDate()
Time floorToDay()
Time floorToWeek()
Time floorToMonth()
Time floorTo(Interval interval)
Time shift(int value, int calendarField)
int get(int calendarField)
int dayOfWeek()
int hour()
int minute()
Collection<Time> timeRange(Time toTime, Time.Interval interval)
boolean after(Time time)
boolean before(Time time)
boolean beforeOrEqual(Time that)
boolean afterOrEqual(Time time)
String format(Formatter formatter)
@Override int compareTo(@NotNull Time that)
@Override String toString()
@Override boolean equals(Object o)
@Override int hashCode()
static class Formatter {
static final Formatter dd_MM_yyyy = new Formatter("dd/MM/yyyy");
static final Formatter kkmm_dd_MM_yyyy = new Formatter("kk:mm dd/MM/yyyy");
static final Formatter kkmmss_dd_MM_yyyy = new Formatter("kk:mm:ss dd/MM/yyyy");
static final Formatter kkmmsss_dd_MM_yyyy = new Formatter("kk:mm:ss.SSS dd/MM/yyyy");
static final Formatter yyyy_MM_dd_HHmmss_Z = new Formatter("yyyy-MM-dd HH:mm:ss Z");
static final Formatter ISO1806 = new Formatter("yyyy-MM-dd'T'HH:mm:ssZ");
}