way_of_working 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -1
  3. data/CONTRIBUTING.md +62 -0
  4. data/README.md +186 -13
  5. data/lib/way_of_working/audit/github/auditor.rb +44 -0
  6. data/lib/way_of_working/audit/github/generators/exec.rb +163 -0
  7. data/lib/way_of_working/audit/github/rules/base.rb +91 -0
  8. data/lib/way_of_working/audit/github/rules/registry.rb +36 -0
  9. data/lib/way_of_working/audit/github/rules/unknown.rb +19 -0
  10. data/lib/way_of_working/audit/github.rb +25 -0
  11. data/lib/way_of_working/changelog/keepachangelog/generators/init.rb +118 -0
  12. data/lib/way_of_working/changelog/keepachangelog/github_audit_rule.rb +32 -0
  13. data/lib/way_of_working/changelog/keepachangelog/templates/docs/way_of_working/changelog.md +73 -0
  14. data/lib/way_of_working/changelog/keepachangelog.rb +35 -0
  15. data/lib/way_of_working/code_of_conduct/contributor_covenant/generators/init.rb +39 -0
  16. data/lib/way_of_working/code_of_conduct/contributor_covenant/github_audit_rule.rb +32 -0
  17. data/lib/way_of_working/code_of_conduct/contributor_covenant/templates/CODE_OF_CONDUCT.md.tt +133 -0
  18. data/lib/way_of_working/code_of_conduct/contributor_covenant/templates/docs/way_of_working/code-of-conduct.md +78 -0
  19. data/lib/way_of_working/code_of_conduct/contributor_covenant.rb +36 -0
  20. data/lib/way_of_working/decision_record/madr/generators/init.rb +41 -0
  21. data/lib/way_of_working/decision_record/madr/generators/new.rb +69 -0
  22. data/lib/way_of_working/decision_record/madr/github_audit_rule.rb +50 -0
  23. data/lib/way_of_working/decision_record/madr/templates/.github/ISSUE_TEMPLATE/decision-record.md +26 -0
  24. data/lib/way_of_working/decision_record/madr/templates/docs/decisions/0000-use-markdown-any-decision-records.md +30 -0
  25. data/lib/way_of_working/decision_record/madr/templates/docs/decisions/README.md +7 -0
  26. data/lib/way_of_working/decision_record/madr/templates/docs/decisions/adr-template.md.tt +82 -0
  27. data/lib/way_of_working/decision_record/madr/templates/docs/decisions/index.md +48 -0
  28. data/lib/way_of_working/decision_record/madr/templates/docs/way_of_working/decision-records.md +195 -0
  29. data/lib/way_of_working/decision_record/madr.rb +53 -0
  30. data/lib/way_of_working/git/repo_reader.rb +2 -2
  31. data/lib/way_of_working/inclusive_language/alex/generators/exec.rb +51 -0
  32. data/lib/way_of_working/inclusive_language/alex/generators/init.rb +34 -0
  33. data/lib/way_of_working/inclusive_language/alex/github_audit_rule.rb +35 -0
  34. data/lib/way_of_working/inclusive_language/alex/templates/.alexignore +2 -0
  35. data/lib/way_of_working/inclusive_language/alex/templates/.alexrc +3 -0
  36. data/lib/way_of_working/inclusive_language/alex/templates/.github/workflows/inclusive-language.yml +16 -0
  37. data/lib/way_of_working/inclusive_language/alex/templates/docs/way_of_working/inclusive-language.md +28 -0
  38. data/lib/way_of_working/inclusive_language/alex.rb +48 -0
  39. data/lib/way_of_working/pull_request_template/hdi/generators/init.rb +26 -0
  40. data/lib/way_of_working/pull_request_template/hdi/github_audit_rule.rb +32 -0
  41. data/lib/way_of_working/pull_request_template/hdi/templates/.github/pull_request_template.md +51 -0
  42. data/lib/way_of_working/pull_request_template/hdi/templates/docs/way_of_working/pull-request-template-and-guidelines.md +50 -0
  43. data/lib/way_of_working/pull_request_template/hdi.rb +35 -0
  44. data/lib/way_of_working/readme_badge/paths.rb +5 -2
  45. data/lib/way_of_working/version.rb +1 -1
  46. data/lib/way_of_working/versioning/semver/generators/init.rb +20 -0
  47. data/lib/way_of_working/versioning/semver/github_audit_rule.rb +49 -0
  48. data/lib/way_of_working/versioning/semver/templates/docs/way_of_working/versioning.md +71 -0
  49. data/lib/way_of_working/versioning/semver.rb +35 -0
  50. data/lib/way_of_working.rb +15 -0
  51. data/way_of_working.gemspec +3 -0
  52. metadata +88 -3
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+
5
+ module WayOfWorking
6
+ module DecisionRecord
7
+ module Madr
8
+ module Generators
9
+ # This generator add a new MADR decision record to the doc/decisions folder
10
+ class New < Thor::Group
11
+ argument :name, type: :string, required: true, desc: 'The title of the decision record'
12
+
13
+ include Thor::Actions
14
+
15
+ source_root WayOfWorking.root.join('lib', 'way_of_working', 'decision_record', 'madr', 'templates')
16
+
17
+ def create_decision_record_file
18
+ case behavior
19
+ when :invoke
20
+ invoke_decision_record_file
21
+ when :revoke
22
+ revoke_decision_record_file
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def invoke_decision_record_file
29
+ @decision_date = Date.today.strftime('%Y-%m-%d')
30
+ @index = next_decision_number.to_i
31
+ @title = name
32
+
33
+ # from https://raw.githubusercontent.com/adr/madr/3.0.0/template/adr-template.md
34
+ template 'docs/decisions/adr-template.md',
35
+ "docs/decisions/#{next_decision_number}-#{dashed_name}.md"
36
+ end
37
+
38
+ def revoke_decision_record_file
39
+ matching_files = Dir.glob("[0-9][0-9][0-9][0-9]-#{dashed_name}.md",
40
+ base: File.join(destination_root, 'docs/decisions'))
41
+ raise "No matching decision record for '#{dashed_name}'" if matching_files.empty?
42
+
43
+ # based on Thor's remove_file
44
+ path = File.expand_path("docs/decisions/#{matching_files.first}", destination_root)
45
+
46
+ say_status :remove, relative_to_original_destination_root(path)
47
+ return unless !options[:pretend] && (File.exist?(path) || File.symlink?(path))
48
+
49
+ require 'fileutils'
50
+ ::FileUtils.rm_rf(path)
51
+ end
52
+
53
+ def next_decision_number
54
+ existing_decisions = Dir.glob('[0-9][0-9][0-9][0-9]-*.md',
55
+ base: File.join(destination_root, 'docs/decisions'))
56
+ last_number = existing_decisions.map do |filename|
57
+ filename.match(/\A(\d{4})-/)[1].to_i
58
+ end.max || -1
59
+ format('%04d', last_number + 1)
60
+ end
61
+
62
+ def dashed_name
63
+ name.downcase.gsub(/[\s_()]/, '-').gsub(/-+/, '-')
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'way_of_working/audit/github/rules/base'
4
+
5
+ module WayOfWorking
6
+ module DecisionRecord
7
+ # The namespace for plugin
8
+ module Madr
9
+ # This rule checks for the MADR Decision Record template.
10
+ class GithubAuditRule < ::WayOfWorking::Audit::Github::Rules::Base
11
+ ADR_TEMPLATE_PATH = 'docs/decisions/adr-template.md'
12
+ DECISION_ZERO_PATH = 'docs/decisions/0000-use-markdown-any-decision-records.md'
13
+ WOW_DOCUMENTATION_PATH = 'docs/way_of_working/decision-records.md'
14
+
15
+ source_root WayOfWorking.root.join('lib', 'way_of_working', 'decision_record', 'madr', 'templates')
16
+
17
+ def validate
18
+ @errors << 'No MADR Decision Record template found' unless repo_file_contains?(
19
+ ADR_TEMPLATE_PATH, '## Context and Problem Statement'
20
+ )
21
+
22
+ unless repo_file_contains_source_file?(WOW_DOCUMENTATION_PATH)
23
+ @errors << 'Stale or missing documentation for using MADR Decision Records'
24
+ end
25
+
26
+ return if repo_file_contains_source_file?(DECISION_ZERO_PATH)
27
+
28
+ @errors << 'No 0000-use-markdown-any-decision-records.md Decision Record found'
29
+ end
30
+
31
+ private
32
+
33
+ def repo_file_contains_source_file?(path)
34
+ repo_file_contains?(path, File.read(self.class.source_root.join(path)))
35
+ end
36
+
37
+ def repo_file_contains?(path, text)
38
+ remote_content = repo_file_contents(path)
39
+ return false if remote_content.nil?
40
+
41
+ remote_content.include?(text)
42
+ end
43
+ end
44
+
45
+ ::WayOfWorking::Audit::Github::Rules::Registry.register(
46
+ GithubAuditRule, 'MADR Decision Records'
47
+ )
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,26 @@
1
+ ---
2
+ name: Decision Record
3
+ about: Create a ticket to discuss or propose a new decision record
4
+ title: ''
5
+ labels: decision record
6
+ assignees: ''
7
+
8
+ ---
9
+ ## Context and Problem Statement
10
+
11
+ {Describe the context and problem statement, e.g., in free form using two to three sentences or in the form of an illustrative story.
12
+ You may want to articulate the problem in form of a question and add links to collaboration boards or issue management systems.}
13
+
14
+ <!-- This is an optional element. Feel free to remove. -->
15
+ ## Decision Drivers
16
+
17
+ * {decision driver 1, e.g., a force, facing concern, …}
18
+ * {decision driver 2, e.g., a force, facing concern, …}
19
+ * … <!-- numbers of drivers can vary -->
20
+
21
+ ## Considered Options
22
+
23
+ * {title of option 1}
24
+ * {title of option 2}
25
+ * {title of option 3}
26
+ * … <!-- numbers of options can vary -->
@@ -0,0 +1,30 @@
1
+ ---
2
+ nav_order: 0
3
+ parent: Decision Records
4
+ ---
5
+ # Use Markdown Any Decision Records
6
+
7
+ ## Context and Problem Statement
8
+
9
+ We want to record any decisions made in this project independent whether decisions concern the architecture ("architectural decision record"), the code, or other fields.
10
+ Which format and structure should these records follow?
11
+
12
+ ## Considered Options
13
+
14
+ * [MADR](https://adr.github.io/madr/) 3.0.0 – The Markdown Any Decision Records
15
+ * [Michael Nygard's template](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions) – The first incarnation of the term "ADR"
16
+ * [Sustainable Architectural Decisions](https://www.infoq.com/articles/sustainable-architectural-design-decisions) – The Y-Statements
17
+ * Other templates listed at <https://github.com/joelparkerhenderson/architecture_decision_record>
18
+ * Formless – No conventions for file format and structure
19
+
20
+ ## Decision Outcome
21
+
22
+ Chosen option: "MADR 3.0.0", because
23
+
24
+ * Implicit assumptions should be made explicit.
25
+ Design documentation is important to enable people understanding the decisions later on.
26
+ See also [A rational design process: How and why to fake it](https://doi.org/10.1109/TSE.1986.6312940).
27
+ * MADR allows for structured capturing of any decision.
28
+ * The MADR format is lean and fits our development style.
29
+ * The MADR structure is comprehensible and facilitates usage & maintenance.
30
+ * The MADR project is vivid.
@@ -0,0 +1,7 @@
1
+ # Decisions
2
+
3
+ This directory contains decision records for the project.
4
+
5
+ For new ADRs, please use [adr-template.md](adr-template.md) as basis.
6
+ More information on MADR is available at <https://adr.github.io/madr/>.
7
+ General information about architectural decision records is available at <https://adr.github.io/>.
@@ -0,0 +1,82 @@
1
+ ---
2
+ nav_order: <%= @index %>
3
+ parent: Decision Records
4
+
5
+ # These are optional elements. Feel free to remove any of them.
6
+ status: {proposed | rejected | accepted | deprecated | … | superseded by ADR-0005 <0005-example.md>}
7
+ date: <%= @decision_date %>
8
+ deciders: {list everyone involved in the decision}
9
+ consulted: {list everyone whose opinions are sought (typically subject-matter experts); and with whom there is a two-way communication}
10
+ informed: {list everyone who is kept up-to-date on progress; and with whom there is a one-way communication}
11
+ ---
12
+ # <%= @title %>
13
+
14
+ ## Context and Problem Statement
15
+
16
+ {Describe the context and problem statement, e.g., in free form using two to three sentences or in the form of an illustrative story.
17
+ You may want to articulate the problem in form of a question and add links to collaboration boards or issue management systems.}
18
+
19
+ <!-- This is an optional element. Feel free to remove. -->
20
+ ## Decision Drivers
21
+
22
+ * {decision driver 1, e.g., a force, facing concern, …}
23
+ * {decision driver 2, e.g., a force, facing concern, …}
24
+ * … <!-- numbers of drivers can vary -->
25
+
26
+ ## Considered Options
27
+
28
+ * {title of option 1}
29
+ * {title of option 2}
30
+ * {title of option 3}
31
+ * … <!-- numbers of options can vary -->
32
+
33
+ ## Decision Outcome
34
+
35
+ Chosen option: "{title of option 1}", because
36
+ {justification. e.g., only option, which meets k.o. criterion decision driver | which resolves force {force} | … | comes out best (see below)}.
37
+
38
+ <!-- This is an optional element. Feel free to remove. -->
39
+ ### Consequences
40
+
41
+ * Good, because {positive consequence, e.g., improvement of one or more desired qualities, …}
42
+ * Bad, because {negative consequence, e.g., compromising one or more desired qualities, …}
43
+ * … <!-- numbers of consequences can vary -->
44
+
45
+ <!-- This is an optional element. Feel free to remove. -->
46
+ ## Validation
47
+
48
+ {describe how the implementation of/compliance with the ADR is validated. E.g., by a review or an ArchUnit test}
49
+
50
+ <!-- This is an optional element. Feel free to remove. -->
51
+ ## Pros and Cons of the Options
52
+
53
+ ### {title of option 1}
54
+
55
+ <!-- This is an optional element. Feel free to remove. -->
56
+ {example | description | pointer to more information | …}
57
+
58
+ * Good, because {argument a}
59
+ * Good, because {argument b}
60
+ <!-- use "neutral" if the given argument weights neither for good nor bad -->
61
+ * Neutral, because {argument c}
62
+ * Bad, because {argument d}
63
+ * … <!-- numbers of pros and cons can vary -->
64
+
65
+ ### {title of other option}
66
+
67
+ {example | description | pointer to more information | …}
68
+
69
+ * Good, because {argument a}
70
+ * Good, because {argument b}
71
+ * Neutral, because {argument c}
72
+ * Bad, because {argument d}
73
+ * …
74
+
75
+ <!-- This is an optional element. Feel free to remove. -->
76
+ ## More Information
77
+
78
+ {You might want to provide additional evidence/confidence for the decision outcome here and/or
79
+ document the team agreement on the decision and/or
80
+ define when and how this decision should be realized and if/when it should be re-visited and/or
81
+ how the decision is validated.
82
+ Links to other decisions and resources might appear here as well.}
@@ -0,0 +1,48 @@
1
+ ---
2
+ has_children: true
3
+ ---
4
+ # Decision Records
5
+
6
+ We use [Markdown Any Decision Records (MADR)](https://adr.github.io/madr/) version 3.0.0.
7
+
8
+ In general, projects will follow the organisation's way of working and so decisions captured within individual projects will generally cover decisions that:
9
+
10
+ - are not already covered in the Way of Working
11
+ - are covered in the Way of Working, but have specific implementation details which need to be captured
12
+ - diverge from the guidance in the Way of Working
13
+
14
+ ## Create a new decision record
15
+
16
+ ### Manual approach
17
+
18
+ 1. Copy `docs/decisions/adr-template.md` to `docs/decisions/NNNN-title-with-dashes.md`, where `NNNN` indicates the next number in sequence.
19
+ 2. Edit `NNNN-title-with-dashes.md`.
20
+
21
+ Note you can also use [other patterns for the directory format](https://github.com/joelparkerhenderson/architecture_decision_record#adr-file-name-conventions).
22
+ As a consequence, some existing tooling might not be applicable.
23
+
24
+ The filenames are following the pattern `NNNN-title-with-dashes.md`, where
25
+
26
+ - `NNNN` is a consecutive number and we assume that there won't be more than 9,999 ADRs in one repository.
27
+ - the title is stored using dashes and lowercase, because [adr-tools] also does that.
28
+ - the suffix is `.md`, because it is a [Markdown](https://github.github.com/gfm/) file.
29
+
30
+ Decisions are placed in the subfolder `decisions/` to keep them close to the documentation but also separate the decisions from other documentation.
31
+
32
+ ### Automatic approach
33
+
34
+ To create a new decision record, run:
35
+
36
+ ```bash
37
+ way_of_working new decision_record [NAME]
38
+ ```
39
+
40
+ Where `[NAME]` is the title of your decision record, for example:
41
+
42
+ ```bash
43
+ way_of_working new decision_record "Use Markdown Any Decision Records"
44
+ ```
45
+
46
+ ## Project decision records
47
+
48
+ Decision records for this project are listed below.
@@ -0,0 +1,195 @@
1
+ ---
2
+ layout: page
3
+ status: REQUIRED
4
+ enforcement: manual
5
+ ---
6
+ # Decision Records
7
+
8
+ ## Purpose
9
+
10
+ We use [Markdown Any Decision Records (MADR)][madr] v3.0.0 to capture project decisions that:
11
+
12
+ - aren't covered in the [Way of Working][wow]
13
+ - need project-specific implementation details
14
+ - diverge from Way of Working guidance
15
+
16
+ {: .note }
17
+ Proposing and reviewing decisions requires familiarity with [GitHub pull requests][gh-pr].
18
+
19
+ ## Scope
20
+
21
+ Applies to decisions about:
22
+
23
+ - **Architecture**: System design, technology stack, frameworks
24
+ - **Process**: Development workflows, deployment, testing
25
+ - **Code standards**: Patterns, conventions, library usage
26
+ - **Dependencies**: Adding/removing major libraries or services
27
+ - **Data**: Schema changes, migration strategies
28
+
29
+ **Create ADR when:**
30
+
31
+ - Impact spans multiple components or teams
32
+ - Long-term consequences or significant cost/risk
33
+ - Multiple viable alternatives exist
34
+
35
+ **Don't create ADR for:**
36
+
37
+ - Already covered by Way of Working
38
+ - Tactical implementation details (use code comments)
39
+ - Temporary workarounds or clear-cut choices
40
+
41
+ ## Requirements
42
+
43
+ **File naming:** `NNNN-title-with-dashes.md`
44
+
45
+ - `NNNN` = consecutive four-digit number (0001, 0002, etc.)
46
+ - Lowercase title with dashes
47
+ - Located in `docs/decisions/`
48
+
49
+ **Required content:**
50
+
51
+ 1. Status (proposed, accepted, rejected, deprecated, superseded)
52
+ 2. Context and problem statement
53
+ 3. Considered options (minimum 2)
54
+ 4. Decision outcome with justification
55
+ 5. Positive and negative consequences
56
+
57
+ **Status lifecycle:**
58
+
59
+ - **proposed** - Under discussion
60
+ - **accepted** - Approved for implementation
61
+ - **rejected** - Decided against
62
+ - **deprecated** - No longer relevant
63
+ - **superseded** - Replaced by newer ADR (link required)
64
+
65
+ ## Setup
66
+
67
+ ```bash
68
+ way_of_working init decision_record
69
+ ```
70
+
71
+ ## Usage
72
+
73
+ ### Create a new decision record
74
+
75
+ ```bash
76
+ way_of_working new decision_record "Use Markdown Any Decision Records"
77
+ ```
78
+
79
+ **Propose decision:**
80
+
81
+ 1. Create ADR with status "proposed"
82
+ 2. Open PR, tag stakeholders
83
+ 3. Discuss in PR comments
84
+ 4. Update to "accepted" once consensus reached
85
+ 5. Merge PR
86
+
87
+ **Supersede existing ADR:**
88
+
89
+ 1. Create new ADR
90
+ 2. Update old ADR status to "superseded by [0XXX-new-title.md](0XXX-new-title.md)"
91
+ 3. Explain what changed in new ADR
92
+
93
+ ## Enforcement
94
+
95
+ **PR Review:**
96
+
97
+ - All ADRs submitted via PR
98
+ - Maintainer approval required
99
+ - Verify MADR template structure, file naming, location
100
+ - Check minimum 2 options with justification
101
+
102
+ **Quality checklist:**
103
+
104
+ - ✅ Multiple alternatives with pros/cons
105
+ - ✅ Clear context and constraints
106
+ - ✅ Explicit trade-offs
107
+ - ❌ Only one option presented
108
+ - ❌ Missing justification or context
109
+
110
+ **Maintenance:**
111
+
112
+ - Quarterly review for relevance
113
+ - Update deprecated/superseded status as needed
114
+
115
+ ## Examples
116
+
117
+ **Database choice:**
118
+
119
+ ```markdown
120
+ # Use PostgreSQL for Primary Database
121
+
122
+ **Status:** accepted
123
+ **Date:** 2025-10-15
124
+
125
+ ## Context and Problem Statement
126
+
127
+ Need relational database for user data with complex relationships.
128
+ Constraints: ACID compliance, 100K users/1M records, prefer open-source.
129
+
130
+ ## Considered Options
131
+
132
+ 1. PostgreSQL (self-hosted)
133
+ 2. MySQL
134
+ 3. RDS PostgreSQL
135
+
136
+ ## Decision Outcome
137
+
138
+ **Chosen:** PostgreSQL (self-hosted)
139
+
140
+ **Pros:** Open-source, advanced features (JSON, full-text search), ACID, team experience
141
+ **Cons:** DevOps overhead, manual backup, manual scaling
142
+
143
+ **Why:** Meets requirements within budget. Cloud-managed exceeds budget by 40%.
144
+ Team expertise mitigates complexity.
145
+
146
+ **Alternatives rejected:**
147
+ - MySQL: No advantage over PostgreSQL
148
+ - RDS: Cost $200-500/month exceeds budget
149
+ ```
150
+
151
+ **Superseded ADR:**
152
+
153
+ ```markdown
154
+ # Use Jest for Frontend Testing
155
+
156
+ **Status:** superseded by [0015-use-vitest.md](0015-use-vitest.md)
157
+ **Date:** 2025-01-10 (original), 2025-09-15 (superseded)
158
+
159
+ **Why superseded:** Vitest now standard for Vite projects,
160
+ better integration and performance.
161
+ ```
162
+
163
+ **Rejected decision:**
164
+
165
+ ```markdown
166
+ # Use GraphQL for API Layer
167
+
168
+ **Status:** rejected
169
+ **Date:** 2025-03-20
170
+
171
+ ## Decision Outcome
172
+
173
+ **Chosen:** Continue with REST API
174
+
175
+ **Why rejected:**
176
+ - Current REST meets all requirements
177
+ - Team lacks GraphQL expertise (4-6 week learning curve)
178
+ - Migration cost: 8 engineer-weeks
179
+ - No client needs GraphQL features
180
+
181
+ **Reconsider when:** Multiple clients need flexible fetching
182
+ or over-fetching impacts performance.
183
+ ```
184
+
185
+ ## Resources
186
+
187
+ - [MADR Documentation][madr]
188
+ - [GDS Architecture Decisions][gds-way]
189
+ - [Way of Working CLI][wow-cli]
190
+
191
+ [madr]: https://adr.github.io/madr/
192
+ [wow]: https://github.com/HealthDataInsight/way_of_working
193
+ [gds-way]: https://gds-way.digital.cabinet-office.gov.uk/standards/architecture-decisions.html
194
+ [gh-pr]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests
195
+ [wow-cli]: ../cli.md
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'madr/generators/init'
4
+ require_relative 'madr/generators/new'
5
+
6
+ # If way_of_working-audit-github is used we can add a rule
7
+ begin
8
+ require 'way_of_working/audit/github/rules/registry'
9
+ require_relative 'madr/github_audit_rule'
10
+ rescue LoadError # rubocop:disable Lint/SuppressedException
11
+ end
12
+
13
+ module WayOfWorking
14
+ module DecisionRecord
15
+ module Madr
16
+ class Error < StandardError; end
17
+ end
18
+ end
19
+
20
+ module SubCommands
21
+ # This reopens the "way_of_working init" sub command
22
+ class Init
23
+ register(DecisionRecord::Madr::Generators::Init, 'decision_record', 'decision_record',
24
+ <<~LONGDESC)
25
+ Description:
26
+ This generator adds Markdown Any Decision Records (MADR) to your project
27
+
28
+ Example:
29
+ way_of_working init decision_record
30
+
31
+ This will create:
32
+ docs/decisions/README.md
33
+ docs/decisions/adr-template.md
34
+ docs/decisions/0000-use-markdown-any-decision-records.md
35
+ LONGDESC
36
+ end
37
+
38
+ # This reopens the "way_of_working new" sub command
39
+ class New
40
+ register(DecisionRecord::Madr::Generators::New, 'decision_record', 'decision_record [NAME]',
41
+ <<~LONGDESC)
42
+ Description:
43
+ This generator adds a new decision record to your project
44
+
45
+ Example:
46
+ way_of_working new decision_record "Title of the decision"
47
+
48
+ This will create:
49
+ docs/decisions/NNNN-title-of-the-decision.md
50
+ LONGDESC
51
+ end
52
+ end
53
+ end
@@ -58,10 +58,10 @@ module WayOfWorking
58
58
 
59
59
  def likely_upstream_remote
60
60
  remotes = @base.remotes
61
- return remotes.first if remotes.count == 1
61
+ return remotes.first if remotes.one?
62
62
 
63
63
  remotes = remotes.reject { |remote| remote.name == 'origin' }
64
- return remotes.first if remotes.count == 1
64
+ return remotes.first if remotes.one?
65
65
 
66
66
  remotes.last
67
67
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor'
4
+ require 'rainbow'
5
+
6
+ module WayOfWorking
7
+ module InclusiveLanguage
8
+ module Alex
9
+ module Generators
10
+ # This generator runs the inclusive language tests
11
+ class Exec < Thor::Group
12
+ argument :path, type: :string, required: false, desc: 'Optional path of the file to test'
13
+
14
+ desc 'This runs the inclusive language tests on this project'
15
+
16
+ def run_first
17
+ @start_time = Time.now
18
+
19
+ say(Rainbow("Limiting tests to #{path}\n").yellow) if path
20
+ end
21
+
22
+ def prep_and_run_alex
23
+ command = ['npx', 'alex', '--why']
24
+ # Configure alex to only test a specific file or folder, if defined
25
+ command << path if path
26
+
27
+ say(Rainbow("\nRunning alex...").yellow)
28
+
29
+ @alex_ok = run_alex(command)
30
+ end
31
+
32
+ def run_last
33
+ say(Rainbow("\nTotal time taken: #{(Time.now - @start_time).to_i} seconds").yellow)
34
+
35
+ if @alex_ok
36
+ say(Rainbow("\nInclusive language tests succeeded!").green)
37
+ else
38
+ abort(Rainbow("\nInclusive language tests failed!").red)
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def run_alex(arguments)
45
+ system(*arguments)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor'
4
+
5
+ module WayOfWorking
6
+ module InclusiveLanguage
7
+ module Alex
8
+ module Generators
9
+ # This generator adds the alexrc file
10
+ class Init < Thor::Group
11
+ include Thor::Actions
12
+
13
+ source_root WayOfWorking.root.join('lib', 'way_of_working', 'inclusive_language', 'alex', 'templates')
14
+
15
+ def copy_inclusive_language_github_workflow_action
16
+ copy_file '.github/workflows/inclusive-language.yml'
17
+ end
18
+
19
+ def copy_alexignore_file
20
+ copy_file '.alexignore'
21
+ end
22
+
23
+ def copy_alexrc_file
24
+ copy_file '.alexrc'
25
+ end
26
+
27
+ def copy_way_of_working_documentation
28
+ copy_file 'docs/way_of_working/inclusive-language.md'
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end