fronde 0.3.4 → 0.5.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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/bin/fronde +15 -30
  3. data/lib/ext/nil_time.rb +25 -0
  4. data/lib/ext/r18n.rb +37 -0
  5. data/lib/ext/time.rb +39 -0
  6. data/lib/ext/time_no_time.rb +23 -0
  7. data/lib/fronde/cli/commands.rb +97 -104
  8. data/lib/fronde/cli/data/Rakefile +8 -0
  9. data/lib/fronde/cli/data/config.yml +13 -0
  10. data/lib/fronde/cli/data/gitignore +6 -0
  11. data/lib/fronde/cli/data/zsh_completion +37 -0
  12. data/lib/fronde/cli/helpers.rb +55 -0
  13. data/lib/fronde/cli/opt_parse.rb +140 -0
  14. data/lib/fronde/cli/throbber.rb +110 -0
  15. data/lib/fronde/cli.rb +42 -42
  16. data/lib/fronde/config/data/org-config.el +25 -0
  17. data/lib/fronde/config/data/ox-fronde.el +158 -0
  18. data/lib/fronde/config/data/themes/umaneti/css/htmlize.css +364 -0
  19. data/lib/fronde/config/data/themes/umaneti/css/style.css +250 -0
  20. data/lib/fronde/config/data/themes/umaneti/img/bottom.png +0 -0
  21. data/lib/fronde/config/data/themes/umaneti/img/content.png +0 -0
  22. data/lib/fronde/config/data/themes/umaneti/img/tic.png +0 -0
  23. data/lib/fronde/config/data/themes/umaneti/img/top.png +0 -0
  24. data/lib/fronde/config/helpers.rb +62 -0
  25. data/lib/fronde/config/lisp.rb +80 -0
  26. data/lib/fronde/config.rb +148 -98
  27. data/lib/fronde/emacs.rb +23 -20
  28. data/lib/fronde/index/atom_generator.rb +55 -66
  29. data/lib/fronde/index/data/all_tags.org +19 -0
  30. data/lib/fronde/index/data/template.org +26 -0
  31. data/lib/fronde/index/data/template.xml +37 -0
  32. data/lib/fronde/index/org_generator.rb +72 -88
  33. data/lib/fronde/index.rb +57 -86
  34. data/lib/fronde/org/file.rb +299 -0
  35. data/lib/fronde/org/file_extracter.rb +101 -0
  36. data/lib/fronde/org.rb +105 -0
  37. data/lib/fronde/preview.rb +43 -39
  38. data/lib/fronde/slug.rb +54 -0
  39. data/lib/fronde/source/gemini.rb +34 -0
  40. data/lib/fronde/source/html.rb +67 -0
  41. data/lib/fronde/source.rb +209 -0
  42. data/lib/fronde/sync/neocities.rb +220 -0
  43. data/lib/fronde/sync/rsync.rb +46 -0
  44. data/lib/fronde/sync.rb +32 -0
  45. data/lib/fronde/templater.rb +101 -71
  46. data/lib/fronde/version.rb +1 -1
  47. data/lib/tasks/cli.rake +33 -0
  48. data/lib/tasks/org.rake +58 -43
  49. data/lib/tasks/site.rake +66 -31
  50. data/lib/tasks/sync.rake +37 -40
  51. data/lib/tasks/tags.rake +11 -7
  52. data/locales/en.yml +61 -14
  53. data/locales/fr.yml +69 -14
  54. metadata +77 -95
  55. data/lib/fronde/config/lisp_config.rb +0 -340
  56. data/lib/fronde/config/org-config.el +0 -19
  57. data/lib/fronde/config/ox-fronde.el +0 -121
  58. data/lib/fronde/org_file/class_methods.rb +0 -72
  59. data/lib/fronde/org_file/extracter.rb +0 -72
  60. data/lib/fronde/org_file/htmlizer.rb +0 -43
  61. data/lib/fronde/org_file.rb +0 -298
  62. data/lib/fronde/utils.rb +0 -229
@@ -2,117 +2,147 @@
2
2
 
3
3
  require 'nokogiri'
4
4
  require 'digest/md5'
5
- require 'fronde/org_file'
5
+ require_relative 'org/file'
6
6
 
7
7
  module Fronde
8
+ class NoHeadError < ::StandardError; end
9
+
8
10
  # Insert custom part inside generated HTML files.
9
11
  class Templater
10
- def initialize(source, dom, opts = {})
12
+ def initialize(source, dom, config = {})
11
13
  @dom = dom
12
14
  @org_file = source
13
- @position = opts['type'] || 'after'
14
- @content = extract_content opts
15
- @element = @dom.css(opts['selector'])
16
- digest = Digest::MD5.hexdigest(@content)
17
- @check_line = " Fronde Template: #{digest} "
15
+ @config = { 'type' => 'after' }.merge(config)
16
+ digest = Digest::MD5.hexdigest(config.to_s)
17
+ @config['check_line'] = " Fronde Template: #{digest} "
18
18
  end
19
19
 
20
20
  def apply
21
- flag_head
22
- content = @org_file.format(@content)
23
- @element.each do |e|
24
- insert_new_node_at e, content
21
+ # Flag the file for this template
22
+ head = @dom.xpath('//head').first
23
+ raise NoHeadError, self unless head
24
+
25
+ head.prepend_child("<!--#{@config['check_line']}-->")
26
+ content = @org_file.format extract_content
27
+ # Remove source element if necessary to avoid doubling it during
28
+ # the insert action
29
+ @config['source'].unlink if @config.has_key? 'source'
30
+ # Insert new content
31
+ @dom.css(@config['selector']).each do |element|
32
+ insert_new_node_at element, content
25
33
  end
26
34
  end
27
35
 
28
36
  def in_head?
29
- @dom.xpath('//head').children.to_a.filter(&:comment?).each do |c|
30
- return true if c.text == @check_line
37
+ @dom.xpath('//head').children.any? do |child|
38
+ next false unless child.comment?
39
+
40
+ child.text == @config['check_line']
41
+ end
42
+ end
43
+
44
+ def valid?(file_name)
45
+ return false unless @config.has_key?('selector')
46
+
47
+ unless @config.has_key?('content') || @config.has_key?('source')
48
+ return false
31
49
  end
32
- false
50
+
51
+ check_path(file_name)
33
52
  end
34
53
 
35
54
  class << self
36
- def customize_output(file_name, source = nil)
37
- templates_to_apply = filter_templates(file_name)
38
- return if templates_to_apply.empty?
39
- if source.nil?
40
- sourcepath = Fronde::OrgFile.source_for_target(file_name)
41
- source = Fronde::OrgFile.new(sourcepath)
42
- end
55
+ def customize_output(file_name)
56
+ source = Fronde::Org::File.new(file_name)
57
+ # Return if no org file found for this published file
58
+ return if source.file.end_with?(file_name)
59
+
43
60
  dom = open_dom(file_name)
44
- templates_to_apply.each do |t|
45
- tpl = Fronde::Templater.new(source, dom, t)
46
- next if tpl.in_head?
47
- tpl.apply
48
- end
49
- write_dom(file_name, dom)
61
+ updated = apply_templates(source, dom, file_name)
62
+ write_dom(file_name, dom) if updated
50
63
  end
51
64
 
52
65
  private
53
66
 
54
- def filter_templates(file_name)
55
- templates = Fronde::Config.get('templates')
56
- return [] if templates.nil? || templates.empty?
57
- templates.filter { |t| check_required_keys(t, file_name) }
67
+ def apply_templates(source, dom, file_name)
68
+ Fronde::CONFIG.get('templates', []).map do |config|
69
+ template = Fronde::Templater.new(source, dom, config)
70
+ next if !template.valid?(file_name) || template.in_head?
71
+
72
+ template.apply
73
+ true
74
+ rescue NoHeadError
75
+ warn R18n.t.fronde.error.templater.no_head_element(file: file_name)
76
+ next
77
+ end.any?
58
78
  end
59
79
 
60
80
  def open_dom(file_name)
61
- file = File.new file_name, 'r'
62
- dom = Nokogiri::HTML file
63
- file.close
64
- dom
81
+ File.open(file_name, 'r') do |file|
82
+ Nokogiri::HTML file
83
+ end
65
84
  end
66
85
 
67
86
  def write_dom(file_name, dom)
68
- file = File.new file_name, 'w'
69
- dom.write_to file
70
- file.close
71
- end
72
-
73
- def check_path(file_name, pathes)
74
- pub_folder = Fronde::Config.get('public_folder')
75
- if pathes.is_a?(Array)
76
- pathes.each do |tp|
77
- return true if File.fnmatch?("#{pub_folder}#{tp}",
78
- file_name, File::FNM_DOTMATCH)
79
- end
80
- return false
87
+ File.open(file_name, 'w') do |file|
88
+ dom.write_to file
81
89
  end
82
- File.fnmatch?("#{pub_folder}#{pathes}",
83
- file_name, File::FNM_DOTMATCH)
84
- end
85
-
86
- def check_required_keys(opts, file_name)
87
- return false unless opts.has_key?('selector')
88
- return false unless opts.has_key?('content') || opts.has_key?('source')
89
- return check_path(file_name, opts['path']) if opts.has_key?('path')
90
- true
91
90
  end
92
91
  end
93
92
 
94
93
  private
95
94
 
96
- def flag_head
97
- @dom.xpath('//head').first.prepend_child("<!--#{@check_line}-->\n")
98
- end
99
-
100
- def insert_new_node_at(elem, content)
101
- case @position
95
+ def insert_new_node_at(element, content)
96
+ case @config['type']
102
97
  when 'before'
103
- elem.add_previous_sibling content
98
+ element.add_previous_sibling content
104
99
  when 'replace'
105
- elem.replace content
100
+ element.replace content
106
101
  else
107
- elem.add_next_sibling content
102
+ element.add_next_sibling content
108
103
  end
109
104
  end
110
105
 
111
- def extract_content(opts)
112
- return opts['content'] if opts['content']
113
- # If we don't have a content option, then we must have a source
114
- # one.
115
- @dom.css(opts['source']).unlink.to_s
106
+ def warn_no_element(source)
107
+ pub_folder = Fronde::CONFIG.get('html_public_folder').sub(
108
+ /^#{Dir.pwd}/, '.'
109
+ )
110
+ warn(
111
+ R18n.t.fronde.error.templater.no_element_found(
112
+ source: source, file: "#{pub_folder}#{@org_file.pub_file}"
113
+ )
114
+ )
115
+ '' # Return empty string
116
+ end
117
+
118
+ def extract_content
119
+ # We must either have a source or a content key
120
+ source = @config.delete 'source'
121
+ unless source.is_a?(String) && source != ''
122
+ return @config['content'] || ''
123
+ end
124
+
125
+ node = @dom.css(source)
126
+ if node.any?
127
+ # Put it back in config
128
+ @config['source'] = node
129
+ return node.to_s
130
+ end
131
+
132
+ # Do nothing if we don’t have a reliable content to work with
133
+ warn_no_element source
134
+ end
135
+
136
+ def check_path(file_name)
137
+ paths = @config['path']
138
+ return true unless paths
139
+
140
+ paths = [paths] unless paths.is_a? Array
141
+
142
+ pub_folder = Fronde::CONFIG.get('html_public_folder')
143
+ paths.any? do |template_path|
144
+ File.fnmatch?("#{pub_folder}#{template_path}", file_name)
145
+ end
116
146
  end
117
147
  end
118
148
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Fronde
4
4
  # @return [String] the version number of the current Fronde release.
5
- VERSION = '0.3.4'
5
+ VERSION = '0.5.0'
6
6
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../fronde/cli/opt_parse'
4
+
5
+ namespace :cli do
6
+ desc 'Generate an autocomplete file for zsh'
7
+ task :zsh_complete do
8
+ data = {}
9
+ all_commands = Fronde::CLI::OptParse::FRONDE_COMMANDS
10
+ data['commands'] = all_commands.filter_map do |command, options|
11
+ next if options[:alias] || command == 'basic'
12
+
13
+ opts = (options[:opts] || []).map do |opt|
14
+ opt_config = Fronde::CLI::OptParse::FRONDE_OPTIONS[opt]
15
+ keyword = nil
16
+ unless opt_config[:boolean]
17
+ keyword = opt_config[:keyword] || opt_config[:long].upcase
18
+ end
19
+ { 'short' => opt,
20
+ 'long' => "--#{opt_config[:long]}",
21
+ 'keyword' => keyword }
22
+ end
23
+
24
+ translation = R18n.t.fronde.bin.commands[command].tr("'", '’')
25
+ { 'name' => command,
26
+ 'translation' => translation,
27
+ 'options' => opts }
28
+ end
29
+ source = File.expand_path '../fronde/cli/data/zsh_completion', __dir__
30
+ template = Liquid::Template.parse(File.read(source))
31
+ puts template.render(data)
32
+ end
33
+ end
data/lib/tasks/org.rake CHANGED
@@ -2,62 +2,56 @@
2
2
 
3
3
  require 'open-uri'
4
4
 
5
- # Fronde::Config is required by Fronde::Utils
6
- require 'fronde/utils'
5
+ require_relative '../fronde/config'
6
+ require_relative '../fronde/cli/throbber'
7
7
 
8
8
  require 'rake/clean'
9
9
 
10
10
  CLOBBER.push(
11
- 'var/tmp/org.tar.gz', 'var/tmp/last_org_version',
12
- 'var/lib/org-config.el', '.dir-locals.el', 'lib/htmlize.el'
11
+ 'var/lib/org-config.el', 'lib/htmlize.el'
13
12
  )
14
13
 
15
- def make_org_cmd(org_dir, target)
16
- make = ['make', '-C', org_dir, target]
17
- return make.join(' ') if verbose
18
- make.insert(3, '-s')
19
- make << 'EMACSQ="emacs -Q --eval \'(setq inhibit-message t)\'"'
20
- make.join(' ')
21
- end
22
-
23
14
  namespace :org do
24
15
  directory 'var/tmp'
25
16
 
26
17
  desc 'Download last version of Org'
27
18
  file 'var/tmp/org.tar.gz' => 'var/tmp' do
28
- download = Thread.new do
29
- Thread.current[:org_version] = Fronde::Config.org_last_version
30
- Fronde::Utils.download_org
31
- end
19
+ # Weird Rake issue, still executing the task even if the file exists
20
+ next if File.exist? 'var/tmp/org.tar.gz'
21
+
22
+ download = Thread.new { Fronde::Org.download }
32
23
  if verbose
33
- download.join
34
- warn "Org version #{download[:org_version]} has been downloaded"
24
+ warn R18n.t.fronde.tasks.org.downloaded(version: download.value)
35
25
  else
36
- Fronde::Utils.throbber(download, 'Downloading Org:')
26
+ Fronde::CLI::Throbber.run(download, R18n.t.fronde.tasks.org.downloading)
37
27
  end
28
+ rescue RuntimeError, Interrupt
29
+ warn R18n.t.fronde.tasks.org.no_download if verbose
38
30
  end
39
31
 
40
32
  desc 'Compile Org'
41
- task compile: 'var/tmp/org.tar.gz' do |task|
42
- org_version = Fronde::Config.org_last_version
33
+ multitask compile: ['var/tmp/org.tar.gz', 'lib'] do |task|
34
+ # No need to force fetch last version as it is only interesting as
35
+ # part of the upgrade task
36
+ org_version = Fronde::Org.last_version
37
+
43
38
  org_dir = "lib/org-#{org_version}"
44
39
  next if Dir.exist?("#{org_dir}/lisp")
40
+
45
41
  build = Thread.new do
46
- sh "tar -C lib -xzf #{task.prerequisites[0]}"
47
- mv "lib/org-mode-release_#{org_version}", org_dir
48
- sh make_org_cmd(org_dir, 'compile')
49
- sh make_org_cmd(org_dir, 'autoloads')
50
- Dir.glob('lib/org-[0-9.]*').each do |ov|
51
- next if ov == org_dir
52
- rm_r ov
53
- end
42
+ Fronde::Org.compile(
43
+ task.prerequisites[0], org_version, org_dir, verbose: verbose
44
+ )
45
+ Dir.glob('lib/org-[0-9.]*').each { rm_r _1 unless _1 == org_dir }
54
46
  end
55
47
  if verbose
56
48
  build.join
57
- warn "#{org_version} has been locally installed"
49
+ warn R18n.t.fronde.tasks.org.installed(version: org_version)
58
50
  else
59
- Fronde::Utils.throbber(build, 'Installing Org:')
51
+ Fronde::CLI::Throbber.run(build, R18n.t.fronde.tasks.org.installing)
60
52
  end
53
+ rescue RuntimeError, Interrupt
54
+ next
61
55
  end
62
56
 
63
57
  directory 'lib'
@@ -77,29 +71,50 @@ namespace :org do
77
71
  end
78
72
 
79
73
  file 'var/lib/org-config.el' => ['lib/htmlize.el', 'lib/ox-gmi.el'] do
80
- Fronde::Config.write_org_lisp_config
74
+ Fronde::CONFIG.write_org_lisp_config
81
75
  end
82
76
 
83
- file '.dir-locals.el' => 'var/lib/org-config.el' do
84
- Fronde::Config.write_dir_locals
77
+ file '.gitignore' do
78
+ next if File.exist? '.gitignore'
79
+
80
+ upstream = File.expand_path(
81
+ '../fronde/cli/data/gitignore', __dir__
82
+ )
83
+ cp upstream, '.gitignore'
85
84
  end
86
85
 
87
86
  desc 'Install Org'
88
- multitask install: ['org:compile', '.dir-locals.el'] do
89
- mkdir_p "#{Fronde::Config.get('public_folder')}/assets"
90
- Fronde::Config.sources.each do |s|
91
- mkdir_p s['path'] unless Dir.exist? s['path']
87
+ multitask install: ['org:compile', '.gitignore'] do
88
+ # lib/htmlize.el and lib/ox-gmi.el cannot be generated in parallel
89
+ # of org:compilation, as it will leads to a weird SSL error. Thus
90
+ # finishing file generation "manually" here.
91
+ Rake::Task['var/lib/org-config.el'].invoke
92
+ sources = Fronde::CONFIG.sources
93
+ sources.each { mkdir_p _1['path'] }
94
+
95
+ outputs = sources.map { _1['type'] }.uniq
96
+ if outputs.include?('html')
97
+ mkdir_p "#{Fronde::CONFIG.get('html_public_folder')}/assets"
98
+ end
99
+ if outputs.include?('gemini')
100
+ mkdir_p Fronde::CONFIG.get('gemini_public_folder')
92
101
  end
93
102
  end
94
103
 
95
- # The following task only run the clobber task (not provided by us)
96
- # and the org:install one, which is already tested. Thus, we can
97
- # safely remove it from coverage.
98
- # :nocov:
99
104
  desc 'Upgrade Org'
100
105
  task :upgrade do
101
106
  Rake::Task['clobber'].execute
107
+ if File.exist? 'var/tmp/org.tar.gz'
108
+ # Cleanup cached tarball only if a new version is available.
109
+ # Also cached the new remote org version in the same time.
110
+ org_version = Fronde::Org.current_version
111
+ begin
112
+ last_version = Fronde::Org.last_version(force: true)
113
+ rescue RuntimeError
114
+ last_version = org_version
115
+ end
116
+ File.unlink 'var/tmp/org.tar.gz' unless org_version == last_version
117
+ end
102
118
  Rake::Task['org:install'].invoke
103
119
  end
104
- # :nocov:
105
120
  end
data/lib/tasks/site.rake CHANGED
@@ -1,54 +1,89 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fronde/emacs'
4
- require 'fronde/index'
5
- require 'fronde/utils'
6
- require 'fronde/org_file'
7
- require 'fronde/templater'
3
+ require_relative '../fronde/emacs'
4
+ require_relative '../fronde/index'
5
+ require_relative '../fronde/templater'
6
+ require_relative '../fronde/cli/throbber'
8
7
 
9
8
  namespace :site do
10
- desc 'Generates all index files'
11
- task :index do
12
- index = Fronde::Index.new
13
- if verbose
14
- index.write_all
15
- next
9
+ desc 'Build all your projects'
10
+ task :build, [:force?] => ['var/lib/org-config.el'] do |_, args|
11
+ args.with_defaults(force?: false)
12
+ build_index = Thread.new do
13
+ all_index = Fronde::Index.all_blog_index
14
+ all_index.each do |index|
15
+ index.write_all_org(verbose: verbose)
16
+ end
17
+ Thread.current[:all_indexes] = all_index
16
18
  end
17
- build = Thread.new do
18
- index.write_all(verbose: false)
19
+ if verbose
20
+ build_index.join
21
+ else
22
+ Fronde::CLI::Throbber.run(
23
+ build_index, R18n.t.fronde.tasks.site.generating_indexes
24
+ )
19
25
  end
20
- Fronde::Utils.throbber(build, 'Generating indexes:')
21
- next if index.empty?
22
- Fronde::Config.write_org_lisp_config(with_tags: true)
23
- end
26
+ all_indexes = build_index[:all_indexes]
24
27
 
25
- desc 'Convert and customize all org files'
26
- task :build, [:force?] => ['var/lib/org-config.el', :index] do |_, args|
27
- args.with_defaults(:force? => false)
28
28
  build_html = Thread.new do
29
29
  rm_r 'var/tmp/timestamps', force: true if args[:force?]
30
30
  Fronde::Emacs.new(verbose: verbose).publish
31
31
  end
32
- begin
33
- Fronde::Utils.throbber(build_html, 'Building:')
34
- # :nocov:
35
- rescue RuntimeError
36
- warn 'Aborting'
37
- next
32
+ Fronde::CLI::Throbber.run(build_html, R18n.t.fronde.tasks.site.building)
33
+
34
+ if all_indexes.any?
35
+ if verbose
36
+ all_indexes.each(&:write_all_feeds)
37
+ else
38
+ publish_feed = Thread.new do
39
+ all_indexes.each do |index|
40
+ index.write_all_feeds(verbose: false)
41
+ end
42
+ end
43
+ Fronde::CLI::Throbber.run(
44
+ publish_feed, R18n.t.fronde.tasks.site.publishing_feeds
45
+ )
46
+ end
38
47
  end
39
- # :nocov:
48
+
49
+ next unless Fronde::CONFIG.sources.any? { |source| source.type == 'html' }
50
+
40
51
  customize_html = Thread.new do
41
- pubfolder = Fronde::Config.get('public_folder')
52
+ pubfolder = Fronde::CONFIG.get('html_public_folder')
42
53
  Dir["#{pubfolder}/**/*.html"].each do |f|
43
54
  Fronde::Templater.customize_output(f)
44
55
  end
45
56
  end
46
- Fronde::Utils.throbber(customize_html, 'Customizing:')
57
+ Fronde::CLI::Throbber.run(
58
+ customize_html, R18n.t.fronde.tasks.site.customizing
59
+ )
60
+ # :nocov:
61
+ rescue RuntimeError, Interrupt
62
+ warn R18n.t.fronde.tasks.site.aborting
63
+ next
64
+ # :nocov:
65
+ end
66
+
67
+ desc 'Cleanup orphaned published files'
68
+ task :clean do
69
+ pubfolder = Fronde::CONFIG.get('html_public_folder')
70
+ Dir["#{pubfolder}/**/*.html"].each do |file_name|
71
+ source = Fronde::Org::File.new(file_name)
72
+
73
+ # Return if an org file has been found for this published file
74
+ next unless source.file == file_name
75
+
76
+ print R18n.t.fronde.tasks.site.remove_orphan_file
77
+ action = $stdin.gets.strip.downcase
78
+ next unless action == 'y'
79
+
80
+ rm file_name
81
+ end
47
82
  end
48
83
 
49
84
  desc 'Start a test server'
50
85
  task :preview do
51
- require 'fronde/preview'
52
- Fronde.start_preview
86
+ require_relative '../fronde/preview'
87
+ Fronde::Preview.start
53
88
  end
54
89
  end
data/lib/tasks/sync.rake CHANGED
@@ -1,56 +1,53 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fronde/config'
4
- require 'fronde/utils'
3
+ require_relative '../fronde/config'
4
+ require_relative '../fronde/sync'
5
+ require_relative '../fronde/cli/throbber'
5
6
 
6
- module Fronde
7
- class SyncError < Error; end
8
- end
9
-
10
- def rsync_command(test = nil)
11
- rsync_command = Fronde::Config.get('rsync')
12
- return rsync_command unless rsync_command.nil?
13
- optstring = []
14
- optstring << 'n' if test
15
- if verbose
16
- optstring << 'v'
17
- else
18
- optstring << 'q'
19
- end
20
- "rsync -#{optstring.join}rlt --delete"
21
- end
22
-
23
- def pull_or_push(direction, label, test)
24
- unless [:pull, :push].include? direction
25
- raise Fronde::SyncError, 'Not a valid direction'
26
- end
27
- remote_path = Fronde::Config.get('remote')
28
- raise Fronde::SyncError, 'No remote path set' if remote_path.nil?
29
- public_folder = Fronde::Config.get('public_folder')
30
- # Default is to push
31
- cmd = ["#{public_folder}/", remote_path]
32
- cmd.reverse! if direction == :pull
33
- rsync = rsync_command(test)
34
- publish_thread = Thread.new do
35
- sh "#{rsync} #{cmd.join(' ')}"
36
- end
37
- Fronde::Utils.throbber(publish_thread, label)
7
+ def source_types
8
+ Fronde::CONFIG.sources.map(&:type).uniq
38
9
  end
39
10
 
40
11
  namespace :sync do
41
12
  desc 'Push changes to server'
42
13
  task :push, :test? do |_, args|
43
- pull_or_push(:push, 'Publishing:', args[:test?])
44
- rescue Fronde::SyncError => e
45
- warn e
14
+ source_types.each do |type|
15
+ publish_thread = Fronde::Sync.pull_or_push(
16
+ :push, type, test: args[:test?], verbose: verbose
17
+ )
18
+ if verbose
19
+ publish_thread.join
20
+ else
21
+ Fronde::CLI::Throbber.run(
22
+ publish_thread, format('Publishing %<fmt>s:', fmt: type)
23
+ )
24
+ end
25
+ rescue Fronde::Sync::Error => e
26
+ warn e
27
+ next
28
+ end
29
+ rescue RuntimeError, Interrupt
46
30
  next
47
31
  end
48
32
 
49
33
  desc 'Pull changes from server'
50
34
  task :pull, :test? do |_, args|
51
- pull_or_push(:pull, 'Pulling:', args[:test?])
52
- rescue Fronde::SyncError => e
53
- warn e
35
+ source_types.each do |type|
36
+ pull_thread = Fronde::Sync.pull_or_push(
37
+ :pull, type, test: args[:test?], verbose: verbose
38
+ )
39
+ if verbose
40
+ pull_thread.join
41
+ else
42
+ Fronde::CLI::Throbber.run(
43
+ pull_thread, format('Pulling %<fmt>s:', fmt: type)
44
+ )
45
+ end
46
+ rescue Fronde::Sync::Error => e
47
+ warn e
48
+ next
49
+ end
50
+ rescue RuntimeError, Interrupt
54
51
  next
55
52
  end
56
53
  end
data/lib/tasks/tags.rake CHANGED
@@ -1,19 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fronde/index'
3
+ require_relative '../fronde/index'
4
4
 
5
5
  namespace :tags do
6
6
  desc 'List all tags by name'
7
7
  task :name do
8
- index = Fronde::Index.new
9
- next if index.empty?
10
- puts index.sort_by(:name).join("\n")
8
+ Fronde::Index.all_blog_index do |index|
9
+ next if index.empty?
10
+
11
+ puts index.sort_by(:name).join("\n")
12
+ end
11
13
  end
12
14
 
13
15
  desc 'List all tags by weight'
14
16
  task :weight do
15
- index = Fronde::Index.new
16
- next if index.empty?
17
- puts index.sort_by(:weight).join("\n")
17
+ Fronde::Index.all_blog_index do |index|
18
+ next if index.empty?
19
+
20
+ puts index.sort_by(:weight).join("\n")
21
+ end
18
22
  end
19
23
  end