diff --git a/README.md b/README.md
index 6f17442..ba4299c 100644
--- a/README.md
+++ b/README.md
@@ -21,25 +21,27 @@ Meet the scripted Jira worklogging! Give it your worklogs in a CSV file (and you
## Configuration
The jwl.config file is a simple JSON structure. It can be placed in (and will be read by jwl in the priority order of)
- - "current folder" (as in "where your shell's %CD%
or ${PWD}
is at the moment")
- - local application data (%USERPROFILE%\AppData\Local
)
- - roaming application data (%USERPROFILE%\AppData\Roaming
)
- - jwl's "installation" folder
+- "current folder" (as in "where your shell's %CD%
or ${PWD}
is at the moment")
+- local application data (%USERPROFILE%\AppData\Local
)
+- roaming application data (%USERPROFILE%\AppData\Roaming
)
+- jwl's "installation" folder
As for the CLI worklogger binary, there are command-line options available as well. Any partial options supplied via CLI will override their respective jwl.config counterparts with the highest priority.
### "ServerClass" setting
Available values are:
- - Vanilla
- - TempoTimeSheets
- - ICTime (not implemented yet)
+- Vanilla
+- TempoTimeSheets
+- ICTime (not implemented yet)
## The input CSV structure
Five columns, data delimited (by default) by a colon:
- Date
(string) - worklog day date (valid formats: YYYY-MM-DD
, YYYY/MM/DD
, DD.MM.YYYY
, all with optional HH:MI:SS
part)
- IssueKey
(string) - Jira issue key (SOMEPROJECT-1234
and the likes)
- - TempoWorklogType
(string) - Tempo Timesheets worklog type; values are checked against the available values from Jira server on each execution.
+ - Activity
(string) - Tempo Timesheets worklog type or ICTime activity; values are remapped
- TimeSpent
(string) - time to be logged for the Jira issue and the date (valid formats: HH:MI
, MI
, HH h MI
, HH h MI m
)
- Comment
(string) - optional worklog comment
+
+The Activity
values are remapped via config $.JiraServer.ActivityMap
. The mapping configuration depends on your Jira server+plugins configuration and is a subject of manual setup by yourself.
diff --git a/jwl.core/JwlCoreProcess.cs b/jwl.core/JwlCoreProcess.cs
index cc9cdb1..b380815 100644
--- a/jwl.core/JwlCoreProcess.cs
+++ b/jwl.core/JwlCoreProcess.cs
@@ -164,7 +164,7 @@ private async Task FillJiraWithWorklogs(InputWorkLog[] inputWorklogs, WorkLog[]
MultiTaskStats progress = new MultiTaskStats(fillJiraWithWorklogsTasks.Length);
MultiTask multiTask = new MultiTask()
{
- TaskFeedback = t => Feedback?.FillJiraWithWorklogsProcess(progress.ApplyTaskStatus(t.Status))
+ OnTaskAwaited = t => Feedback?.FillJiraWithWorklogsProcess(progress.ApplyTaskStatus(t.Status))
};
await multiTask.WhenAll(fillJiraWithWorklogsTasks);
@@ -181,7 +181,7 @@ private async Task ReadInputFiles(IEnumerable fileNames)
MultiTaskStats progressStats = new MultiTaskStats(readerTasks.Length);
MultiTask multiTask = new MultiTask()
{
- TaskFeedback = t => Feedback?.ReadCsvInputProcess(progressStats.ApplyTaskStatus(t.Status))
+ OnTaskAwaited = t => Feedback?.ReadCsvInputProcess(progressStats.ApplyTaskStatus(t.Status))
};
if (readerTasks.Any())
diff --git a/jwl.infra/MultiTask.cs b/jwl.infra/MultiTask.cs
index 2d7bb70..b180c39 100644
--- a/jwl.infra/MultiTask.cs
+++ b/jwl.infra/MultiTask.cs
@@ -6,8 +6,8 @@ public enum ProgressState
{
Unknown,
Starting,
- BeforeTaskWait,
- AfterTaskWait,
+ BeforeTaskAwait,
+ AfterTaskAwait,
Finished,
Error,
Cancelled
@@ -15,8 +15,8 @@ public enum ProgressState
public ProgressState State { get; private set; } = ProgressState.Unknown;
- public Action? ProcessFeedback { get; init; }
- public Action? TaskFeedback { get; init; }
+ public Action? OnStateChange { get; init; }
+ public Action? OnTaskAwaited { get; init; }
public MultiTask()
{
@@ -25,35 +25,34 @@ public MultiTask()
public async Task WhenAll(IEnumerable tasks, CancellationToken? cancellationToken = null)
{
State = ProgressState.Starting;
- ProcessFeedback?.Invoke(this);
+ OnStateChange?.Invoke(this);
HashSet tasksToExecute = tasks.ToHashSet();
List errors = new List();
while (tasksToExecute.Any())
{
- State = ProgressState.BeforeTaskWait;
- ProcessFeedback?.Invoke(this);
+ State = ProgressState.BeforeTaskAwait;
+ OnStateChange?.Invoke(this);
- Task? taskFinished = null;
try
{
cancellationToken?.ThrowIfCancellationRequested();
- taskFinished = await Task.WhenAny(tasksToExecute);
+ Task finishedTask = await Task.WhenAny(tasksToExecute);
- State = ProgressState.AfterTaskWait;
- ProcessFeedback?.Invoke(this);
- TaskFeedback?.Invoke(taskFinished);
+ State = ProgressState.AfterTaskAwait;
+ OnStateChange?.Invoke(this);
+ OnTaskAwaited?.Invoke(finishedTask);
- if (taskFinished.Status is TaskStatus.Faulted or TaskStatus.Canceled)
+ if (finishedTask.Status is TaskStatus.Faulted or TaskStatus.Canceled)
{
- tasksToExecute.Remove(taskFinished);
- throw taskFinished.Exception ?? new Exception($"Task ended in {taskFinished.Status} status without exception details");
+ tasksToExecute.Remove(finishedTask);
+ throw finishedTask.Exception ?? new Exception($"Task ended in {finishedTask.Status} status without exception details");
}
- else if (taskFinished.Status == TaskStatus.RanToCompletion)
+ else if (finishedTask.Status == TaskStatus.RanToCompletion)
{
- if (!tasksToExecute.Remove(taskFinished))
+ if (!tasksToExecute.Remove(finishedTask))
throw new InvalidOperationException("Task reported as finished... again!");
}
}
@@ -67,24 +66,27 @@ public async Task WhenAll(IEnumerable tasks, CancellationToken? cancellati
}
}
- if (errors.All(ex => ex is TaskCanceledException))
+ if (errors.Any())
{
- State = ProgressState.Cancelled;
- ProcessFeedback?.Invoke(this);
+ if (errors.All(ex => ex is TaskCanceledException))
+ {
+ State = ProgressState.Cancelled;
+ OnStateChange?.Invoke(this);
- throw new TaskCanceledException($"All {errors.Count} tasks have been cancelled", new AggregateException(errors));
- }
- else if (errors.Any())
- {
- State = ProgressState.Error;
- ProcessFeedback?.Invoke(this);
+ throw new TaskCanceledException($"All {errors.Count} tasks have been cancelled", new AggregateException(errors));
+ }
+ else
+ {
+ State = ProgressState.Error;
+ OnStateChange?.Invoke(this);
- throw new AggregateException(errors);
+ throw new AggregateException(errors);
+ }
}
else
{
State = ProgressState.Finished;
- ProcessFeedback?.Invoke(this);
+ OnStateChange?.Invoke(this);
}
}
}