├── .gitignore ├── README.md ├── another-docs └── decisions │ ├── 0001-use-slf4j-together-with-log4j2-for-logging.md │ ├── 0002-test-external-links-in-documentation.md │ └── 0003-implement-a-global-store.md ├── docs └── decisions │ ├── 0000-use-markdown-any-decision-records.md │ ├── 0001-use-vue.js.md │ ├── 0002-use-antlr-for-parsing-adrs.md │ ├── 0003-use-pizzly-as-backend.md │ └── 0004-invalid-madr.md └── images ├── add-webview.png ├── context-menu-file.png ├── context-menu-folder.png ├── main-webview.png └── workspace.png /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction to the VS Code Extension for the ADR Manager 2 | 3 | This repository serves as a short introduction to the features of the Visual Studio Code (VS Code) extension for the ADR Manager. For more information, please go to the [VS Code Marketplace page of the extension](https://marketplace.visualstudio.com/items?itemName=StevenChen.vscode-adr-manager). 4 | 5 | 6 |
7 | 8 | ## Prerequisites 9 | 10 | * Install [VS Code](https://code.visualstudio.com) 11 | * Install the [VS Code Extension for the ADR Manager](https://marketplace.visualstudio.com/items?itemName=StevenChen.vscode-adr-manager) 12 | * Download this repository to your local computer 13 | * Open the root folder of this repository in a VS Code instance. The folder `vscode-adr-manager-introduction` should be the only root folder in your current workspace. 14 | 15 | Your VS Code workspace should look something like this: 16 | 17 | VS Code workspace after opening repo folder 18 | 19 | Feel free to open your own directory to experiment with the extension! 20 | 21 |
22 | 23 | ## Features 24 | 25 | ### Commands 26 | 27 | ADR Manager provides several commands that can be accessed via the Command Palette (`Ctrl+Shift+P` on Windows/Linux, `Cmd+Shift+P` on macOS). Commands provided by this extension will be prefixed by `ADR Manager:`. 28 | 29 | ADR Manager currently provides the following commands: 30 | 31 | 32 | #### Open ADR Manager 33 | 34 |  35 | 36 | _Main webview of the ADR Manager._ 37 | 38 |
39 | 40 | When executing this command, the extension will open the main webview panel of the extension which lists every ADR in the ADR Directory it could find. From here, you may add and edit ADRs using the provided editor, or delete ADRs (i.e., move them to the trash can). If the user decides to edit an ADR, the extension will try to open another webview which shows the extension's ADR editor, prefilled with the data from that particular ADR. 41 | 42 | The user can configure his preferred editor modes for adding and viewing ADRs based on the grade of detail in VS Code's settings. 43 | 44 | ``` 45 | Try to open the main webview and experiment with adding, editing and deleting ADRs. 46 | See how these actions affect the file contents and the workspace! 47 | ``` 48 | 49 |
50 | 51 | #### Add New ADR 52 | 53 |  54 | 55 | _ADR editor provided by the ADR Manager._ 56 | 57 |
58 | 59 | When executing this command (or when clicking on the `Add ADR` button on the main webview), the extension will open a webview panel where the user can create a new ADR using the editor provided by the extension. The user may switch between editor modes to reveal or hide fields of the ADR based on the user's needs. 60 | 61 |
62 | 63 | #### Open ADR Manager on This File 64 | 65 | When executing this command, the extension will try to open the ADR editor and fill it with information according to the content of the Markdown file that is currently in the active text editor of VS Code. If the Markdown file does not conform to MADR, the extension will show an error message. 66 | 67 | This command works regardless of the location of the Markdown file, i.e., the Markdown file does not have to be located inside of the ADR Directory, although the extension will inform the user if that's the case (for consistency's sake). 68 | 69 | **Note**: This command will only show in the command palette if the currently opened Markdown file loosely follows the naming conventions of MADR. See the extension's page on the Marketplace for the exact criteria. 70 | 71 | ``` 72 | Try opening a valid MADR in 'docs/decisions' in the VS Code text editor and executing this command. 73 | Try the same with 'docs/decisions/0004-invalid-madr.md' and see what happens! 74 | ``` 75 | 76 |
77 | 78 | #### Change ADR Directory 79 | 80 | When executing this command, the extension will ask the user to type in a path to the new/preferred ADR Directory. This path must be a relative path relative to the root folder(s) of the workspace. 81 | 82 | **Example**: If the root folder of the workspace is 'vscode-adr-manager-introduction' and I enter 'path/to/my/adr-directory', the resulting ADR Directory will be located at 'vscode-adr-manager-introduction/path/to/my/adr-directory/'. 83 | 84 | The ADR Directory can also be changed in the settings. 85 | 86 | ``` 87 | Try opening the main webview of the ADR Manager. 88 | Then, change the ADR Directory from 'docs/decisions' to 'another-docs/decisions' and see what happens! 89 | ``` 90 | 91 |
92 | 93 | #### Initialize ADR Directory 94 | 95 | When executing this command, the extension will try to create the ADR Directory specified by the user. Additionally, the extension will fill the ADR Directory with some useful files to start using MADR. 96 | 97 | If the ADR Directory already exists in the workspace, the extension will notify the user. 98 | 99 | ``` 100 | Try changing the ADR Directory to a new directory not present in this repository and executing this command. 101 | Try executing the same command again immediately after and see what happens! 102 | ``` 103 | 104 |
105 | 106 | ### Menus 107 | 108 | ADR Manager provides entries in the context menu of specific files and folders in the VS Code file explorer (i.e., when right-clicking on specific files or folders). 109 | 110 | 111 | #### Open ADR Manager 112 | 113 |  114 | 115 | _Context menu of the ADR Directory._ 116 | 117 |
118 | 119 | When opening the context menu for the ADR Directory or any folder along the way to the ADR Directory, there will be a new entry `Open ADR Manager` at the bottom of the context menu. Upon clicking that entry, the extension will execute the command [Open ADR Manager](#open-adr-manager), showing the main webview of the extension. 120 | 121 | ``` 122 | While the ADR Directory is set to 'docs/decisions', try to right-click on either 'docs' or 'decisions' 123 | in the file explorer and look for the new entry. 124 | ``` 125 | 126 |
127 | 128 | #### Open ADR Manager on This File 129 | 130 |  131 | 132 | _Context menu of a MADR file._ 133 | 134 |
135 | 136 | When opening the context menu for a Markdown file that loosely follows the MADR naming conventions, there will be a new entry `Open ADR Manager on This File` at the bottom of the context menu. Upon clicking that entry, the extension will execute the command [Open ADR Manager on This File](#open-adr-manager-on-this-file) on the specified file. 137 | 138 | ``` 139 | Try to right-click any MADR in 'docs/decision' in the file explorer and look for the new entry. 140 | Try to right-click this 'README.md' file and see what happens! 141 | ``` 142 | 143 |
144 | 145 | ### Linting 146 | 147 | ADR Manager also provides some basic linting rules when editing a Markdown file that loosely follows the MADR naming conventions in the VS Code text editor. These linting rules may help the user to resolve issues with the extension not being able to parse an ADR in the ADR Directory. 148 | 149 | ``` 150 | The file 'docs/decisions/0004-invalid-madr.md' cannot be edited in the editor provided by the extension. 151 | Try to open the file in the VS Code text editor and try to fix all errors. 152 | Then try again to edit the file via the editor provided by the extension. 153 | ``` 154 | 155 |
156 | 157 | ### Snippets 158 | 159 | ADR Manager provides two snippets that help the user to create MADRs via the VS Code text editor. These snippets insert MADR templates into Markdown files such that the user only has to fill out the fields of the MADR. The user can use the `Tab` key to jump to the next field until all fields have been filled out. 160 | 161 | To insert a snippet, the user has to open a Markdown file and manually trigger IntelliSense (`Ctrl+Space`) and look for the keyword, or type in the keyword (or parts of it) to automatically trigger IntelliSense. 162 | 163 | #### Basic MADR Template 164 | 165 | This snippet inserts a MADR template at the cursor's current position that contains only the required fields of a MADR. The keyword for this snippet 'basic-madr'. 166 | 167 | #### Professional MADR Template 168 | 169 | This snippet inserts a MADR template at the cursor's position that contains all available fields of a MADR. 170 | The keyword for this snippet is 'professional-madr' 171 | 172 | ``` 173 | Create a new Markdown file anywhere in the workspace. 174 | Try to insert either of these snippets with IntelliSense. 175 | Try filling out the fields with 'tabbing' to the next field. 176 | ``` 177 | -------------------------------------------------------------------------------- /another-docs/decisions/0001-use-slf4j-together-with-log4j2-for-logging.md: -------------------------------------------------------------------------------- 1 | --- 2 | parent: Decision Records 3 | nav_order: 2 4 | --- 5 | # Use Slf4j Together with Log4j2 for Logging 6 | 7 | ## Context and Problem Statement 8 | 9 | Up to version 4.1 JabRef uses apache-commons-logging 1.2 for logging errors and messages. However, this is not compatible with java 9 and is superseded by log4j. 10 | 11 | ## Decision Drivers 12 | 13 | * SLF4J provides a façade for several logging frameworks, including log4j and supports already java 9 14 | * Log4j is already defined as dependency and slf4j has already been required by a third party dependency 15 | 16 | ## Considered Options 17 | 18 | * [Log4j2](https://logging.apache.org/log4j/2.x/) 19 | * [SLF4J with Log4j2 binding](https://logging.apache.org/log4j/2.x/maven-artifacts.html) 20 | * [SLF4J with Logback binding](https://logback.qos.ch/) 21 | * SLF4J with log4j2 binding 22 | 23 | ## Decision Outcome 24 | 25 | Chosen option: "SLF4J with Log4j2 binding", because comes out best \(see below\). 26 | 27 | ## Pros and Cons of the Options 28 | 29 | ### Log4j2 30 | 31 | * Good, because dependency already exists 32 | * Good, because Java 9 support since version 2.10 33 | * Bad, because direct dependency 34 | 35 | ### SLF4J with Logback binding 36 | 37 | * Good, because migration tool available 38 | * Good, because native implementation of slf4j 39 | * Bad, because Java 9 support only available in alpha 40 | * Bad, because different syntax than log4j/commons logging 41 | 42 | ### SLF4J with log4j2 binding 43 | 44 | * Good, because it only requires minimal changes to our logging infrastructure 45 | * Good, because Apache Log4j 2 is an upgrade to Log4j that provides significant improvements over its predecessor, Log4j 1.x, and provides many of the improvements available in Logback while fixing some inherent problems in Logback’s architecture. 46 | * Good, because supports other loggers as well 47 | * Good, because Java 9 support 48 | * Good, because already defined 49 | * Good, because migration tool available 50 | * Good, because it is a façade for several loggers. Thus, the underlying implementation can easily be changed in the future. 51 | * Bad, because logger statements require a slight different syntax 52 | -------------------------------------------------------------------------------- /another-docs/decisions/0002-test-external-links-in-documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | parent: Decision Records 3 | nav_order: 11 4 | --- 5 | # Test External Links in Documentation 6 | 7 | ## Context and Problem Statement 8 | 9 | The JabRef repository contains Markdown (`.md`) files documenting the JabRef code. 10 | The documentation contains links to external resources. 11 | For high-quality documentation, external links should be working. 12 | 13 | ## Decision Drivers 14 | 15 | * Checking external links should not cause issues in the normal workflow 16 | 17 | ## Considered Options 18 | 19 | * Check external links once a month 20 | * Check external links in the "checkstyle" task 21 | * Do not check external links 22 | 23 | ## Decision Outcome 24 | 25 | Chosen option: "Check external links once a month", because \[justification. e.g., only option, which meets k.o. criterion decision driver \| which resolves force force \| … \| comes out best \(see below\)\]. 26 | 27 | ### Positive Consequences 28 | 29 | * Automatic notification of broken external links 30 | 31 | ### Negative Consequences 32 | 33 | * Some external sites need to [be disabled](https://github.com/JabRef/jabref/pull/6542/files). For instance, GitHub.com always returns "forbidden". A [filter for status is future work of the used tool](https://github.com/tcort/markdown-link-check/issues/94#issuecomment-634947466). 34 | 35 | ## Pros and Cons of the Options 36 | 37 | ### Check external links once a month 38 | 39 | * Good, because does not interfere with the normal development workflow 40 | * Bad, because an additional workflow is required 41 | 42 | ### Check external links in the "checkstyle" task 43 | 44 | * Good, because no separate workflow is required 45 | * Bad, because checks fail independent of the PR (because external web sites can go down and go up independent of a PR) 46 | 47 | ### Do not check external links 48 | 49 | * Good, because no testing at all is required 50 | * Bad, because external links break without any notice 51 | * Bad, because external links have to be checked manually 52 | -------------------------------------------------------------------------------- /another-docs/decisions/0003-implement-a-global-store.md: -------------------------------------------------------------------------------- 1 | # Implement a Global Store 2 | 3 | * Status: Accepted 4 | 5 | Technical Story: Implement a simple global store 6 | 7 | ## Context and Problem Statement 8 | 9 | The ADR-Manager has a state that needs to be stored. 10 | Data that make sense storing globally: 11 | 12 | * Edited ADRs until they're committed (maybe even all ADRs from all added repositories) 13 | * Added Repositories 14 | * The current mode (basic, advanced, professional) 15 | 16 | How should the state be stored? 17 | 18 | ## Decision Drivers 19 | 20 | * ADR-Manager should be lightweight and easy to implement. 21 | * ADR-Manager should be easy to maintain. 22 | 23 | ## Considered Options 24 | 25 | * Don't use any global store 26 | * Only use local storage in combination with Events/Props 27 | * Use the Vue-State-Manager Vuex 28 | * Implement a state manager from scratch. 29 | 30 | ## Decision Outcome 31 | 32 | Chosen option: "Implement a state manager from scratch.", because comes out best. The data can additionally be stored in Local Storage but this should be managed by the global store as well. 33 | 34 | ### Positive Consequences 35 | 36 | * New functionality will be easier to add. 37 | 38 | ## Pros and Cons of the Options 39 | 40 | ### Don't use any global store 41 | 42 | Just "cascade" updates between Vue-Components via Events and Props. E.g. each editor tab has a prop (v-model) for the displayed ADR. Whenever the ADR is changed the Sup-Component (currently TheEditor.vue) updates the ADR in each tab. When a new ADR is created via a toolbar menu, the event needs to cascade down to each related Editor-Component. 43 | 44 | * Good, because it's easy to implement. 45 | * Bad, because it's hard to debug. 46 | * Bad, because GUI and functionality is more directly connected. Changes to the GUI often require bigger updates to functionality and vice versa. 47 | 48 | ### Only use local storage in combination with Events/Props 49 | 50 | Use local storage (i.e. persistent storage) to store the state and use events (e. g. a global event bus) to communicate changes to the state. 51 | 52 | * Good, because it's easy to implement. 53 | * Good, because most data should be stored in persistent storage anyway. 54 | * Bad, because cannot take advantage of Vue's reactivity. 55 | 56 | ### Use the Vue-State-Manager Vuex 57 | 58 | Docs can be found at https://vuex.vuejs.org/. 59 | 60 | * Good, because best long-term maintainability. 61 | * Good, because prepares for extensions like 'Undo-Redo'. 62 | * Good, because the development team can gather experience with Vuex. 63 | * Bad, because of more concepts and boilerplate. 64 | * Bad, because does not fit in our project. We assume that ADR-Manager is a small-to-medium project and not a medium-to-large project 65 | 66 | ### Implement a state manager from scratch. 67 | 68 | Implement a state manager from scratch as described at https://vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch. 69 | 70 | * Good, because GUI and functionality are split better. Debugging is easier. 71 | * Good, because it's a compromise between using Vuex and using no global state. -------------------------------------------------------------------------------- /docs/decisions/0000-use-markdown-any-decision-records.md: -------------------------------------------------------------------------------- 1 | # Use Markdown Any Decision Records 2 | 3 | ## Context and Problem Statement 4 | 5 | We want to record any decisions made in this project independent whether decisions concern the architecture ("architectural decision record"), the code, or other fields. 6 | Which format and structure should these records follow? 7 | 8 | ## Considered Options 9 | 10 | * [MADR](https://adr.github.io/madr/) 3.0.0 – The Markdown Any Decision Records 11 | * [Michael Nygard's template](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions) – The first incarnation of the term "ADR" 12 | * [Sustainable Architectural Decisions](https://www.infoq.com/articles/sustainable-architectural-design-decisions) – The Y-Statements 13 | * Other templates listed at 14 | * Formless – No conventions for file format and structure 15 | 16 | ## Decision Outcome 17 | 18 | Chosen option: "MADR 3.0.0", because 19 | 20 | * Implicit assumptions should be made explicit. 21 | Design documentation is important to enable people understanding the decisions later on. 22 | See also [A rational design process: How and why to fake it](https://doi.org/10.1109/TSE.1986.6312940). 23 | * MADR allows for structured capturing of any decision. 24 | * The MADR format is lean and fits our development style. 25 | * The MADR structure is comprehensible and facilitates usage & maintenance. 26 | * The MADR project is vivid. -------------------------------------------------------------------------------- /docs/decisions/0001-use-vue.js.md: -------------------------------------------------------------------------------- 1 | # Use Vue.js 2 | 3 | * Status: accepted 4 | * Date: 2022-08-05 5 | 6 | ## Context and Problem Statement 7 | 8 | A framework makes the creation of a web app significantly easier. Which framework should be used? 9 | 10 | ## Considered Options 11 | 12 | * Vue.js 13 | * Angular 14 | 15 | ## Decision Outcome 16 | 17 | Chosen option: "Vue.js", because the team has more experience with Vue.js. 18 | -------------------------------------------------------------------------------- /docs/decisions/0002-use-antlr-for-parsing-adrs.md: -------------------------------------------------------------------------------- 1 | # Use Antlr for Parsing ADRs 2 | 3 | * Status: accepted 4 | 5 | Technical Story: Proposed in the GitHub Issues [#17](https://github.com/koppor/adr-manager/issues/17), [#19](https://github.com/koppor/adr-manager/issues/19) 6 | 7 | ## Context and Problem Statement 8 | 9 | ADR Manager needs to parse existing ADRs. Each ADR is stored in a markdown file. Example: https://github.com/adr/madr/blob/master/docs/adr/0001-use-CC0-as-license.md. 10 | 11 | ## Considered Options 12 | 13 | * Use a generic Markdown Parser 14 | * Use ANTLR to create an ADR specific parser 15 | * Write a parser from scratch 16 | 17 | ## Decision Outcome 18 | 19 | Chosen option: "Use ANTLR to create an ADR specific parser", because comes out best (see below). 20 | 21 | ### Positive Consequences 22 | 23 | * Some existing ADRs are accepted now without changes. 24 | * Better control over output 25 | 26 | ### Negative Consequences 27 | 28 | * The new parser is worse at parsing "invalid" ADRs than the generic one. 29 | * ANTLR Parser seems to be quite slow. 30 | 31 | ## Pros and Cons of the Options 32 | 33 | ### Use a generic Markdown Parser 34 | 35 | Enhance generic Markdown parser and use the result of that parser. For that, available options are listed at https://github.com/f43i4n/md-schema/blob/master/docs/related-work.md. 36 | 37 | This option was used in the mock-up with the library [md-to-json](https://github.com/ajithr/md-2-json). 38 | 39 | * Good, because easiest solution. 40 | * Good, because md-to-json can parse the json back to a Markdown. 41 | * Bad, because md-to-json adds extra line breaks, which are hard to remove. 42 | 43 | ### Use ANTLR to create an ADR specific parser 44 | 45 | Use ANTLR4 to write a parser specifically for ADRs. 46 | 47 | * Good, because flexible parser and full control over output. 48 | * Good, because hopefully maintainable. ANTLR Grammar can be used to specify how ADRs must look. 49 | * Bad, because extra work. 50 | 51 | ### Write a parser from scratch 52 | 53 | * Bad, because extra work. 54 | * Bad, because writing stuff from scratch is a bad anti pattern. 55 | -------------------------------------------------------------------------------- /docs/decisions/0003-use-pizzly-as-backend.md: -------------------------------------------------------------------------------- 1 | # Use Pizzly as Backend 2 | 3 | * Status: Accepted 4 | 5 | ## Context and Problem Statement 6 | 7 | Should the ADR Manager have a backend? If so, how should it look? 8 | 9 | ## Considered Options 10 | 11 | * Use a Python back end 12 | * Don't use a back end 13 | * Use Pizzly as Backend 14 | 15 | ## Decision Outcome 16 | 17 | Chosen option: "Use Pizzly as Backend", because comes out best (see below). 18 | 19 | ## Pros and Cons of the Options 20 | 21 | ### Use a Python back end 22 | 23 | * Good, because GitHub interaction can be achieved. 24 | * Bad, because hard to maintain. 25 | 26 | ### Don't use a back end 27 | 28 | * Bad, because we can't authorize to GitHub without back end. 29 | 30 | ### Use Pizzly as Backend 31 | 32 | [Pizzly](https://github.com/Bearer/Pizzly/) can handle the OAuth dance for us. It can be hosted on Heroku as the back end. 33 | 34 | * Good, because less work than writing the back end from scratch. 35 | * Good, because we don't have to handle the authorization process. 36 | -------------------------------------------------------------------------------- /docs/decisions/0004-invalid-madr.md: -------------------------------------------------------------------------------- 1 | 2 | * Status: Proposed 3 | * Deciders: {everyone involved in this decision, e.g., separated by commas} 4 | * Date: YYYY-MM-DD 5 | 6 | Technical Story: {technical context of the ADR, e.g., a ticket or issue URL} 7 | 8 | ## Context and Problem Statement 9 | 10 | 11 | 12 | ## Decision Drivers 13 | 14 | * {decision driver 1, e.g., a force, facing concern, ...} 15 | * {decision driver 2, e.g., a force, facing concern, ...} 16 | * ... 17 | 18 | ## Considered options 19 | 20 | * Option 1 21 | * Option 2 22 | * Option 3 23 | 24 | ## Decision Outcome 25 | 26 | Chosen option: "Option not in 'Considered Options", because {justification, e.g., only option, which meets k.o. criterion decision driver | which resolves force {force} | … | comes out best} 27 | 28 | ### Positive Consequences 29 | 30 | * {e.g., improvement of one or more desired qualities, ...} 31 | * ... 32 | 33 | ### Negative Consequences 34 | 35 | * {e.g., compromising of one or more desired qualities, ...} 36 | * ... 37 | 38 | ## Pros and Cons of the Options 39 | 40 | ### Option 1 41 | 42 | {example | description | pointer to more information | ...} 43 | 44 | * Good, because {argument a} 45 | * Good, because {argument b} 46 | * Bad, because {argument x} 47 | * Bad, because {argument y} 48 | 49 | ### Option 2 50 | 51 | {example | description | pointer to more information | ...} 52 | 53 | * Good, because {argument a} 54 | * Good, because {argument b} 55 | * Bad, because {argument x} 56 | * Bad, because {argument y} 57 | 58 | ... 59 | 60 | ## Links 61 | 62 | * Link 1 63 | * Link 2 64 | -------------------------------------------------------------------------------- /images/add-webview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adr/vscode-adr-manager-introduction/4ab0bbac6b9f7203e5b10d06fdb651f92dac3bab/images/add-webview.png -------------------------------------------------------------------------------- /images/context-menu-file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adr/vscode-adr-manager-introduction/4ab0bbac6b9f7203e5b10d06fdb651f92dac3bab/images/context-menu-file.png -------------------------------------------------------------------------------- /images/context-menu-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adr/vscode-adr-manager-introduction/4ab0bbac6b9f7203e5b10d06fdb651f92dac3bab/images/context-menu-folder.png -------------------------------------------------------------------------------- /images/main-webview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adr/vscode-adr-manager-introduction/4ab0bbac6b9f7203e5b10d06fdb651f92dac3bab/images/main-webview.png -------------------------------------------------------------------------------- /images/workspace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adr/vscode-adr-manager-introduction/4ab0bbac6b9f7203e5b10d06fdb651f92dac3bab/images/workspace.png --------------------------------------------------------------------------------