spreen-wiki 0.1.0 → 0.2.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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -7
  3. data/exe/spreen +2 -2
  4. data/lib/spreen-wiki.rb +2 -2
  5. data/lib/spreen_wiki/application.rb +149 -0
  6. data/lib/spreen_wiki/cli.rb +157 -0
  7. data/lib/spreen_wiki/configuration.rb +215 -0
  8. data/lib/spreen_wiki/home.rb +100 -0
  9. data/lib/spreen_wiki/sidebar.rb +48 -0
  10. data/lib/spreen_wiki/unknown_wiki_count_list_exporter.rb +59 -0
  11. data/lib/spreen_wiki/unknown_wiki_list_exporter_for_llm.rb +51 -0
  12. data/lib/{spreen/wiki → spreen_wiki}/version.rb +2 -4
  13. data/lib/spreen_wiki.rb +18 -0
  14. data/sig/generated/spreen_wiki/application.rbs +91 -0
  15. data/sig/generated/spreen_wiki/cli.rbs +68 -0
  16. data/sig/generated/spreen_wiki/configuration.rbs +148 -0
  17. data/sig/generated/spreen_wiki/home.rbs +52 -0
  18. data/sig/generated/spreen_wiki/sidebar.rbs +29 -0
  19. data/sig/generated/spreen_wiki/unknown_wiki_count_list_exporter.rbs +38 -0
  20. data/sig/generated/spreen_wiki/unknown_wiki_list_exporter_for_llm.rbs +35 -0
  21. data/sig/generated/spreen_wiki/version.rbs +5 -0
  22. data/sig/generated/spreen_wiki.rbs +8 -0
  23. metadata +23 -23
  24. data/lib/spreen/wiki/application.rb +0 -151
  25. data/lib/spreen/wiki/cli.rb +0 -159
  26. data/lib/spreen/wiki/configuration.rb +0 -217
  27. data/lib/spreen/wiki/home.rb +0 -102
  28. data/lib/spreen/wiki/sidebar.rb +0 -50
  29. data/lib/spreen/wiki/unknown_wiki_count_list_exporter.rb +0 -61
  30. data/lib/spreen/wiki/unknown_wiki_list_exporter_for_llm.rb +0 -53
  31. data/lib/spreen/wiki.rb +0 -20
  32. data/sig/generated/spreen/wiki/application.rbs +0 -93
  33. data/sig/generated/spreen/wiki/cli.rbs +0 -70
  34. data/sig/generated/spreen/wiki/configuration.rbs +0 -150
  35. data/sig/generated/spreen/wiki/home.rbs +0 -54
  36. data/sig/generated/spreen/wiki/sidebar.rbs +0 -31
  37. data/sig/generated/spreen/wiki/unknown_wiki_count_list_exporter.rbs +0 -40
  38. data/sig/generated/spreen/wiki/unknown_wiki_list_exporter_for_llm.rbs +0 -37
  39. data/sig/generated/spreen/wiki/version.rbs +0 -7
  40. data/sig/generated/spreen/wiki.rbs +0 -10
  41. /data/lib/{spreen/wiki → spreen_wiki}/templates/category/english.md +0 -0
  42. /data/lib/{spreen/wiki → spreen_wiki}/templates/category/japanese.md +0 -0
  43. /data/lib/{spreen/wiki → spreen_wiki}/templates/owner/english.md +0 -0
  44. /data/lib/{spreen/wiki → spreen_wiki}/templates/owner/japanese.md +0 -0
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spreen-wiki
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - hayat01sh1da
@@ -22,29 +22,29 @@ files:
22
22
  - README.md
23
23
  - exe/spreen
24
24
  - lib/spreen-wiki.rb
25
- - lib/spreen/wiki.rb
26
- - lib/spreen/wiki/application.rb
27
- - lib/spreen/wiki/cli.rb
28
- - lib/spreen/wiki/configuration.rb
29
- - lib/spreen/wiki/home.rb
30
- - lib/spreen/wiki/sidebar.rb
31
- - lib/spreen/wiki/templates/category/english.md
32
- - lib/spreen/wiki/templates/category/japanese.md
33
- - lib/spreen/wiki/templates/owner/english.md
34
- - lib/spreen/wiki/templates/owner/japanese.md
35
- - lib/spreen/wiki/unknown_wiki_count_list_exporter.rb
36
- - lib/spreen/wiki/unknown_wiki_list_exporter_for_llm.rb
37
- - lib/spreen/wiki/version.rb
25
+ - lib/spreen_wiki.rb
26
+ - lib/spreen_wiki/application.rb
27
+ - lib/spreen_wiki/cli.rb
28
+ - lib/spreen_wiki/configuration.rb
29
+ - lib/spreen_wiki/home.rb
30
+ - lib/spreen_wiki/sidebar.rb
31
+ - lib/spreen_wiki/templates/category/english.md
32
+ - lib/spreen_wiki/templates/category/japanese.md
33
+ - lib/spreen_wiki/templates/owner/english.md
34
+ - lib/spreen_wiki/templates/owner/japanese.md
35
+ - lib/spreen_wiki/unknown_wiki_count_list_exporter.rb
36
+ - lib/spreen_wiki/unknown_wiki_list_exporter_for_llm.rb
37
+ - lib/spreen_wiki/version.rb
38
38
  - sig/generated/spreen-wiki.rbs
39
- - sig/generated/spreen/wiki.rbs
40
- - sig/generated/spreen/wiki/application.rbs
41
- - sig/generated/spreen/wiki/cli.rbs
42
- - sig/generated/spreen/wiki/configuration.rbs
43
- - sig/generated/spreen/wiki/home.rbs
44
- - sig/generated/spreen/wiki/sidebar.rbs
45
- - sig/generated/spreen/wiki/unknown_wiki_count_list_exporter.rbs
46
- - sig/generated/spreen/wiki/unknown_wiki_list_exporter_for_llm.rbs
47
- - sig/generated/spreen/wiki/version.rbs
39
+ - sig/generated/spreen_wiki.rbs
40
+ - sig/generated/spreen_wiki/application.rbs
41
+ - sig/generated/spreen_wiki/cli.rbs
42
+ - sig/generated/spreen_wiki/configuration.rbs
43
+ - sig/generated/spreen_wiki/home.rbs
44
+ - sig/generated/spreen_wiki/sidebar.rbs
45
+ - sig/generated/spreen_wiki/unknown_wiki_count_list_exporter.rbs
46
+ - sig/generated/spreen_wiki/unknown_wiki_list_exporter_for_llm.rbs
47
+ - sig/generated/spreen_wiki/version.rbs
48
48
  - sig/generated/test/application_test.rbs
49
49
  - sig/generated/test/configuration_test.rbs
50
50
  - sig/generated/test/home_test.rbs
@@ -1,151 +0,0 @@
1
- # frozen_string_literal: true
2
- # rbs_inline: enabled
3
-
4
- require_relative 'configuration'
5
-
6
- module Spreen
7
- module Wiki
8
- # Base class for the wiki-organising commands. Loads the wiki tree under
9
- # base_path, groups it by Owner or Category in either English or Japanese,
10
- # and exposes the resulting maps to its subclasses. Grouping criteria,
11
- # languages and labels are resolved through Configuration and can be
12
- # extended via a `.spreen.yml` file.
13
- class Application
14
- class NotImplementedError < StandardError; end
15
-
16
- # @rbs base_path: String
17
- # @rbs group_by: String
18
- # @rbs language: String
19
- # @rbs home_overflow: (bool | String)
20
- # @rbs **options: untyped
21
- # @rbs return: untyped
22
- def self.run(base_path: Dir.pwd, group_by: 'Owner', language: 'English', home_overflow: 'false', **)
23
- instance = new(base_path:, group_by:, language:, home_overflow:, **)
24
- instance.validate!
25
- instance.run
26
- end
27
-
28
- # @rbs base_path: String
29
- # @rbs group_by: String
30
- # @rbs language: String
31
- # @rbs home_overflow: (bool | String)
32
- # @rbs config: Configuration?
33
- # @rbs **options: untyped
34
- # @rbs return: void
35
- def initialize(base_path: Dir.pwd, group_by: 'Owner', language: 'English', home_overflow: 'false',
36
- config: nil, **)
37
- @base_path = base_path
38
- @group_by = group_by
39
- @language = language
40
- @home_overflow = parse_home_overflow(home_overflow)
41
- @config = config || Configuration.new(base_path:, **)
42
- @path_to_home = File.join(base_path, 'Home.md')
43
- @path_to_sidebar = File.join(base_path, '_Sidebar.md')
44
- @paths_to_wikis = Dir[File.join(base_path, '**', '*.md')]
45
- @excluded_paths = @config.excluded_dirs.flat_map { |dir| Dir[File.join(base_path, dir, '**', '*.md')] }
46
- end
47
-
48
- # @rbs return: void
49
- def validate!
50
- raise ArgumentError, "Invalid group_by: `#{group_by}`" unless config.group_bys.include?(group_by)
51
- raise ArgumentError, "Invalid language: `#{language}`" unless config.languages(group_by).include?(language)
52
-
53
- validate_home_overflow!
54
- end
55
-
56
- # @rbs return: untyped
57
- def run
58
- raise NotImplementedError, 'This method must be implemented in each subclass.'
59
- end
60
-
61
- private
62
-
63
- attr_reader :base_path,
64
- :group_by,
65
- :language,
66
- :home_overflow,
67
- :config,
68
- :path_to_home,
69
- :path_to_sidebar,
70
- :paths_to_wikis,
71
- :excluded_paths
72
-
73
- # @rbs return: void
74
- def validate_home_overflow!
75
- return if [true, false].include?(home_overflow)
76
-
77
- raise ArgumentError, "Invalid home_overflow: `#{home_overflow}` must be boolean"
78
- end
79
-
80
- # @rbs raw: (bool | String)
81
- # @rbs return: (bool | String)
82
- def parse_home_overflow(raw)
83
- case raw
84
- when 'true' then true
85
- when 'false' then false
86
- else raw
87
- end
88
- end
89
-
90
- # @rbs return: Array[String]
91
- def target_paths
92
- @target_paths ||= paths_to_wikis.reject do |path_to_wiki|
93
- path_to_wiki == path_to_home ||
94
- path_to_wiki == path_to_sidebar ||
95
- excluded_paths.include?(path_to_wiki)
96
- end
97
- end
98
-
99
- # @rbs return: Regexp
100
- def target_regexp
101
- @target_regexp ||= config.target_regexp(group_by)
102
- end
103
-
104
- # @rbs return: String
105
- def no_declaration
106
- @no_declaration ||= config.no_declaration(group_by, language)
107
- end
108
-
109
- # @rbs return: Hash[String, Array[String]]
110
- def wiki_maps_with_namespace
111
- @wiki_maps_with_namespace ||= begin
112
- named = Hash.new { |hash, namespace| hash[namespace] = [] } #: Hash[String, Array[String]]
113
- undeclared = Hash.new { |hash, namespace| hash[namespace] = [] } #: Hash[String, Array[String]]
114
- target_paths.each { |target_path| populate_namespace(target_path, named, undeclared) }
115
- named.sort.to_h.merge(undeclared)
116
- end
117
- end
118
-
119
- # @rbs target_path: String
120
- # @rbs named: Hash[String, Array[String]]
121
- # @rbs undeclared: Hash[String, Array[String]]
122
- # @rbs return: void
123
- def populate_namespace(target_path, named, undeclared)
124
- return unless File.exist?(target_path)
125
-
126
- namespace = namespace_for(target_path)
127
- bucket = namespace == no_declaration ? undeclared : named
128
- bucket[namespace] << File.basename(target_path)
129
- end
130
-
131
- # @rbs target_path: String
132
- # @rbs return: String
133
- def namespace_for(target_path)
134
- declaration = File.open(target_path, &:gets)
135
- return no_declaration unless declaration&.start_with?(target_regexp)
136
-
137
- declaration.chomp.gsub(target_regexp, '')
138
- end
139
-
140
- # @rbs return: Hash[String, Array[String]]
141
- def owned_wiki_maps
142
- @owned_wiki_maps ||= wiki_maps_with_namespace.select { |namespace, _| namespace.include?('@') }
143
- end
144
-
145
- # @rbs return: Hash[String, Array[String]]
146
- def plain_wiki_maps
147
- @plain_wiki_maps ||= wiki_maps_with_namespace.reject { |namespace, _| namespace.include?('@') }
148
- end
149
- end
150
- end
151
- end
@@ -1,159 +0,0 @@
1
- # frozen_string_literal: true
2
- # rbs_inline: enabled
3
-
4
- require 'optparse'
5
- require_relative 'version'
6
- require_relative 'home'
7
- require_relative 'sidebar'
8
- require_relative 'unknown_wiki_count_list_exporter'
9
- require_relative 'unknown_wiki_list_exporter_for_llm'
10
-
11
- module Spreen
12
- module Wiki
13
- # Command line interface behind the `spreen` executable:
14
- # `spreen <update|count-report|llm-export> [options]`.
15
- class CLI
16
- HELP = <<~HELP
17
- Usage: spreen <command> [options]
18
-
19
- Commands:
20
- update Regenerate Home.md and _Sidebar.md from the wiki tree
21
- count-report Export a count report of the unknown-namespace wikis
22
- llm-export Export the unknown-namespace wiki list for an LLM
23
- version Print the version
24
-
25
- Run `spreen <command> --help` to list the command's options.
26
- HELP
27
-
28
- # Flags shared by every command, mapped to the keyword arguments of the
29
- # underlying classes. --exclude and the per-command flags are wired up
30
- # separately because they need a type or a fixed value.
31
- COMMON_OPTIONS = {
32
- '--path PATH' => [:base_path, 'Path to the wiki clone (default: current directory)'],
33
- '--group-by GROUP_BY' => [:group_by, 'Grouping criteria (default: Owner)'],
34
- '--language LANGUAGE' => [:language, 'Language of the labels (default: English)'],
35
- '--org ORGANISATION' => [:organisation, 'GitHub organisation/user hosting the wiki'],
36
- '--repo REPOSITORY' => [:repository, 'GitHub repository whose wiki is organised'],
37
- '--wiki-url URL' => [:wiki_url, 'Wiki URL (overrides the one derived from --org/--repo)'],
38
- '--template-dir DIR' => [:template_dir, 'Directory of <group_by>/<language>.md Home templates'],
39
- '--config FILE' => [:config_path, 'Config file path (default: <path>/.spreen.yml)']
40
- }.freeze
41
-
42
- # @rbs argv: Array[String]
43
- # @rbs return: Integer
44
- def self.start(argv = ARGV)
45
- new(argv).run
46
- end
47
-
48
- # @rbs argv: Array[String]
49
- # @rbs return: void
50
- def initialize(argv)
51
- @argv = argv.dup
52
- @options = { base_path: Dir.pwd, group_by: 'Owner', language: 'English', home_overflow: 'false' }
53
- end
54
-
55
- # @rbs return: Integer
56
- def run
57
- command = argv.shift
58
- case command
59
- when 'update', 'count-report', 'llm-export' then execute(command)
60
- when 'version', '--version', '-v' then print_version
61
- when nil, 'help', '--help', '-h' then print_help(command)
62
- else unknown_command(command)
63
- end
64
- end
65
-
66
- private
67
-
68
- attr_reader :argv, :options
69
-
70
- # @rbs command: String
71
- # @rbs return: Integer
72
- def execute(command)
73
- parser(command).parse!(argv)
74
- __send__(command.tr('-', '_'))
75
- 0
76
- rescue ArgumentError, OptionParser::ParseError => e
77
- warn e.message
78
- 1
79
- end
80
-
81
- # @rbs return: Integer
82
- def print_version
83
- puts VERSION
84
- 0
85
- end
86
-
87
- # @rbs command: String?
88
- # @rbs return: Integer
89
- def print_help(command)
90
- puts HELP
91
- command.nil? ? 1 : 0
92
- end
93
-
94
- # @rbs command: String
95
- # @rbs return: Integer
96
- def unknown_command(command)
97
- warn "Unknown command: `#{command}`"
98
- warn HELP
99
- 1
100
- end
101
-
102
- # @rbs return: void
103
- def update
104
- wiki_url = Home.run(**options)
105
- Sidebar.run(**options)
106
- puts 'Updated Home.md and _Sidebar.md.'
107
- puts "Check them out at '#{wiki_url}' !!" if wiki_url
108
- end
109
-
110
- # @rbs return: void
111
- def count_report
112
- count_list_by_namespace, path_to_export = UnknownWikiCountListExporter.run(**options)
113
- puts count_list_by_namespace
114
- puts "Exported the unknown wiki count report to '#{path_to_export}'."
115
- end
116
-
117
- # @rbs return: void
118
- def llm_export
119
- path_to_export = UnknownWikiListExporterForLLM.run(**options)
120
- puts "Exported the unknown wiki list for LLM to '#{path_to_export}'."
121
- end
122
-
123
- # @rbs command: String
124
- # @rbs return: OptionParser
125
- def parser(command)
126
- OptionParser.new("Usage: spreen #{command} [options]") do |opt|
127
- add_common_options(opt)
128
- add_command_options(opt, command)
129
- end
130
- end
131
-
132
- # @rbs opt: OptionParser
133
- # @rbs return: void
134
- def add_common_options(opt)
135
- COMMON_OPTIONS.each do |flag, (key, description)|
136
- opt.on(flag, description) { |value| options[key] = value }
137
- end
138
- opt.on('--exclude DIR1,DIR2', Array, 'Directories to skip while scanning') do |dirs|
139
- options[:excluded_dirs] = dirs
140
- end
141
- end
142
-
143
- # @rbs opt: OptionParser
144
- # @rbs command: String
145
- # @rbs return: void
146
- def add_command_options(opt, command)
147
- if command == 'update'
148
- opt.on('--overflow', 'Split Home into per-namespace pages under wikis-by-owner/') do
149
- options[:home_overflow] = 'true'
150
- end
151
- else
152
- opt.on('--output FILENAME', 'Export filename (relative to --path unless absolute)') do |filename|
153
- options[:output] = filename
154
- end
155
- end
156
- end
157
- end
158
- end
159
- end
@@ -1,217 +0,0 @@
1
- # frozen_string_literal: true
2
- # rbs_inline: enabled
3
-
4
- require 'yaml'
5
-
6
- module Spreen
7
- module Wiki
8
- # Resolves the runtime configuration for a wiki checkout. Every value is
9
- # looked up with the same precedence: explicit keyword argument, then the
10
- # `.spreen.yml` file under base_path (or config_path), then the
11
- # ORGANISATION_NAME environment variable (organisation only), then the
12
- # built-in defaults.
13
- class Configuration
14
- CONFIG_FILENAME = '.spreen.yml'
15
- EMPTY_HASH = {}.freeze #: Hash[String, untyped]
16
- DEFAULT_TEMPLATE_DIR = File.expand_path(File.join(__dir__.to_s, 'templates'))
17
- DEFAULT_EXCLUDED_DIRS = %w[spreen-wiki wikis-by-owner].freeze
18
-
19
- # Built-in labels: how the first line of a wiki page is parsed (regexp),
20
- # which namespace collects pages without a declaration (no_declaration),
21
- # which namespaces the count report covers (unknown_namespaces) and which
22
- # namespace the LLM export targets (llm_target_namespace). A config file
23
- # can override any of these, add languages or add group_by criteria.
24
- DEFAULT_LABELS = {
25
- 'Owner' => {
26
- 'regexp' => '[Oo]wner:\s?',
27
- 'languages' => {
28
- 'English' => {
29
- 'no_declaration' => 'Unowned',
30
- 'unknown_namespaces' => ['Unknown Owner nor Necessity', 'Unowned but Necessary', 'Unowned'],
31
- 'llm_target_namespace' => 'Unknown Owner nor Necessity'
32
- },
33
- 'Japanese' => {
34
- 'no_declaration' => 'Owner記名なし',
35
- 'unknown_namespaces' => [
36
- 'Ownerチームが不明だが必要なページ群',
37
- 'Ownerチーム・要or不要が不明なページ群',
38
- 'Owner記名なし'
39
- ],
40
- 'llm_target_namespace' => 'Ownerチーム・要or不要が不明なページ群'
41
- }
42
- }
43
- },
44
- 'Category' => {
45
- 'regexp' => '[Cc]ategory:\s?',
46
- 'languages' => {
47
- 'English' => {
48
- 'no_declaration' => 'Uncategorised',
49
- 'unknown_namespaces' => ['Uncategorised'],
50
- 'llm_target_namespace' => 'Uncategorised'
51
- },
52
- 'Japanese' => {
53
- 'no_declaration' => 'Category記載なし',
54
- 'unknown_namespaces' => ['Category記載なし'],
55
- 'llm_target_namespace' => 'Category記載なし'
56
- }
57
- }
58
- }
59
- }.freeze
60
-
61
- attr_reader :organisation, :repository, :wiki_url, :owner_base_url, :excluded_dirs, :template_dir
62
-
63
- # @rbs!
64
- # @organisation: String?
65
- # @repository: String?
66
- # @wiki_url: String?
67
- # @owner_base_url: String?
68
- # @excluded_dirs: Array[String]
69
- # @template_dir: String
70
- # @file: Hash[String, untyped]
71
- # @labels: Hash[String, untyped]
72
-
73
- # @rbs base_path: String
74
- # @rbs config_path: String?
75
- # @rbs organisation: String?
76
- # @rbs repository: String?
77
- # @rbs wiki_url: String?
78
- # @rbs owner_base_url: String?
79
- # @rbs excluded_dirs: Array[String]?
80
- # @rbs template_dir: String?
81
- # @rbs return: void
82
- def initialize(base_path:, config_path: nil, organisation: nil, repository: nil, wiki_url: nil,
83
- owner_base_url: nil, excluded_dirs: nil, template_dir: nil)
84
- @file = load_file(config_path || File.join(base_path, CONFIG_FILENAME))
85
- @organisation = resolve_organisation(organisation)
86
- @repository = resolve(repository, 'repository')
87
- @wiki_url = resolve_wiki_url(wiki_url)
88
- @owner_base_url = resolve_owner_base_url(owner_base_url)
89
- @excluded_dirs = excluded_dirs || file.fetch('exclude', DEFAULT_EXCLUDED_DIRS)
90
- @template_dir = template_dir || file.fetch('template_dir', DEFAULT_TEMPLATE_DIR)
91
- @labels = deep_merge(DEFAULT_LABELS, file.fetch('labels', EMPTY_HASH))
92
- end
93
-
94
- # @rbs return: Array[String]
95
- def group_bys
96
- labels.keys
97
- end
98
-
99
- # @rbs group_by: String
100
- # @rbs return: Array[String]
101
- def languages(group_by)
102
- label_for(group_by).fetch('languages', EMPTY_HASH).keys
103
- end
104
-
105
- # @rbs group_by: String
106
- # @rbs return: Regexp
107
- def target_regexp(group_by)
108
- Regexp.new(label_for(group_by).fetch('regexp', ''))
109
- end
110
-
111
- # @rbs group_by: String
112
- # @rbs language: String
113
- # @rbs return: String
114
- def no_declaration(group_by, language)
115
- language_labels(group_by, language).fetch('no_declaration', '')
116
- end
117
-
118
- # @rbs group_by: String
119
- # @rbs language: String
120
- # @rbs return: Array[String]
121
- def unknown_namespaces(group_by, language)
122
- language_labels(group_by, language).fetch('unknown_namespaces', [])
123
- end
124
-
125
- # @rbs group_by: String
126
- # @rbs language: String
127
- # @rbs return: String
128
- def llm_target_namespace(group_by, language)
129
- language_labels(group_by, language).fetch('llm_target_namespace', '')
130
- end
131
-
132
- # @rbs group_by: String
133
- # @rbs language: String
134
- # @rbs return: String
135
- def path_to_template(group_by, language)
136
- File.join(template_dir, group_by.downcase, "#{language.downcase}.md")
137
- end
138
-
139
- private
140
-
141
- attr_reader :file, :labels
142
-
143
- # Treats empty strings the same as nil so that callers can pass values
144
- # straight from optional environment variables or CLI flags.
145
- # @rbs value: String?
146
- # @rbs return: String?
147
- def presence(value)
148
- value unless value.nil? || value.empty?
149
- end
150
-
151
- # @rbs explicit: String?
152
- # @rbs key: String
153
- # @rbs return: String?
154
- def resolve(explicit, key)
155
- presence(explicit) || presence(file[key])
156
- end
157
-
158
- # @rbs explicit: String?
159
- # @rbs return: String?
160
- def resolve_organisation(explicit)
161
- resolve(explicit, 'organisation') || presence(ENV.fetch('ORGANISATION_NAME', nil))
162
- end
163
-
164
- # @rbs explicit: String?
165
- # @rbs return: String?
166
- def resolve_wiki_url(explicit)
167
- resolve(explicit, 'wiki_url') || default_wiki_url
168
- end
169
-
170
- # @rbs explicit: String?
171
- # @rbs return: String?
172
- def resolve_owner_base_url(explicit)
173
- resolve(explicit, 'owner_base_url') || default_owner_base_url
174
- end
175
-
176
- # @rbs path: String
177
- # @rbs return: Hash[String, untyped]
178
- def load_file(path)
179
- return {} unless File.exist?(path)
180
-
181
- YAML.safe_load_file(path) || {}
182
- end
183
-
184
- # @rbs group_by: String
185
- # @rbs return: Hash[String, untyped]
186
- def label_for(group_by)
187
- labels.fetch(group_by, EMPTY_HASH)
188
- end
189
-
190
- # @rbs group_by: String
191
- # @rbs language: String
192
- # @rbs return: Hash[String, untyped]
193
- def language_labels(group_by, language)
194
- label_for(group_by).fetch('languages', EMPTY_HASH).fetch(language, EMPTY_HASH)
195
- end
196
-
197
- # @rbs return: String?
198
- def default_wiki_url
199
- "https://github.com/#{organisation}/#{repository}/wiki" if organisation && repository
200
- end
201
-
202
- # @rbs return: String?
203
- def default_owner_base_url
204
- "https://github.com/orgs/#{organisation}/teams/" if organisation
205
- end
206
-
207
- # @rbs base: Hash[String, untyped]
208
- # @rbs override: Hash[String, untyped]
209
- # @rbs return: Hash[String, untyped]
210
- def deep_merge(base, override)
211
- base.merge(override) do |_key, old_value, new_value|
212
- old_value.is_a?(Hash) && new_value.is_a?(Hash) ? deep_merge(old_value, new_value) : new_value
213
- end
214
- end
215
- end
216
- end
217
- end
@@ -1,102 +0,0 @@
1
- # frozen_string_literal: true
2
- # rbs_inline: enabled
3
-
4
- require 'fileutils'
5
- require_relative 'application'
6
-
7
- module Spreen
8
- module Wiki
9
- # Generates the wiki Home page, optionally splitting per-owner content out
10
- # into `wikis-by-owner/<owner>.md` when home_overflow is enabled. Returns
11
- # the configured wiki URL (if any) so callers can point at the result.
12
- class Home < Application
13
- # @rbs return: String?
14
- def run
15
- home_overflow ? write_concise_home_passage : write_home_passage
16
- config.wiki_url
17
- end
18
-
19
- private
20
-
21
- # @rbs return: String
22
- def path_to_wikis_by_owner
23
- @path_to_wikis_by_owner ||= File.join(base_path, 'wikis-by-owner')
24
- end
25
-
26
- # @rbs return: String
27
- def path_to_home_template
28
- path = config.path_to_template(group_by, language)
29
- unless File.exist?(path)
30
- raise ArgumentError, "Missing Home template: `#{path}`. Ship one there or configure template_dir."
31
- end
32
-
33
- path
34
- end
35
-
36
- # @rbs return: Array[String]
37
- def home_passage
38
- @home_passage ||= File.readlines(path_to_home_template).append("\n")
39
- end
40
-
41
- # @rbs return: void
42
- def write_home_passage
43
- FileUtils.rm_rf(path_to_wikis_by_owner)
44
- owned_wiki_maps.each { |namespace, wikis| append_block(home_passage, namespace, wikis, owned: true) }
45
- plain_wiki_maps.each { |namespace, wikis| append_block(home_passage, namespace, wikis, owned: false) }
46
- File.write(path_to_home, home_passage.join.chomp)
47
- end
48
-
49
- # @rbs return: void
50
- def write_concise_home_passage
51
- FileUtils.mkdir_p(path_to_wikis_by_owner)
52
- write_per_namespace_files
53
- write_home_table_of_contents
54
- end
55
-
56
- # @rbs return: void
57
- def write_per_namespace_files
58
- owned_wiki_maps.each { |namespace, wikis| write_overflow_block(namespace, wikis, owned: true) }
59
- plain_wiki_maps.each { |namespace, wikis| write_overflow_block(namespace, wikis, owned: false) }
60
- end
61
-
62
- # @rbs return: void
63
- def write_home_table_of_contents
64
- (owned_wiki_maps.keys + plain_wiki_maps.keys).each { |namespace| home_passage << "- [[#{namespace}]]\n" }
65
- home_passage << "\n"
66
- File.write(path_to_home, home_passage.join.chomp)
67
- end
68
-
69
- # @rbs passage: Array[String]
70
- # @rbs namespace: String
71
- # @rbs wikis: Array[String]
72
- # @rbs owned: bool
73
- # @rbs return: void
74
- def append_block(passage, namespace, wikis, owned:)
75
- passage << "#{heading_for(namespace, owned:)}\n"
76
- passage << "\n"
77
- wikis.each { |wiki| passage << "- [[#{wiki.gsub('.md', '')}]]\n" }
78
- passage << "\n"
79
- end
80
-
81
- # @rbs namespace: String
82
- # @rbs wikis: Array[String]
83
- # @rbs owned: bool
84
- # @rbs return: void
85
- def write_overflow_block(namespace, wikis, owned:)
86
- scratch = [] #: Array[String]
87
- append_block(scratch, namespace, wikis, owned:)
88
- File.write(File.join(path_to_wikis_by_owner, "#{namespace}.md"), scratch.join.chomp)
89
- end
90
-
91
- # @rbs namespace: String
92
- # @rbs owned: bool
93
- # @rbs return: String
94
- def heading_for(namespace, owned:)
95
- owner_base_url = config.owner_base_url
96
- return "## #{namespace}" unless owned && owner_base_url
97
-
98
- "## [#{namespace}](#{owner_base_url + namespace.delete('@')})"
99
- end
100
- end
101
- end
102
- end