Skip to content

Latest commit

 

History

History
112 lines (77 loc) · 5.91 KB

development.md

File metadata and controls

112 lines (77 loc) · 5.91 KB

Developing with this solution

I've used this as an opportunity to prove out some of the benefits of the CommandDotNet v3 preview which provides tools to ease troubleshooting. Documentation for these tools is pending so I'll summarize here.

Architecture

Design Theory

A console app is an interface to business logic, much the same as a web api is. In this way, commands are analagous to endpoints.

This app is designed the similar to a web api. Let's compare the layers...

Layer Web API Console
Host Program Program
API Endpoints Commands
Business Logic Business Logic Business Logic

The same business logic could be hosted in both types of app and the console can provides types of interaction, feedback and long lived processes that require additional components in a web app.

Implementation
  • Jira2AzureDevOps contains just the program and configuration logic
  • Jira2AzureDevOps.Console contains all of the commands and middleware logic
  • Jira2AzureDevOps.Logic contains aall of the migration busines logic

The working directory serves as the local data store for a migration. A migration file is stored for each migration to track it's import status.

Export & Import use the same IJiraApi stack. Export is a by-produce of the CachedJiraApi using LocalDirJiraApi. Due to this design, Import also performs an Export for issues that aren't already exported. This ensures all issues in the cache and available for archive.

C# classes were created for Json deserialization. I used QuickType to generate the classes from json data with some tweaks afterward. The classes do not contain a comprehensive list of every field. They contain what I needed for the project and extra where I didn't remove the unused properties. Enhance these objects if you need to import more fields. I found this approach useful for interrogating the data.

RSP files

described in the README.md

Using appSettings for default options

described in the README.md

enabled by SetDefaultsFromConfigMiddleware

Debug Directive

Debugging console apps can be a hassle. Changing the arguments in the project properties is a lot of extra steps.

CommandDotNet includes a useful feature for debugging called a Debug Directive initially created by the System.CommandLine project. By specifying [debug] as the first argument, you'll be prompted to attach a debugger to the current process.

$ jira2ado [debug] export issues-by-id

Attach your debugger to process 18640 (dotnet).

This makes it easy to debug with different arguments every time.

Logging

I used NLog for structured logging and to take advantage of that ecosystem of appenders without lock-in. Some options include:

Console logging is enabled by default at INFO level and above. Commands who's output should not contain console logs (eg. report commands) can disable console logging with the DisableConsoleLoggingAttribute

enabled by DisableConsoleLoggingMiddleware

When a command is run, Repro Headers (arguments and other system information) are included at the start of the run. These can be disabled for a command with the NoReproHeadersAttribute.

[I][09:20:22]
***************************************
 Command: export issues-by-project
  Options:
    projects           = APP
    issue-list-source  = Cache
    workspace          = C:\jira2ado\jira-cache (default)
    jira-username      = me@jira (default)
    jira-token         = ***** (default)
    jira-url           = https://company_slug.atlassian.net (default)
    jira-batch-size    = 100 (default)

 Original input:
   export issues-by-project -P APP --issue-list-source Cache

  Tool version  = Jira2AzureDevOps.exe 1.0.0.0
  .Net version  = .NET Framework 4.8.3815.0
  OS version    = Microsoft Windows 10.0.18362
  Machine       = my-laptop
  Username      = my-laptop\me
***************************************

(default) indicates the value wasn't provided in the command line, as can be seen from the Original input section. I've found this incredibly helpful when trying to repro a bug or simply confirm what I've already done. The Solidify team had a version of this as well and I've included the environment data they added.

Tip: Repro headers are not logged to console when a command is decorated with DisableConsoleLoggingAttribute. The headers will still output to the log file, so this is generally preferred over NoReproHeadersAttribute

enabled by ReproHeadersMiddleware

IArgumentModel validation

Argument models allow defining arguments as properties in a class for reuse. Implement ISelfValidatingArgumentModel to provide validation errors for the model.

enabled by SelfValidatingArgumentsMiddleware

Console Enumerator

the ConsoleEnumerator provides the EnumerateOperation extension method to provide a consistent experience for

  • tracking count of processed and errored and elapsed time
  • estimated time remaining and estimated time complete
  • writing to failure files
  • responding to Ctrl+C cancellations by stopping the enumeration