ascii_binder 0.1.10.1 → 0.1.11
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.
- checksums.yaml +4 -4
- data/features/repo_build.feature +5 -0
- data/features/step_definitions/steps.rb +7 -0
- data/features/support/_invalid_alias_topic_map.yml +50 -0
- data/features/support/env.rb +54 -4
- data/features/support/test_distro/_topic_map.yml +14 -0
- data/features/support/test_distro/welcome/aliased.adoc +9 -0
- data/lib/ascii_binder/distro_branch.rb +4 -0
- data/lib/ascii_binder/engine.rb +19 -2
- data/lib/ascii_binder/helpers.rb +11 -0
- data/lib/ascii_binder/topic_entity.rb +90 -21
- data/lib/ascii_binder/topic_map.rb +53 -3
- data/lib/ascii_binder/version.rb +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53fd1820d7812317c08e7b9f6546b218a6e4f446
|
4
|
+
data.tar.gz: 43dc2c310ecaadd51d3ff32b63b07a6c63eba03f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26b8c93816f4b5b0a5b80862448dd18cdc9acb79e464ee7c5655e5cc14c506e5c53c32356bd2e87344d0e390433148ec0f7458733711868d31a9dbce8439a78c
|
7
|
+
data.tar.gz: a1ea94b2f4dd024146b9809fdb040d7c681bc7ed93bdc22e7a33f9a0c8b056ef4aad254e15e6452398bc8e8abdc1d9ff48e90eb1ad945da28b56f88c8aaa39be
|
data/features/repo_build.feature
CHANGED
@@ -13,6 +13,11 @@ Feature: asciibinder build
|
|
13
13
|
When the user runs `asciibinder build` on that repo directory
|
14
14
|
Then the program generates preview content for all distros in the current branch
|
15
15
|
|
16
|
+
Scenario: A user wants to do a build in a repo with alias that points to a nonexistant topic
|
17
|
+
Given a valid AsciiBinder docs repo with an invalid alias
|
18
|
+
When the user runs `asciibinder build` on that repo directory
|
19
|
+
Then the program exits with a warning
|
20
|
+
|
16
21
|
Scenario: A user wants to build a single distro against the current repo branch
|
17
22
|
Given a valid AsciiBinder docs repo with multiple distros
|
18
23
|
When the user runs `asciibinder build --distro=distro_test` on that repo directory
|
@@ -15,13 +15,20 @@ end
|
|
15
15
|
Given(/^a valid AsciiBinder docs repo(.*)$/) do |repo_condition|
|
16
16
|
multiple_distros = false
|
17
17
|
offset_docs_root = false
|
18
|
+
invalid_alias = false
|
18
19
|
if repo_condition == ' with multiple distros'
|
19
20
|
multiple_distros = true
|
20
21
|
elsif repo_condition == ' where the docs root is not at the repo root'
|
21
22
|
multiple_distros = true
|
22
23
|
offset_docs_root = true
|
24
|
+
elsif repo_condition == ' with an invalid alias'
|
25
|
+
multiple_distros = true
|
26
|
+
invalid_alias = true
|
23
27
|
end
|
24
28
|
initialize_test_repo(true,multiple_distros,offset_docs_root)
|
29
|
+
if invalid_alias
|
30
|
+
invalidate_topic_map
|
31
|
+
end
|
25
32
|
end
|
26
33
|
|
27
34
|
Given(/^an invalid AsciiBinder docs repo(.*)$/) do |invalid_condition|
|
@@ -0,0 +1,50 @@
|
|
1
|
+
---
|
2
|
+
Name: AsciiBinder Doc Project
|
3
|
+
Dir: welcome
|
4
|
+
Topics:
|
5
|
+
- Name: Welcome
|
6
|
+
File: index
|
7
|
+
- Name: Aliased Topic
|
8
|
+
File: aliased
|
9
|
+
- Name: Subtopics
|
10
|
+
Dir: subtopics
|
11
|
+
Topics:
|
12
|
+
- Name: All Distros
|
13
|
+
File: index
|
14
|
+
- Name: MAIN_ONLY_TOPIC
|
15
|
+
File: main_only_topic
|
16
|
+
Distros: distro_main
|
17
|
+
- Name: TEST_ONLY_TOPIC
|
18
|
+
File: test_only_topic
|
19
|
+
Distros: distro_test
|
20
|
+
- Name: Wilcard All
|
21
|
+
File: wildcard_all
|
22
|
+
Distros: distro_*
|
23
|
+
|
24
|
+
---
|
25
|
+
Name: MAIN_ONLY_TOPIC_GROUP
|
26
|
+
Dir: main_only_topic_group
|
27
|
+
Distros: distro_main
|
28
|
+
Topics:
|
29
|
+
- Name: MAIN_ONLY_WELCOME
|
30
|
+
File: index
|
31
|
+
|
32
|
+
---
|
33
|
+
Name: TEST_ONLY_TOPIC_GROUP
|
34
|
+
Dir: test_only_topic_group
|
35
|
+
Distros: distro_test
|
36
|
+
Topics:
|
37
|
+
- Name: TEST_ONLY_WELCOME
|
38
|
+
File: index
|
39
|
+
|
40
|
+
---
|
41
|
+
Name: ALIASES_GROUP
|
42
|
+
Dir: aliases
|
43
|
+
Topics:
|
44
|
+
- Name: Alias to Nonexistant
|
45
|
+
File: a_to_a
|
46
|
+
Alias: welcome/nonexistent
|
47
|
+
- Name: Alias to External
|
48
|
+
File: a_to_e
|
49
|
+
Alias: https://redhat.com/
|
50
|
+
|
data/features/support/env.rb
CHANGED
@@ -45,6 +45,10 @@ module Helpers
|
|
45
45
|
@topic_map ||= YAML.load_stream(open(File.join(docs_root,'_topic_map.yml')))
|
46
46
|
end
|
47
47
|
|
48
|
+
def alias_files
|
49
|
+
@alias_files ||= ['aliases/a_to_a.html','aliases/a_to_e.html']
|
50
|
+
end
|
51
|
+
|
48
52
|
def preview_dir
|
49
53
|
@preview_dir ||= File.join(docs_root,'_preview')
|
50
54
|
end
|
@@ -78,6 +82,22 @@ module Helpers
|
|
78
82
|
`cd #{dir} && find .`.split("\n").select{ |item| item.end_with?('.html') }.map{ |item| item[2..-1] }
|
79
83
|
end
|
80
84
|
|
85
|
+
def files_diff_explanation(gen_paths,cfg_paths)
|
86
|
+
gen_extras = (gen_paths-cfg_paths)
|
87
|
+
cfg_extras = (cfg_paths-gen_paths)
|
88
|
+
explanation = ''
|
89
|
+
if gen_extras.length > 0
|
90
|
+
explanation = "Unexpected extra files were generated:\n\t* " + gen_extras.join("\n\t* ")
|
91
|
+
end
|
92
|
+
if cfg_extras.length > 0
|
93
|
+
if explanation.length > 0
|
94
|
+
explanation = explanation + "\n"
|
95
|
+
end
|
96
|
+
explanation = explanation + "Expected files were not generated:\n\t* " + cfg_extras.join("\n\t* ")
|
97
|
+
end
|
98
|
+
return explanation
|
99
|
+
end
|
100
|
+
|
81
101
|
def actual_preview_info
|
82
102
|
all_preview_paths = find_html_files(preview_dir)
|
83
103
|
|
@@ -292,6 +312,12 @@ module Helpers
|
|
292
312
|
system("cd #{working_dir} && git add . > /dev/null && git commit -am 'Commit invalid distro map' > /dev/null")
|
293
313
|
end
|
294
314
|
|
315
|
+
def invalidate_topic_map
|
316
|
+
invalid_map = File.join(gem_root,'features','support','_invalid_alias_topic_map.yml')
|
317
|
+
FileUtils.cp(invalid_map,File.join(docs_root,'_topic_map.yml'))
|
318
|
+
system("cd #{working_dir} && git add . > /dev/null && git commit -am 'Commit invalid alias topic map' > /dev/null")
|
319
|
+
end
|
320
|
+
|
295
321
|
def initialize_remote_repo
|
296
322
|
remote_dir = Dir.mktmpdir('ascii_binder-cucumber-remote')
|
297
323
|
FileUtils.rm_rf(remote_dir)
|
@@ -357,7 +383,6 @@ module Helpers
|
|
357
383
|
target_distro = real_preview_info[:distros][0]
|
358
384
|
target_page = real_preview_info[:pages][0].split('/').join(':').split('.')[0]
|
359
385
|
|
360
|
-
|
361
386
|
if distro_count == 0 or branch_count == 0
|
362
387
|
puts "ERROR: A build operation should produce at least one distro / branch preview."
|
363
388
|
exit 1
|
@@ -413,8 +438,20 @@ module Helpers
|
|
413
438
|
puts "ERROR: Expected distro / branch combo '#{distro}' / '#{branch}' was not generated for preview."
|
414
439
|
exit 1
|
415
440
|
end
|
441
|
+
# Alias check
|
442
|
+
alias_files.each do |afile|
|
443
|
+
genmatches = gen_paths_map[distro][branch].select{ |i| i.end_with?(afile) }
|
444
|
+
if genmatches.length == 0
|
445
|
+
puts "ERROR: Alias file '#{afile}' was not generated for distro / branch combo '#{distro}' / '#{branch}'."
|
446
|
+
exit 1
|
447
|
+
elsif genmatches.length > 1
|
448
|
+
puts "ERROR: Alias file '#{afile}' found more than once in generated output: #{genmatches.inspect}"
|
449
|
+
exit 1
|
450
|
+
end
|
451
|
+
end
|
416
452
|
if not gen_paths_map[distro][branch] == all_paths_map[distro][branch]
|
417
|
-
|
453
|
+
explanation = files_diff_explanation(gen_paths_map[distro][branch],all_paths_map[distro][branch])
|
454
|
+
puts "ERROR: Mismatch between expected and actual preview file paths for distro / branch combo '#{distro}' / '#{branch}'.\n#{explanation}"
|
418
455
|
exit 1
|
419
456
|
end
|
420
457
|
end
|
@@ -434,10 +471,23 @@ module Helpers
|
|
434
471
|
puts "ERROR: Content was generated for site '#{site}' even though it was only expected for site '#{target_site}'"
|
435
472
|
exit 1
|
436
473
|
end
|
437
|
-
|
474
|
+
# Alias check
|
475
|
+
if real_site_map[site][distro][branch].length > 0 and all_paths_map[site][distro][branch].length > 0
|
476
|
+
alias_files.each do |afile|
|
477
|
+
genmatches = real_site_map[site][distro][branch].select{ |i| i.end_with?(afile) }
|
478
|
+
if genmatches.length == 0
|
479
|
+
puts "ERROR: Alias file '#{afile}' was not generated for site / distro / branch combo '#{site}' / '#{distro}' / '#{branch}'."
|
480
|
+
exit 1
|
481
|
+
elsif genmatches.length > 1
|
482
|
+
puts "ERROR: Alias file '#{afile}' found more than once in generated site output: #{genmatches.inspect}"
|
483
|
+
exit 1
|
484
|
+
end
|
485
|
+
end
|
486
|
+
end
|
438
487
|
# Confirm that what was generated matches what was expected.
|
439
488
|
if (target_site == '' or site == target_site) and not real_site_map[site][distro][branch] == all_paths_map[site][distro][branch]
|
440
|
-
|
489
|
+
explanation = files_diff_explanation(real_site_map[site][distro][branch],all_paths_map[site][distro][branch])
|
490
|
+
puts "ERROR: Mismatch between expected and actual site file paths for site / distro / branch combo '#{site}' / '#{distro}' / '#{branch}'.\n#{explanation}"
|
441
491
|
exit 1
|
442
492
|
end
|
443
493
|
end
|
@@ -4,6 +4,8 @@ Dir: welcome
|
|
4
4
|
Topics:
|
5
5
|
- Name: Welcome
|
6
6
|
File: index
|
7
|
+
- Name: Aliased Topic
|
8
|
+
File: aliased
|
7
9
|
- Name: Subtopics
|
8
10
|
Dir: subtopics
|
9
11
|
Topics:
|
@@ -34,3 +36,15 @@ Distros: distro_test
|
|
34
36
|
Topics:
|
35
37
|
- Name: TEST_ONLY_WELCOME
|
36
38
|
File: index
|
39
|
+
|
40
|
+
---
|
41
|
+
Name: ALIASES_GROUP
|
42
|
+
Dir: aliases
|
43
|
+
Topics:
|
44
|
+
- Name: Alias to Aliased
|
45
|
+
File: a_to_a
|
46
|
+
Alias: welcome/aliased
|
47
|
+
- Name: Alias to External
|
48
|
+
File: a_to_e
|
49
|
+
Alias: https://redhat.com/
|
50
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
= Aliased Topic
|
2
|
+
{product-author}
|
3
|
+
{product-version}
|
4
|
+
:data-uri:
|
5
|
+
:icons:
|
6
|
+
|
7
|
+
This topic exercises topic _aliasing_, which enables authors to manage page redirects without having to fiddle with web server settings.
|
8
|
+
|
9
|
+
This behavior borrows directly from the same-named concept supported by the link:https://gohugo.io[hugo] blog generator.
|
@@ -27,6 +27,10 @@ module AsciiBinder
|
|
27
27
|
@branch_path ||= File.join(preview_dir,@distro.id,@dir)
|
28
28
|
end
|
29
29
|
|
30
|
+
def branch_url_base
|
31
|
+
@branch_url_base ||= File.join('/',@dir)
|
32
|
+
end
|
33
|
+
|
30
34
|
def branch_stylesheet_dir
|
31
35
|
@branch_stylesheet_dir ||= File.join(branch_path,STYLESHEET_DIRNAME)
|
32
36
|
end
|
data/lib/ascii_binder/engine.rb
CHANGED
@@ -437,11 +437,26 @@ module AsciiBinder
|
|
437
437
|
if single_page_path.length == 0
|
438
438
|
puts " - #{topic_entity.repo_path}"
|
439
439
|
end
|
440
|
-
|
440
|
+
if topic_entity.is_alias?
|
441
|
+
configure_and_generate_alias(topic_entity,branch_config)
|
442
|
+
else
|
443
|
+
configure_and_generate_page(topic_entity,branch_config,navigation)
|
444
|
+
end
|
441
445
|
end
|
442
446
|
end
|
443
447
|
end
|
444
448
|
|
449
|
+
def configure_and_generate_alias(topic,branch_config)
|
450
|
+
distro = branch_config.distro
|
451
|
+
topic_target = topic.topic_alias
|
452
|
+
unless valid_url?(topic_target)
|
453
|
+
topic_target = File.join(branch_config.branch_url_base,topic_target + ".html")
|
454
|
+
end
|
455
|
+
topic_text = alias_text(topic_target)
|
456
|
+
preview_path = topic.preview_path(distro.id,branch_config.dir)
|
457
|
+
File.write(preview_path,topic_text)
|
458
|
+
end
|
459
|
+
|
445
460
|
def configure_and_generate_page(topic,branch_config,navigation)
|
446
461
|
distro = branch_config.distro
|
447
462
|
topic_adoc = File.open(topic.source_path,'r').read
|
@@ -451,7 +466,8 @@ module AsciiBinder
|
|
451
466
|
branch_config.distro.id,
|
452
467
|
"product-title=#{branch_config.distro_name}",
|
453
468
|
"product-version=#{branch_config.name}",
|
454
|
-
"product-author=#{branch_config.distro_author}"
|
469
|
+
"product-author=#{branch_config.distro_author}",
|
470
|
+
"repo_path=#{topic.repo_path}"
|
455
471
|
])
|
456
472
|
|
457
473
|
doc = Asciidoctor.load topic_adoc, :header_footer => false, :safe => :unsafe, :attributes => page_attrs
|
@@ -502,6 +518,7 @@ module AsciiBinder
|
|
502
518
|
:images_path => "../../#{dir_depth}#{branch_config.dir}/#{IMAGE_DIRNAME}/",
|
503
519
|
:site_home_path => "../../#{dir_depth}index.html",
|
504
520
|
:template_path => template_dir,
|
521
|
+
:repo_path => topic.repo_path,
|
505
522
|
}
|
506
523
|
full_file_text = page(page_args)
|
507
524
|
File.write(preview_path,full_file_text)
|
data/lib/ascii_binder/helpers.rb
CHANGED
@@ -10,6 +10,7 @@ module AsciiBinder
|
|
10
10
|
IMAGE_DIRNAME = '_images'
|
11
11
|
BLANK_STRING_RE = Regexp.new('^\s*$')
|
12
12
|
ID_STRING_RE = Regexp.new('^[A-Za-z0-9\-\_]+$')
|
13
|
+
URL_STRING_RE = Regexp.new('^https?:\/\/[\S]+$')
|
13
14
|
|
14
15
|
def valid_id?(check_id)
|
15
16
|
return false unless check_id.is_a?(String)
|
@@ -24,6 +25,12 @@ module AsciiBinder
|
|
24
25
|
return true
|
25
26
|
end
|
26
27
|
|
28
|
+
def valid_url?(check_string)
|
29
|
+
return false unless valid_string?(check_string)
|
30
|
+
return false unless check_string.match URL_STRING_RE
|
31
|
+
return true
|
32
|
+
end
|
33
|
+
|
27
34
|
def camelize(text)
|
28
35
|
text.gsub(/[^0-9a-zA-Z ]/i, '').split(' ').map{ |t| t.capitalize }.join
|
29
36
|
end
|
@@ -83,5 +90,9 @@ module AsciiBinder
|
|
83
90
|
def image_dir
|
84
91
|
@image_dir ||= File.join(docs_root_dir,IMAGE_DIRNAME)
|
85
92
|
end
|
93
|
+
|
94
|
+
def alias_text(target)
|
95
|
+
"<!DOCTYPE html><html><head><title>#{target}</title><link rel=\"canonical\" href=\"#{target}\"/><meta name=\"robots\" content=\"noindex\"><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" /><meta http-equiv=\"refresh\" content=\"0; url=#{target}\" /></head></html>"
|
96
|
+
end
|
86
97
|
end
|
87
98
|
end
|
@@ -5,7 +5,7 @@ include AsciiBinder::Helpers
|
|
5
5
|
|
6
6
|
module AsciiBinder
|
7
7
|
class TopicEntity
|
8
|
-
attr_reader :name, :dir, :file, :distro_keys, :subitems, :raw, :parent, :depth
|
8
|
+
attr_reader :name, :dir, :file, :topic_alias, :distro_keys, :subitems, :raw, :parent, :depth
|
9
9
|
|
10
10
|
def initialize(topic_entity,actual_distro_keys,dir_path='',parent_group=nil,depth=0)
|
11
11
|
@raw = topic_entity
|
@@ -14,9 +14,13 @@ module AsciiBinder
|
|
14
14
|
@name = topic_entity['Name']
|
15
15
|
@dir = topic_entity['Dir']
|
16
16
|
@file = topic_entity['File']
|
17
|
+
@topic_alias = topic_entity['Alias']
|
17
18
|
@depth = depth
|
18
19
|
@actual_distro_keys = actual_distro_keys
|
19
20
|
@distro_keys = topic_entity.has_key?('Distros') ? parse_distros(topic_entity['Distros']) : actual_distro_keys
|
21
|
+
@nav_trees = {}
|
22
|
+
@alias_lists = {}
|
23
|
+
@path_lists = {}
|
20
24
|
@subitems = []
|
21
25
|
if topic_entity.has_key?('Topics')
|
22
26
|
entity_dir = @dir.nil? ? '<nil_dir>' : @dir
|
@@ -33,12 +37,16 @@ module AsciiBinder
|
|
33
37
|
if is_group?
|
34
38
|
this_step = dir
|
35
39
|
elsif is_topic?
|
36
|
-
this_step =
|
40
|
+
this_step = file.end_with?('.adoc') ? file : "#{file}.adoc"
|
37
41
|
end
|
38
42
|
@dir_path == '' ? this_step : File.join(@dir_path,this_step)
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
46
|
+
def basename_path
|
47
|
+
@basename_path ||= File.join(File.dirname(repo_path),File.basename(repo_path,'.adoc'))
|
48
|
+
end
|
49
|
+
|
42
50
|
def repo_path_html
|
43
51
|
@repo_path_html ||= is_topic? ? File.join(File.dirname(repo_path),File.basename(repo_path,'.adoc')) + ".html" : repo_path
|
44
52
|
end
|
@@ -58,9 +66,9 @@ module AsciiBinder
|
|
58
66
|
def group_filepaths
|
59
67
|
@group_filepaths ||= begin
|
60
68
|
group_filepaths = []
|
61
|
-
if is_topic?
|
69
|
+
if is_topic? and not is_alias?
|
62
70
|
group_filepaths << File.join(File.dirname(repo_path),File.basename(repo_path,'.adoc'))
|
63
|
-
|
71
|
+
elsif is_group?
|
64
72
|
subitems.each do |subitem|
|
65
73
|
group_filepaths.concat(subitem.group_filepaths)
|
66
74
|
end
|
@@ -71,26 +79,67 @@ module AsciiBinder
|
|
71
79
|
end
|
72
80
|
|
73
81
|
def nav_tree(distro_key)
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
82
|
+
@nav_trees[distro_key] ||= begin
|
83
|
+
nav_tree = {}
|
84
|
+
if distro_keys.include?(distro_key) and not is_alias?
|
85
|
+
nav_tree[:id] = id
|
86
|
+
nav_tree[:name] = name
|
87
|
+
if is_topic?
|
88
|
+
nav_tree[:path] = "../" + repo_path_html
|
89
|
+
elsif is_group?
|
90
|
+
sub_nav_items = []
|
91
|
+
subitems.each do |subitem|
|
92
|
+
sub_nav = subitem.nav_tree(distro_key)
|
93
|
+
next if sub_nav.empty?
|
94
|
+
sub_nav_items << sub_nav
|
95
|
+
end
|
96
|
+
if sub_nav_items.empty?
|
97
|
+
nav_tree = {}
|
98
|
+
else
|
99
|
+
nav_tree[:topics] = sub_nav_items
|
100
|
+
end
|
101
|
+
end
|
86
102
|
end
|
103
|
+
nav_tree
|
104
|
+
end
|
105
|
+
end
|
87
106
|
|
88
|
-
|
89
|
-
|
107
|
+
def alias_list(distro_key)
|
108
|
+
@alias_lists[distro_key] ||= begin
|
109
|
+
sub_aliases = []
|
110
|
+
if distro_keys.include?(distro_key)
|
111
|
+
if is_group?
|
112
|
+
subitems.each do |subitem|
|
113
|
+
sub_list = subitem.alias_list(distro_key)
|
114
|
+
sub_list.each do |sub_list_alias|
|
115
|
+
sub_aliases << sub_list_alias
|
116
|
+
end
|
117
|
+
end
|
118
|
+
elsif is_alias?
|
119
|
+
sub_aliases << { :alias_path => basename_path, :redirect_path => topic_alias }
|
120
|
+
end
|
121
|
+
end
|
122
|
+
sub_aliases
|
123
|
+
end
|
124
|
+
end
|
90
125
|
|
91
|
-
|
126
|
+
def path_list(distro_key)
|
127
|
+
@path_lists[distro_key] ||= begin
|
128
|
+
sub_paths = []
|
129
|
+
if distro_keys.include?(distro_key)
|
130
|
+
if is_group?
|
131
|
+
subitems.each do |subitem|
|
132
|
+
sub_list = subitem.path_list(distro_key)
|
133
|
+
sub_list.each do |sub_list_path|
|
134
|
+
sub_paths << sub_list_path
|
135
|
+
end
|
136
|
+
end
|
137
|
+
elsif is_topic? and not is_alias?
|
138
|
+
sub_paths << basename_path
|
139
|
+
end
|
140
|
+
end
|
141
|
+
sub_paths
|
92
142
|
end
|
93
|
-
return nav_tree
|
94
143
|
end
|
95
144
|
|
96
145
|
# Is this topic entity or any of its children used in
|
@@ -140,6 +189,10 @@ module AsciiBinder
|
|
140
189
|
@is_topic ||= dir.nil? and not name.nil? and not file.nil? and subitems.length == 0
|
141
190
|
end
|
142
191
|
|
192
|
+
def is_alias?
|
193
|
+
@is_alias ||= is_topic? and not topic_alias.nil?
|
194
|
+
end
|
195
|
+
|
143
196
|
def is_valid?
|
144
197
|
validate
|
145
198
|
end
|
@@ -176,7 +229,7 @@ module AsciiBinder
|
|
176
229
|
distro_keys.each do |distro_key|
|
177
230
|
next if @actual_distro_keys.include?(distro_key)
|
178
231
|
if verbose
|
179
|
-
errors << "#{entity_id} 'Distros' filter includes
|
232
|
+
errors << "#{entity_id} 'Distros' filter includes nonexistent distro key '#{distro_key}'"
|
180
233
|
else
|
181
234
|
return false
|
182
235
|
end
|
@@ -204,6 +257,13 @@ module AsciiBinder
|
|
204
257
|
return false
|
205
258
|
end
|
206
259
|
end
|
260
|
+
if not topic_alias.nil?
|
261
|
+
if verbose
|
262
|
+
errors << "#{entity_id} is a topic group with an Alias entry. Aliases are only supported for topic items."
|
263
|
+
else
|
264
|
+
return false
|
265
|
+
end
|
266
|
+
end
|
207
267
|
subitems.each do |subitem|
|
208
268
|
next if subitem.is_valid?
|
209
269
|
if verbose
|
@@ -220,6 +280,15 @@ module AsciiBinder
|
|
220
280
|
return false
|
221
281
|
end
|
222
282
|
end
|
283
|
+
# We can do basic validation of the 'Alias' string here, but real validation has
|
284
|
+
# to be done after the whole topic map is loaded.
|
285
|
+
if not topic_alias.nil? and not valid_string?(topic_alias)
|
286
|
+
if verbose
|
287
|
+
errors << "#{entity_id} has invalid 'Alias' value."
|
288
|
+
else
|
289
|
+
return false
|
290
|
+
end
|
291
|
+
end
|
223
292
|
else
|
224
293
|
if verbose
|
225
294
|
errors << "#{entity_id} is not parseable as a group or a topic: '#{raw.inspect}'"
|
@@ -10,8 +10,9 @@ module AsciiBinder
|
|
10
10
|
attr_reader :list
|
11
11
|
|
12
12
|
def initialize(topic_file,distro_keys)
|
13
|
-
@topic_yaml
|
14
|
-
@
|
13
|
+
@topic_yaml = YAML.load_stream(open(File.join(docs_root_dir,topic_file)))
|
14
|
+
@distro_keys = distro_keys
|
15
|
+
@list = []
|
15
16
|
@topic_yaml.each do |topic_entity|
|
16
17
|
@list << AsciiBinder::TopicEntity.new(topic_entity,distro_keys)
|
17
18
|
end
|
@@ -31,17 +32,47 @@ module AsciiBinder
|
|
31
32
|
nav_tree = []
|
32
33
|
@list.each do |topic_entity|
|
33
34
|
entity_nav = topic_entity.nav_tree(distro_key)
|
34
|
-
next if entity_nav.
|
35
|
+
next if entity_nav.empty?
|
35
36
|
nav_tree << entity_nav
|
36
37
|
end
|
37
38
|
return nav_tree
|
38
39
|
end
|
39
40
|
|
41
|
+
def alias_list(distro_key)
|
42
|
+
alias_list = []
|
43
|
+
@list.each do |topic_entity|
|
44
|
+
alias_sublist = topic_entity.alias_list(distro_key)
|
45
|
+
next if alias_sublist.empty?
|
46
|
+
alias_list.push(*alias_sublist)
|
47
|
+
end
|
48
|
+
return alias_list
|
49
|
+
end
|
50
|
+
|
51
|
+
def path_list(distro_key)
|
52
|
+
path_list = []
|
53
|
+
@list.each do |topic_entity|
|
54
|
+
path_sublist = topic_entity.path_list(distro_key)
|
55
|
+
next if path_sublist.empty?
|
56
|
+
path_list.push(*path_sublist)
|
57
|
+
end
|
58
|
+
return path_list
|
59
|
+
end
|
60
|
+
|
40
61
|
def is_valid?
|
41
62
|
@list.each do |topic_entity|
|
42
63
|
next if topic_entity.is_valid? and topic_entity.is_group?
|
43
64
|
return false
|
44
65
|
end
|
66
|
+
# Test all aliases
|
67
|
+
@distro_keys.each do |distro_key|
|
68
|
+
distro_aliases = alias_list(distro_key)
|
69
|
+
distro_paths = path_list(distro_key)
|
70
|
+
distro_aliases.each do |alias_map|
|
71
|
+
return false if distro_paths.include?(alias_map[:alias_path])
|
72
|
+
next if valid_url?(alias_map[:redirect_path])
|
73
|
+
return false unless distro_paths.include?(alias_map[:redirect_path])
|
74
|
+
end
|
75
|
+
end
|
45
76
|
return true
|
46
77
|
end
|
47
78
|
|
@@ -55,7 +86,26 @@ module AsciiBinder
|
|
55
86
|
next if topic_entity.is_valid?
|
56
87
|
errors << topic_entity.errors
|
57
88
|
end
|
89
|
+
# Test all aliases
|
90
|
+
@distro_keys.each do |distro_key|
|
91
|
+
distro_aliases = alias_list(distro_key)
|
92
|
+
distro_paths = path_list(distro_key)
|
93
|
+
distro_aliases.each do |alias_map|
|
94
|
+
if distro_paths.include?(alias_map[:alias_path])
|
95
|
+
errors << "An actual topic file and a topic alias both exist at the same path '#{alias_map[:alias_path]}' for distro '#{distro_key}'"
|
96
|
+
end
|
97
|
+
next if valid_url?(alias_map[:redirect_path])
|
98
|
+
if not distro_paths.include?(alias_map[:redirect_path])
|
99
|
+
errors << "Topic alias '#{alias_map[:alias_path]}' points to a nonexistant topic '#{alias_map[:redirect_path]}' for distro '#{distro_key}'"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
58
103
|
return errors
|
59
104
|
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def validate_alias(topic_entity)
|
109
|
+
end
|
60
110
|
end
|
61
111
|
end
|
data/lib/ascii_binder/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ascii_binder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- N. Harrison Ripps
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-09-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -280,6 +280,7 @@ files:
|
|
280
280
|
- features/repo_package.feature
|
281
281
|
- features/step_definitions/steps.rb
|
282
282
|
- features/support/_clone_distro_map.yml
|
283
|
+
- features/support/_invalid_alias_topic_map.yml
|
283
284
|
- features/support/_invalid_distro_map.yml
|
284
285
|
- features/support/env.rb
|
285
286
|
- features/support/test_distro/.gitignore
|
@@ -299,6 +300,7 @@ files:
|
|
299
300
|
- features/support/test_distro/index-test.html
|
300
301
|
- features/support/test_distro/main_only_topic_group/index.adoc
|
301
302
|
- features/support/test_distro/test_only_topic_group/index.adoc
|
303
|
+
- features/support/test_distro/welcome/aliased.adoc
|
302
304
|
- features/support/test_distro/welcome/index.adoc
|
303
305
|
- features/support/test_distro/welcome/subtopics/index.adoc
|
304
306
|
- features/support/test_distro/welcome/subtopics/main_only_topic.adoc
|
@@ -357,7 +359,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
357
359
|
version: '0'
|
358
360
|
requirements: []
|
359
361
|
rubyforge_project:
|
360
|
-
rubygems_version: 2.6.
|
362
|
+
rubygems_version: 2.6.13
|
361
363
|
signing_key:
|
362
364
|
specification_version: 4
|
363
365
|
summary: AsciiBinder is an AsciiDoc-based system for authoring and publishing closely
|
@@ -372,6 +374,7 @@ test_files:
|
|
372
374
|
- features/repo_package.feature
|
373
375
|
- features/step_definitions/steps.rb
|
374
376
|
- features/support/_clone_distro_map.yml
|
377
|
+
- features/support/_invalid_alias_topic_map.yml
|
375
378
|
- features/support/_invalid_distro_map.yml
|
376
379
|
- features/support/env.rb
|
377
380
|
- features/support/test_distro/.gitignore
|
@@ -391,6 +394,7 @@ test_files:
|
|
391
394
|
- features/support/test_distro/index-test.html
|
392
395
|
- features/support/test_distro/main_only_topic_group/index.adoc
|
393
396
|
- features/support/test_distro/test_only_topic_group/index.adoc
|
397
|
+
- features/support/test_distro/welcome/aliased.adoc
|
394
398
|
- features/support/test_distro/welcome/index.adoc
|
395
399
|
- features/support/test_distro/welcome/subtopics/index.adoc
|
396
400
|
- features/support/test_distro/welcome/subtopics/main_only_topic.adoc
|