fronde 0.3.2 → 0.3.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 160fe641b74b790fc6446fa97854ebc9aba8dcd4aef50d7651510c8f6b92d63f
4
- data.tar.gz: aefb09d2cd99c6b10d9e281934799e4821023da5404ff09fb1558b9632c22649
3
+ metadata.gz: '09c19f62dc0488af47253babe5508d3542a32641cd37ad4d48db18bcc9e99e41'
4
+ data.tar.gz: abed078181d7348c50706e6221e0820753a336d1ba23b0248e6ec588a8b43d07
5
5
  SHA512:
6
- metadata.gz: 2c68e67d4adadd0f06a21526f1a6f5b13d8d9e7eabfe67861eff3823c8283da9cba88b728aa7fa00178d45ed81479bc124e2cc727f051b33cec3cf57dc94d448
7
- data.tar.gz: 6f9325d21dd7491e0c83c6d12a03b7b0d755dd9afebf5dc241ec6a40f40e2b5c8c93648d0da9c4020d0d30d4adb74a2eb6b8db580223b3844a6fd622b3a50184
6
+ metadata.gz: 87d05d4afddff426c8093bfe210d4b33744493ebc4a095aef6c0127c072f013550d6169b8573b36916e3f2f286a023b47ee644ba8cc105ed25d73ee71bd7f1ed
7
+ data.tar.gz: f22641978e2b3b2416dfc36af56f914a345869b029e972ebc881dfa085ab9fe5bd8435174954fe5772d6a0e822ea51ec9a5f2c3759a27503f8fdb2730672eeed
data/bin/fronde CHANGED
@@ -8,7 +8,7 @@ require 'fronde/version'
8
8
  require 'fronde/cli'
9
9
 
10
10
  R18n.default_places = File.expand_path('../locales', __dir__)
11
- R18n.set Fronde::Config.settings['lang']
11
+ R18n.set Fronde::Config.get('lang')
12
12
 
13
13
  optparser = OptionParser.new
14
14
  optparser.version = Fronde::VERSION
@@ -38,7 +38,7 @@ if params[:help] || cmd_err
38
38
  end
39
39
  ARGV.shift
40
40
 
41
- init_cmds = [:fronde_init, :fronde_config]
41
+ init_cmds = [:fronde_init, :fronde_config, :fronde_update]
42
42
  unless File.exist?('config.yml') || init_cmds.include?(command)
43
43
  fronde.fronde_init
44
44
  end
@@ -3,18 +3,21 @@
3
3
  module Fronde
4
4
  # Fronde commands
5
5
  module CLICommands
6
+ def fronde_update
7
+ update_config
8
+ @rake.options.build_all = true
9
+ @rake.invoke_task('org:upgrade')
10
+ end
11
+ alias_method :fronde_config, :fronde_update
12
+
6
13
  def fronde_init
7
- cnf = @options.merge
8
- cnf.delete(:verbose)
9
- cnf.transform_keys!(&:to_s)
10
- Fronde::Config.save(Fronde::Config.settings.merge(cnf))
14
+ update_config
11
15
  @rake.options.build_all = true
12
16
  @rake.invoke_task('org:install')
13
17
  return if File.exist? 'src/index.org'
14
18
  Fronde::OrgFile.new('src/index.org', @options).write
15
19
  fronde_open 'src/index.org'
16
20
  end
17
- alias_method :fronde_config, :fronde_init
18
21
 
19
22
  def fronde_build
20
23
  @rake.options.build_all = true
@@ -26,7 +29,7 @@ module Fronde
26
29
  def fronde_preview
27
30
  Thread.new do
28
31
  sleep 1
29
- port = Fronde::Config.settings.dig('preview', 'server_port') || 5000
32
+ port = Fronde::Config.get(['preview', 'server_port'], 5000)
30
33
  uri = "http://127.0.0.1:#{port}/"
31
34
  current_os = Fronde::Utils.current_os
32
35
  case current_os
@@ -62,10 +65,10 @@ module Fronde
62
65
 
63
66
  def fronde_help(command = 'basic', error: false)
64
67
  warn R18n.t.fronde.bin.error.no_command if error
65
- cmd = Fronde::Utils.resolve_possible_alias(command)
66
- cmd_opt = Fronde::Utils::FRONDE_COMMANDS[cmd]
68
+ cmd_opt = Fronde::Utils.command_options(command)
67
69
  label = cmd_opt[:label] || command
68
70
  warn format("%<label>s\n\n", label: R18n.t.fronde.bin.usage(label))
71
+ cmd = cmd_opt[:name] || command
69
72
  if R18n.t.fronde.bin.commands[cmd].translated?
70
73
  warn format("%<label>s\n\n", label: R18n.t.fronde.bin.commands[cmd])
71
74
  end
@@ -76,6 +79,13 @@ module Fronde
76
79
 
77
80
  private
78
81
 
82
+ def update_config
83
+ cnf = @options.merge
84
+ cnf.delete(:verbose)
85
+ cnf.transform_keys!(&:to_s)
86
+ Fronde::Config.save(Fronde::Config.settings.merge(cnf))
87
+ end
88
+
79
89
  def new_file_name(file_path)
80
90
  file_path = File.expand_path(file_path || '')
81
91
  return file_path if file_path[-4..] == '.org'
data/lib/fronde/cli.rb CHANGED
@@ -36,14 +36,14 @@ module Fronde
36
36
 
37
37
  fronde_spec = Gem::Specification.find_by_name 'fronde'
38
38
  R18n.default_places = "\#{fronde_spec.gem_dir}/locales"
39
- R18n.set(Fronde::Config.settings['lang'] || 'en')
39
+ R18n.set(Fronde::Config.get('lang', 'en'))
40
40
  R18n::Filters.on(:named_variables)
41
41
 
42
42
  Dir.glob("\#{fronde_spec.gem_dir}/lib/tasks/*.rake").each { |r| import r }
43
43
 
44
44
  task default: 'site:build'
45
45
  RAKE
46
- IO.write 'Rakefile', rakefile
46
+ File.write 'Rakefile', rakefile
47
47
  end
48
48
 
49
49
  def init_gitignore
@@ -54,7 +54,7 @@ module Fronde
54
54
  public_html
55
55
  var
56
56
  GITIGNORE
57
- IO.write '.gitignore', gitignore
57
+ File.write '.gitignore', gitignore
58
58
  end
59
59
  end
60
60
  end
@@ -4,6 +4,20 @@ require 'json'
4
4
  require 'open-uri'
5
5
  require 'fronde/version'
6
6
 
7
+ def fetch_org_version
8
+ # Retrieve last org version from git repository tags page.
9
+ tag_rx = Regexp.new(
10
+ '<a href=\'/cgit/emacs/org-mode.git/tag/\?h=' \
11
+ '(?<tag>release_(?<number>[^\']+))\'>\k<tag></a>'
12
+ )
13
+ versions = URI(
14
+ 'https://git.savannah.gnu.org/cgit/emacs/org-mode.git/refs/'
15
+ ).open.readlines.map do |line|
16
+ line.match(tag_rx) { |matchdata| matchdata[:number] }
17
+ end
18
+ versions.compact.first
19
+ end
20
+
7
21
  module Fronde
8
22
  # This module contains utilitary methods to ease ~org-config.el~
9
23
  # file generation
@@ -14,15 +28,12 @@ module Fronde
14
28
  def org_last_version
15
29
  return @org_version if @org_version
16
30
  if File.exist?('var/tmp/last_org_version')
17
- @org_version = IO.read('var/tmp/last_org_version')
31
+ @org_version = File.read('var/tmp/last_org_version')
18
32
  return @org_version
19
33
  end
20
- versions = JSON.parse(
21
- URI('https://updates.orgmode.org/data/releases').open.read
22
- ).sort { |a, b| b['date'] <=> a['date'] }
23
- @org_version = versions.first['version']
34
+ @org_version = fetch_org_version
24
35
  FileUtils.mkdir_p 'var/tmp'
25
- IO.write('var/tmp/last_org_version', @org_version)
36
+ File.write('var/tmp/last_org_version', @org_version)
26
37
  @org_version
27
38
  end
28
39
 
@@ -33,24 +44,29 @@ module Fronde
33
44
  # existed already.
34
45
  #
35
46
  # @return [Integer] the length written (as returned by the
36
- # underlying ~IO.write~ method call)
47
+ # underlying ~File.write~ method call)
48
+ # rubocop:disable Metrics/MethodLength
37
49
  def write_org_lisp_config(with_tags: false)
38
50
  projects = org_generate_projects(with_tags: with_tags)
39
51
  workdir = Dir.pwd
40
- content = IO.read(File.expand_path('./org-config.el', __dir__))
41
- .gsub('__VERSION__', Fronde::VERSION)
42
- .gsub('__WORK_DIR__', workdir)
43
- .gsub('__FRONDE_DIR__', __dir__)
44
- .gsub('__ORG_VER__', org_last_version)
45
- .gsub('__ALL_PROJECTS__', projects.values.join("\n "))
46
- .gsub('__THEME_CONFIG__', org_default_theme_config)
47
- .gsub('__ALL_PROJECTS_NAMES__', project_names(projects))
48
- .gsub('__LONG_DATE_FMT__', r18n_full_datetime_format)
49
- .gsub('__AUTHOR_EMAIL__', settings['author_email'] || '')
50
- .gsub('__AUTHOR_NAME__', settings['author'])
52
+ content = File.read(File.expand_path('./org-config.el', __dir__))
53
+ .gsub('__VERSION__', Fronde::VERSION)
54
+ .gsub('__WORK_DIR__', workdir)
55
+ .gsub('__FRONDE_DIR__', __dir__)
56
+ .gsub('__ORG_VER__', org_last_version)
57
+ .gsub(
58
+ '__ALL_PROJECTS__',
59
+ projects.values.join("\n ")
60
+ )
61
+ .gsub('__THEME_CONFIG__', org_default_theme_config)
62
+ .gsub('__ALL_PROJECTS_NAMES__', project_names(projects))
63
+ .gsub('__LONG_DATE_FMT__', r18n_full_datetime_format)
64
+ .gsub('__AUTHOR_EMAIL__', get('author_email', ''))
65
+ .gsub('__AUTHOR_NAME__', get('author'))
51
66
  FileUtils.mkdir_p "#{workdir}/var/lib"
52
- IO.write("#{workdir}/var/lib/org-config.el", content)
67
+ File.write("#{workdir}/var/lib/org-config.el", content)
53
68
  end
69
+ # rubocop:enable Metrics/MethodLength
54
70
 
55
71
  # Generate emacs directory variables file.
56
72
  #
@@ -59,11 +75,11 @@ module Fronde
59
75
  # of this fronde instance.
60
76
  #
61
77
  # @return [Integer] the length written (as returned by the
62
- # underlying ~IO.write~ method call)
78
+ # underlying ~File.write~ method call)
63
79
  def write_dir_locals
64
80
  workdir = Dir.pwd
65
81
  # rubocop:disable Layout/LineLength
66
- IO.write(
82
+ File.write(
67
83
  "#{workdir}/.dir-locals.el",
68
84
  "((org-mode . ((eval . (load-file \"#{workdir}/var/lib/org-config.el\")))))"
69
85
  )
@@ -93,12 +109,10 @@ module Fronde
93
109
  names = projects.keys.map do |p|
94
110
  ["\"#{p}\"", "\"#{p}-assets\""]
95
111
  end.flatten
96
- unless settings['theme'] == 'default'
97
- names << "\"theme-#{settings['theme']}\""
98
- end
112
+ names << "\"theme-#{get('theme')}\"" unless get('theme') == 'default'
99
113
  sources.each do |s|
100
114
  # Default theme defined in settings is already included
101
- next unless s['theme'] && s['theme'] != settings['theme']
115
+ next unless s['theme'] && s['theme'] != get('theme')
102
116
  # Never include theme named 'default' as it does not rely on any
103
117
  # file to export.
104
118
  next if s['theme'] == 'default'
@@ -118,9 +132,9 @@ module Fronde
118
132
  def publication_path(project)
119
133
  publish_in = [Dir.pwd]
120
134
  if project['type'] == 'gemini'
121
- publish_in << (settings['gemini_public_folder'] || 'public_gmi')
135
+ publish_in << get('gemini_public_folder', 'public_gmi')
122
136
  else
123
- publish_in << settings['public_folder']
137
+ publish_in << get('public_folder')
124
138
  end
125
139
  publish_in << project['target'] unless project['target'] == '.'
126
140
  publish_in.join('/')
@@ -187,7 +201,7 @@ module Fronde
187
201
  'html-head-include-default-style' => 't',
188
202
  'html-head-include-scripts' => 't'
189
203
  }
190
- curtheme = project['theme'] || settings['theme']
204
+ curtheme = project['theme'] || get('theme')
191
205
  return defaults if curtheme.nil? || curtheme == 'default'
192
206
  defaults['html-head'] = org_default_html_head
193
207
  defaults['html-head-include-default-style'] = 'nil'
@@ -205,7 +219,7 @@ module Fronde
205
219
  else
206
220
  defaults.merge!(
207
221
  org_default_html_options(project),
208
- settings['org-html'] || {},
222
+ get('org-html', {}),
209
223
  project['org-html'] || {}
210
224
  )
211
225
  end
@@ -213,14 +227,14 @@ module Fronde
213
227
  end
214
228
 
215
229
  def expand_vars_in_html_head(head, project)
216
- curtheme = project['theme'] || settings['theme']
230
+ curtheme = project['theme'] || get('theme')
217
231
  # Head may be frozen when coming from settings
218
232
  head = head.gsub('__THEME__', curtheme)
219
- .gsub('__DOMAIN__', settings['domain'])
233
+ .gsub('__DOMAIN__', get('domain'))
220
234
  return head.gsub('__ATOM_FEED__', '') unless project['is_blog']
221
235
  atomfeed = <<~ATOMFEED
222
236
  <link rel="alternate" type="application/atom+xml" title="Atom 1.0"
223
- href="#{settings['domain']}/feeds/index.xml" />
237
+ href="#{get('domain')}/feeds/index.xml" />
224
238
  ATOMFEED
225
239
  head.gsub('__ATOM_FEED__', atomfeed)
226
240
  end
@@ -261,7 +275,7 @@ module Fronde
261
275
  end
262
276
 
263
277
  def org_default_theme_config
264
- theme_config = org_theme_config(settings['theme'])
278
+ theme_config = org_theme_config(get('theme'))
265
279
  return theme_config if theme_config == ''
266
280
  format("\n %<conf>s", conf: theme_config)
267
281
  end
@@ -278,7 +292,7 @@ module Fronde
278
292
  # rubocop:enable Layout/LineLength
279
293
  ' :recursive t',
280
294
  format(' :publishing-directory "%<wd>s/%<pub>s/assets/%<theme>s"',
281
- wd: workdir, pub: settings['public_folder'], theme: theme),
295
+ wd: workdir, pub: get('public_folder'), theme: theme),
282
296
  ' :publishing-function org-publish-attachment)'
283
297
  ].join("\n ").strip
284
298
  end
data/lib/fronde/config.rb CHANGED
@@ -24,7 +24,7 @@ module Fronde
24
24
  # Settings will be available like this:
25
25
  #
26
26
  # #+begin_src
27
- # Fronde::Config.settings['author']
27
+ # Fronde::Config.get('author')
28
28
  # => "Alice Doe"
29
29
  # #+end_src
30
30
  class Config
@@ -33,15 +33,38 @@ module Fronde
33
33
  class << self
34
34
  # Access the current website settings
35
35
  #
36
- # If the settings have not been loaded yet, this method is
37
- # responsible for calling the one, which actually loads them.
36
+ # If necessary, this method will load settings from a config
37
+ # file.
38
38
  #
39
39
  # @return [Hash] the website settings
40
40
  def settings
41
- return load_settings unless @config
41
+ load_settings
42
42
  @config
43
43
  end
44
44
 
45
+ # Return a named setting.
46
+ #
47
+ # ~setting~ may be a ~String~ or an ~Array~.
48
+ #
49
+ # If the given ~setting~ name is an Array, this method will
50
+ # behave as ~Hash::dig~.
51
+ #
52
+ # If no value is found for the given setting, ~default~ will be
53
+ # returned.
54
+ #
55
+ # @param setting [String, Array] the setting to get
56
+ # @param default the default value to use if ~setting~ is absent
57
+ # @return the setting value or nil
58
+ def get(setting, default = nil)
59
+ load_settings
60
+ if setting.is_a? Array
61
+ value = @config.dig(*setting)
62
+ else
63
+ value = @config[setting]
64
+ end
65
+ value || default
66
+ end
67
+
45
68
  # Save the settings given as a parameter to the ~config.yml~ file.
46
69
  #
47
70
  # Not only this method overwrite the old settings, but it replace
@@ -58,25 +81,42 @@ module Fronde
58
81
  # which may be different from a system to another. Thus it may
59
82
  # be confusing if one use fronde on two different computer and
60
83
  # these params always change.
84
+ default_keys = default_settings.keys
61
85
  new_config.delete_if do |k, v|
62
- ['domain', 'public_folder', 'templates', 'theme'].include?(k) \
63
- && v == default_settings[k]
86
+ default_keys.include?(k) && v == default_settings[k]
64
87
  end
65
- IO.write 'config.yml', new_config.to_yaml
88
+ File.write 'config.yml', new_config.to_yaml
89
+ @config = @sources = nil
66
90
  load_settings # Reload config, taking default settings into account
67
91
  end
68
92
 
93
+ # Reset settings
94
+ #
95
+ # This method is handy for testing purpose. Next call to
96
+ # {file:Fronde/Config.html#get-class_method get} or
97
+ # {file:Fronde/Config.html#settings-class_method settings} will
98
+ # force reload the settings from the config file
99
+ #
100
+ # @return nil
101
+ def reset
102
+ @sources = @config = nil
103
+ end
104
+
69
105
  # Load the given settings as if they comes from the ~config.yml~ file.
70
106
  #
71
- # This method is handy for testing purpose. Later call to
107
+ # This method is handy for testing purpose. Next call to
108
+ # {file:Fronde/Config.html#get-class_method get},
109
+ # {file:Fronde/Config.html#sources-class_method sources} or
72
110
  # {file:Fronde/Config.html#settings-class_method settings} will
73
111
  # use these new settings.
74
112
  #
75
113
  # @param config [Hash] the settings to artificially load
76
114
  # @return [Hash] the new settings
77
115
  def load_test(config)
78
- @sources = nil # Reset sources
116
+ reset
79
117
  @config = default_settings.merge config
118
+ sources
119
+ @config
80
120
  end
81
121
 
82
122
  # Return the qualified projects sources list.
@@ -84,8 +124,9 @@ module Fronde
84
124
  # @return [Array] the fully qualified projects sources list
85
125
  def sources
86
126
  return @sources if @sources
127
+ load_settings
87
128
  default_sources = [{ 'path' => 'src', 'target' => '.' }]
88
- @sources = (settings['sources'] || default_sources).map do |s|
129
+ @sources = get('sources', default_sources).map do |s|
89
130
  build_source(s)
90
131
  end.compact
91
132
  end
@@ -93,7 +134,7 @@ module Fronde
93
134
  private
94
135
 
95
136
  def load_settings
96
- @sources = nil
137
+ return @config if @config
97
138
  conf_file = 'config.yml'
98
139
  if File.exist? conf_file
99
140
  @config = default_settings.merge(YAML.load_file(conf_file)).freeze
data/lib/fronde/emacs.rb CHANGED
@@ -24,7 +24,7 @@ module Fronde
24
24
  private
25
25
 
26
26
  def emacs_command(*arguments)
27
- default_emacs = Fronde::Config.settings['emacs']
27
+ default_emacs = Fronde::Config.get('emacs')
28
28
  emacs_cmd = [
29
29
  default_emacs || 'emacs -Q --batch -nw',
30
30
  '--eval \'(setq enable-dir-local-variables nil)\''
@@ -19,7 +19,7 @@ module Fronde
19
19
  slug = Fronde::OrgFile.slug index_name
20
20
  FileUtils.mkdir_p "#{@pubdir}/feeds"
21
21
  atomdest = "#{@pubdir}/feeds/#{slug}.xml"
22
- IO.write(atomdest, to_atom(index_name))
22
+ File.write(atomdest, to_atom(index_name))
23
23
  end
24
24
 
25
25
  private
@@ -29,13 +29,12 @@ module Fronde
29
29
  # @param title [String] the title of the current atom feed
30
30
  # @return [String] the Atom header as a String
31
31
  def atom_header(title)
32
- domain = Fronde::Config.settings['domain']
32
+ domain = Fronde::Config.get('domain')
33
33
  upddate = @date.rfc3339
34
34
  if title == 'index'
35
35
  slug = 'index'
36
36
  tagurl = domain
37
- title = Fronde::Config.settings['title'] || \
38
- R18n.t.fronde.index.all_tags
37
+ title = Fronde::Config.get('title', R18n.t.fronde.index.all_tags)
39
38
  else
40
39
  slug = Fronde::OrgFile.slug(title)
41
40
  tagurl = "#{domain}/tags/#{slug}.html"
@@ -47,13 +46,13 @@ module Fronde
47
46
  <feed xmlns="http://www.w3.org/2005/Atom"
48
47
  xmlns:dc="http://purl.org/dc/elements/1.1/"
49
48
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
50
- xml:lang="#{Fronde::Config.settings['lang']}">
49
+ xml:lang="#{Fronde::Config.get('lang')}">
51
50
 
52
51
  <title>#{title}</title>
53
52
  <link href="#{domain}/feeds/#{slug}.xml" rel="self" type="application/atom+xml"/>
54
53
  <link href="#{tagurl}" rel="alternate" type="text/html" title="#{title}"/>
55
54
  <updated>#{upddate}</updated>
56
- <author><name>#{Fronde::Config.settings['author'] || ''}</name></author>
55
+ <author><name>#{Fronde::Config.get('author', '')}</name></author>
57
56
  <id>urn:md5:#{Digest::MD5.hexdigest(domain)}</id>
58
57
  <generator uri="https://git.umaneti.net/fronde/about/">Fronde</generator>
59
58
  ENDATOM
@@ -18,7 +18,7 @@ module Fronde
18
18
  FileUtils.mkdir 'tags' unless Dir.exist? 'tags'
19
19
  content = to_org index_name
20
20
  orgdest = "tags/#{slug}.org"
21
- IO.write(orgdest, content)
21
+ File.write(orgdest, content)
22
22
  end
23
23
 
24
24
  private
@@ -37,7 +37,7 @@ module Fronde
37
37
  next unless Dir.exist?(project['path'])
38
38
  warn "Generated blog home for #{project['name']}" if verbose
39
39
  orgdest = format('%<root>s/index.org', root: project['path'])
40
- IO.write(orgdest, to_org(project['name'], is_project: true))
40
+ File.write(orgdest, to_org(project['name'], is_project: true))
41
41
  end
42
42
  end
43
43
 
@@ -57,7 +57,7 @@ module Fronde
57
57
  end
58
58
 
59
59
  def tag_published_url(tag_name)
60
- domain = Fronde::Config.settings['domain']
60
+ domain = Fronde::Config.get('domain')
61
61
  title = @tags_names[tag_name]
62
62
  tag_link = "#{domain}/tags/#{tag_name}.html"
63
63
  "[[#{tag_link}][#{title}]]"
@@ -67,12 +67,12 @@ module Fronde
67
67
  if is_tag
68
68
  title = @tags_names[title]
69
69
  elsif title.nil? || title == 'index'
70
- title = Fronde::Config.settings['title']
70
+ title = Fronde::Config.get('title')
71
71
  end
72
72
  <<~HEADER.strip
73
73
  #+title: #{title}
74
- #+author: #{Fronde::Config.settings['author']}
75
- #+language: #{Fronde::Config.settings['lang']}
74
+ #+author: #{Fronde::Config.get('author')}
75
+ #+language: #{Fronde::Config.get('lang')}
76
76
  HEADER
77
77
  end
78
78
 
data/lib/fronde/index.rb CHANGED
@@ -17,7 +17,7 @@ module Fronde
17
17
  include Fronde::IndexOrgGenerator
18
18
 
19
19
  def initialize
20
- @pubdir = Fronde::Config.settings['public_folder']
20
+ @pubdir = Fronde::Config.get('public_folder')
21
21
  @index = { 'index' => [] }
22
22
  @projects = {}
23
23
  @tags_names = {}
@@ -6,7 +6,7 @@ module Fronde
6
6
  def source_for_target(file_name)
7
7
  # file_name may be frozen...
8
8
  src = file_name.sub(/\.html\z/, '.org')
9
- pubfolder = Fronde::Config.settings['public_folder']
9
+ pubfolder = Fronde::Config.get('public_folder')
10
10
  src.sub!(/^#{pubfolder}\//, '')
11
11
  # Look for match in each possible sources. The first found wins.
12
12
  Fronde::Config.sources.each do |project|
@@ -36,7 +36,7 @@ module Fronde
36
36
  target = "#{project['target']}/#{target}" if project['target'] != '.'
37
37
  end
38
38
  return target unless with_public_folder
39
- pubfolder = Fronde::Config.settings['public_folder']
39
+ pubfolder = Fronde::Config.get('public_folder')
40
40
  "#{pubfolder}/#{target}"
41
41
  end
42
42
 
@@ -8,7 +8,7 @@ module Fronde
8
8
  # Main method, which will call the other to initialize an
9
9
  # {Fronde::OrgFile} instance.
10
10
  def extract_data
11
- @content = IO.read @file
11
+ @content = File.read @file
12
12
  @title = extract_title
13
13
  @subtitle = extract_subtitle
14
14
  @date = extract_date
@@ -49,7 +49,7 @@ module Fronde
49
49
 
50
50
  def extract_author
51
51
  m = /^#\+author:(.+)$/i.match(@content)
52
- return Fronde::Config.settings['author'] if m.nil?
52
+ return Fronde::Config.get('author') if m.nil?
53
53
  m[1].strip
54
54
  end
55
55
 
@@ -61,7 +61,7 @@ module Fronde
61
61
 
62
62
  def extract_lang
63
63
  m = /^#\+language:(.+)$/i.match(@content)
64
- return Fronde::Config.settings['lang'] if m.nil?
64
+ return Fronde::Config.get('lang') if m.nil?
65
65
  m[1].strip
66
66
  end
67
67
 
@@ -13,7 +13,7 @@ module Fronde
13
13
  #
14
14
  # @return [String] the HTML keywords list
15
15
  def keywords_to_html
16
- domain = Fronde::Config.settings['domain']
16
+ domain = Fronde::Config.get('domain')
17
17
  klist = @keywords.map do |k|
18
18
  <<~KEYWORDLINK
19
19
  <li class="keyword">
@@ -15,7 +15,7 @@ module Fronde
15
15
  # This class is responsible for reading or writing existing or new org
16
16
  # files, and formating their content to be used on the generated
17
17
  # website.
18
- class OrgFile
18
+ class OrgFile # rubocop:disable Metrics/ClassLength
19
19
  # @return [String] the title of the current org document, taken from
20
20
  # the ~#+title:~ header.
21
21
  attr_reader :title
@@ -240,7 +240,7 @@ module Fronde
240
240
  .gsub('%k', @keywords.join(', '))
241
241
  .gsub('%K', keywords_to_html)
242
242
  .gsub('%l', @lang)
243
- .gsub('%L', (Fronde::Config.settings['license'] || '').gsub(/\s+/, ' ').strip)
243
+ .gsub('%L', Fronde::Config.get('license', '').gsub(/\s+/, ' ').strip)
244
244
  .gsub('%n', "Fronde #{Fronde::VERSION}")
245
245
  .gsub('%N', "<a href=\"https://git.umaneti.net/fronde/about/\">Fronde</a> #{Fronde::VERSION}")
246
246
  .gsub('%s', @subtitle)
@@ -257,12 +257,12 @@ module Fronde
257
257
  # The intermediate parent folders are created if necessary.
258
258
  #
259
259
  # @return [Integer] the length written (as returned by the
260
- # underlying ~IO.write~ method call)
260
+ # underlying ~File.write~ method call)
261
261
  def write
262
262
  raise TypeError, 'no conversion from nil file name to path.' if @file.nil?
263
263
  file_dir = File.dirname @file
264
264
  FileUtils.mkdir_p file_dir unless Dir.exist? file_dir
265
- IO.write @file, @content
265
+ File.write @file, @content
266
266
  end
267
267
 
268
268
  private
@@ -272,7 +272,7 @@ module Fronde
272
272
  @html_file = Fronde::OrgFile.target_for_source(
273
273
  @file, @project, with_public_folder: false
274
274
  )
275
- @url = "#{Fronde::Config.settings['domain']}/#{@html_file}"
275
+ @url = "#{Fronde::Config.get('domain')}/#{@html_file}"
276
276
  end
277
277
 
278
278
  def init_empty_file
@@ -280,9 +280,9 @@ module Fronde
280
280
  @subtitle = ''
281
281
  @date = DateTime.now
282
282
  @notime = false
283
- @author = @options[:author] || Fronde::Config.settings['author']
283
+ @author = @options[:author] || Fronde::Config.get('author')
284
284
  @keywords = []
285
- @lang = @options[:lang] || Fronde::Config.settings['lang']
285
+ @lang = @options[:lang] || Fronde::Config.get('lang')
286
286
  @excerpt = ''
287
287
  body = @options[:content] || ''
288
288
  @content = @options[:raw_content] || <<~ORG
@@ -19,9 +19,9 @@ module Fronde # rubocop:disable Style/Documentation
19
19
  private
20
20
 
21
21
  def local_path(requested_path)
22
- routes = Fronde::Config.settings.dig('preview', 'routes') || {}
22
+ routes = Fronde::Config.get(['preview', 'routes'], {})
23
23
  return routes[requested_path] if routes.has_key? requested_path
24
- local_path = Fronde::Config.settings['public_folder'] + requested_path
24
+ local_path = Fronde::Config.get('public_folder') + requested_path
25
25
  if File.directory? local_path
26
26
  local_path = format(
27
27
  '%<path>s/index.html', path: local_path.delete_suffix('/')
@@ -32,9 +32,9 @@ module Fronde # rubocop:disable Style/Documentation
32
32
  end
33
33
 
34
34
  def parse_body(local_path, local_host)
35
- body = IO.read local_path
35
+ body = File.read local_path
36
36
  return body unless local_path.match?(/\.(?:ht|x)ml\z/)
37
- domain = Fronde::Config.settings['domain']
37
+ domain = Fronde::Config.get('domain')
38
38
  return body if domain == ''
39
39
  body.gsub(/"file:\/\//, format('"%<host>s', host: local_host))
40
40
  .gsub(/"#{domain}/, format('"%<host>s', host: local_host))
@@ -45,7 +45,7 @@ module Fronde # rubocop:disable Style/Documentation
45
45
  def start_preview
46
46
  # Inspired by ruby un.rb library, which allows normally to start a
47
47
  # webrick server in one line: ruby -run -e httpd public_html -p 5000
48
- port = Fronde::Config.settings.dig('preview', 'server_port') || 5000
48
+ port = Fronde::Config.get(['preview', 'server_port'], 5000)
49
49
  s = WEBrick::HTTPServer.new(Port: port)
50
50
  s.mount '/', Fronde::PreviewServlet
51
51
  ['TERM', 'QUIT', 'INT'].each { |sig| trap(sig, proc { s.shutdown }) }
@@ -52,7 +52,7 @@ module Fronde
52
52
  private
53
53
 
54
54
  def filter_templates(file_name)
55
- templates = Fronde::Config.settings['templates']
55
+ templates = Fronde::Config.get('templates')
56
56
  return [] if templates.nil? || templates.empty?
57
57
  templates.filter { |t| check_required_keys(t, file_name) }
58
58
  end
@@ -71,7 +71,7 @@ module Fronde
71
71
  end
72
72
 
73
73
  def check_path(file_name, pathes)
74
- pub_folder = Fronde::Config.settings['public_folder']
74
+ pub_folder = Fronde::Config.get('public_folder')
75
75
  if pathes.is_a?(Array)
76
76
  pathes.each do |tp|
77
77
  return true if File.fnmatch?("#{pub_folder}#{tp}",
data/lib/fronde/utils.rb CHANGED
@@ -7,6 +7,9 @@ require 'r18n-core'
7
7
  require 'fronde/config'
8
8
 
9
9
  module Fronde
10
+ # Default Error, which may be raised by fronde code
11
+ class Error < ::StandardError; end
12
+
10
13
  # Embeds usefull methods, mainly used in rake tasks.
11
14
  module Utils
12
15
  # @return [Hash] the possible throbber themes
@@ -38,7 +41,8 @@ module Fronde
38
41
  # configuration
39
42
  FRONDE_COMMANDS = {
40
43
  'init' => { opts: ['-a', '-h', '-l', '-t', '-v'] },
41
- 'config' => { alias: 'init' },
44
+ 'update' => { opts: ['-a', '-h', '-l', '-t', '-v'] },
45
+ 'config' => { alias: 'update' },
42
46
  'preview' => { opts: ['-h'] },
43
47
  'open' => { opts: ['-a', '-h', '-l', '-t', '-v'] },
44
48
  'edit' => { alias: 'open' },
@@ -144,6 +148,17 @@ module Fronde
144
148
  command
145
149
  end
146
150
 
151
+ # Returns the given command options.
152
+ #
153
+ # This method will first try to resolve command alias, if any.
154
+ #
155
+ # @param command [String] the command, which options should be returned
156
+ # @return [Hash] the command options
157
+ def command_options(command)
158
+ cmd = resolve_possible_alias command
159
+ FRONDE_COMMANDS[cmd].merge(name: cmd)
160
+ end
161
+
147
162
  # Try to discover the current host operating system.
148
163
  #
149
164
  # @return [String] either apple, windows or linux (default)
@@ -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.2'
5
+ VERSION = '0.3.3'
6
6
  end
data/lib/tasks/org.rake CHANGED
@@ -12,12 +12,19 @@ CLOBBER.push(
12
12
  'var/lib/org-config.el', '.dir-locals.el', 'lib/htmlize.el'
13
13
  )
14
14
 
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
+
15
23
  namespace :org do
16
24
  directory 'var/tmp'
17
25
 
18
26
  desc 'Download last version of Org'
19
27
  file 'var/tmp/org.tar.gz' => 'var/tmp' do
20
- verbose = Rake::FileUtilsExt.verbose_flag
21
28
  download = Thread.new do
22
29
  Thread.current[:org_version] = Fronde::Config.org_last_version
23
30
  Fronde::Utils.download_org
@@ -32,20 +39,14 @@ namespace :org do
32
39
 
33
40
  desc 'Compile Org'
34
41
  task compile: 'var/tmp/org.tar.gz' do |task|
35
- verbose = Rake::FileUtilsExt.verbose_flag
36
42
  org_version = Fronde::Config.org_last_version
37
43
  org_dir = "lib/org-#{org_version}"
38
44
  next if Dir.exist?("#{org_dir}/lisp")
39
- make = ['make', '-C', org_dir]
40
- unless verbose
41
- make << '-s'
42
- make << 'EMACSQ="emacs -Q --eval \'(setq inhibit-message t)\'"'
43
- end
44
45
  build = Thread.new do
45
46
  sh "tar -C lib -xzf #{task.prerequisites[0]}"
46
47
  mv "lib/org-mode-release_#{org_version}", org_dir
47
- sh((make + ['compile']).join(' '))
48
- sh((make + ['autoloads']).join(' '))
48
+ sh make_org_cmd(org_dir, 'compile')
49
+ sh make_org_cmd(org_dir, 'autoloads')
49
50
  Dir.glob('lib/org-[0-9.]*').each do |ov|
50
51
  next if ov == org_dir
51
52
  rm_r ov
@@ -65,14 +66,14 @@ namespace :org do
65
66
  htmlize = URI(
66
67
  'https://raw.githubusercontent.com/hniksic/emacs-htmlize/master/htmlize.el'
67
68
  ).open.read
68
- IO.write 'lib/htmlize.el', htmlize
69
+ File.write 'lib/htmlize.el', htmlize
69
70
  end
70
71
 
71
72
  file 'lib/ox-gmi.el' => 'lib' do
72
73
  ox_gmi = URI(
73
74
  'https://git.umaneti.net/ox-gmi.el/plain/ox-gmi.el'
74
75
  ).open.read
75
- IO.write 'lib/ox-gmi.el', ox_gmi
76
+ File.write 'lib/ox-gmi.el', ox_gmi
76
77
  end
77
78
 
78
79
  file 'var/lib/org-config.el' => ['lib/htmlize.el', 'lib/ox-gmi.el'] do
@@ -85,7 +86,7 @@ namespace :org do
85
86
 
86
87
  desc 'Install Org'
87
88
  multitask install: ['org:compile', '.dir-locals.el'] do
88
- mkdir_p "#{Fronde::Config.settings['public_folder']}/assets"
89
+ mkdir_p "#{Fronde::Config.get('public_folder')}/assets"
89
90
  Fronde::Config.sources.each do |s|
90
91
  mkdir_p s['path'] unless Dir.exist? s['path']
91
92
  end
data/lib/tasks/site.rake CHANGED
@@ -10,7 +10,6 @@ namespace :site do
10
10
  desc 'Generates all index files'
11
11
  task :index do
12
12
  index = Fronde::Index.new
13
- verbose = Rake::FileUtilsExt.verbose_flag
14
13
  if verbose
15
14
  index.write_all
16
15
  next
@@ -28,7 +27,7 @@ namespace :site do
28
27
  args.with_defaults(:force? => false)
29
28
  build_html = Thread.new do
30
29
  rm_r 'var/tmp/timestamps', force: true if args[:force?]
31
- Fronde::Emacs.new(verbose: Rake::FileUtilsExt.verbose_flag).publish
30
+ Fronde::Emacs.new(verbose: verbose).publish
32
31
  end
33
32
  begin
34
33
  Fronde::Utils.throbber(build_html, 'Building:')
@@ -39,7 +38,7 @@ namespace :site do
39
38
  end
40
39
  # :nocov:
41
40
  customize_html = Thread.new do
42
- pubfolder = Fronde::Config.settings['public_folder']
41
+ pubfolder = Fronde::Config.get('public_folder')
43
42
  Dir["#{pubfolder}/**/*.html"].each do |f|
44
43
  Fronde::Templater.customize_output(f)
45
44
  end
data/lib/tasks/sync.rake CHANGED
@@ -3,8 +3,12 @@
3
3
  require 'fronde/config'
4
4
  require 'fronde/utils'
5
5
 
6
- def rsync_command(verbose, test = nil)
7
- rsync_command = Fronde::Config.settings['rsync']
6
+ module Fronde
7
+ class SyncError < Error; end
8
+ end
9
+
10
+ def rsync_command(test = nil)
11
+ rsync_command = Fronde::Config.get('rsync')
8
12
  return rsync_command unless rsync_command.nil?
9
13
  optstring = []
10
14
  optstring << 'n' if test
@@ -16,19 +20,37 @@ def rsync_command(verbose, test = nil)
16
20
  "rsync -#{optstring.join}rlt --delete"
17
21
  end
18
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)
38
+ end
39
+
19
40
  namespace :sync do
20
- desc 'Push change to server'
41
+ desc 'Push changes to server'
21
42
  task :push, :test? do |_, args|
22
- remote_path = Fronde::Config.settings['remote']
23
- if remote_path.nil?
24
- warn 'No remote path set'
25
- next
26
- end
27
- public_folder = Fronde::Config.settings['public_folder']
28
- publish_thread = Thread.new do
29
- sh [rsync_command(Rake::FileUtilsExt.verbose_flag, args[:test?]),
30
- "#{public_folder}/", remote_path].join(' ')
31
- end
32
- Fronde::Utils.throbber(publish_thread, 'Publishing:')
43
+ pull_or_push(:push, 'Publishing:', args[:test?])
44
+ rescue Fronde::SyncError => e
45
+ warn e
46
+ next
47
+ end
48
+
49
+ desc 'Pull changes from server'
50
+ task :pull, :test? do |_, args|
51
+ pull_or_push(:pull, 'Pulling:', args[:test?])
52
+ rescue Fronde::SyncError => e
53
+ warn e
54
+ next
33
55
  end
34
56
  end
data/locales/en.yml CHANGED
@@ -6,6 +6,7 @@ fronde:
6
6
  cmd_title: Commands
7
7
  alias: Alias for %1.
8
8
  init: Initialize your Fronde instance (you just need to do it once).
9
+ update: Update Fronde dependency (to be run once in a while).
9
10
  preview: 'Start a test web server to preview your website on http://127.0.0.1:5000'
10
11
  open: Open or create an org file.
11
12
  build: Compile your org files to HTML.
data/locales/fr.yml CHANGED
@@ -6,6 +6,7 @@ fronde:
6
6
  cmd_title: Commandes
7
7
  alias: Alias pour %1.
8
8
  init: Initialise votre instance de Fronde (vous ne devriez faire cela qu'une fois).
9
+ update: Met à jour les dépendances de Fronde (à lancer une fois de temps à autre).
9
10
  preview: "Démarre un serveur web de test pour prévisualiser votre site à l'adresse http://127.0.0.1:5000"
10
11
  open: Ouvre ou crée un fichier org.
11
12
  build: Compile vos fichiers org en HTML.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fronde
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Étienne Deparis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-25 00:00:00.000000000 Z
11
+ date: 2022-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.11'
19
+ version: '1.13'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.11'
26
+ version: '1.13'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: r18n-core
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '3.0'
47
+ version: '3.1'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '3.0'
54
+ version: '3.1'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -128,70 +128,70 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '1.1'
131
+ version: '1.3'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '1.1'
138
+ version: '1.3'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: rspec
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: '3.10'
145
+ version: '3.11'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: '3.10'
152
+ version: '3.11'
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: rubocop
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - "~>"
158
158
  - !ruby/object:Gem::Version
159
- version: '1.12'
159
+ version: '1.36'
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
- version: '1.12'
166
+ version: '1.36'
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: rubocop-performance
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
171
  - - "~>"
172
172
  - !ruby/object:Gem::Version
173
- version: '1.10'
173
+ version: '1.15'
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
- version: '1.10'
180
+ version: '1.15'
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: rubocop-rspec
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
185
  - - "~>"
186
186
  - !ruby/object:Gem::Version
187
- version: '2.2'
187
+ version: '2.13'
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - "~>"
193
193
  - !ruby/object:Gem::Version
194
- version: '2.2'
194
+ version: '2.13'
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: simplecov
197
197
  requirement: !ruby/object:Gem::Requirement
@@ -258,7 +258,11 @@ files:
258
258
  homepage: https://git.umaneti.net/fronde/about/
259
259
  licenses:
260
260
  - WTFPL
261
- metadata: {}
261
+ metadata:
262
+ rubygems_mfa_required: 'true'
263
+ source_code_uri: https://git.umaneti.net/fronde
264
+ homepage_uri: https://etienne.depar.is/fronde/
265
+ funding_uri: https://liberapay.com/milouse
262
266
  post_install_message:
263
267
  rdoc_options: []
264
268
  require_paths:
@@ -274,7 +278,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
274
278
  - !ruby/object:Gem::Version
275
279
  version: '0'
276
280
  requirements: []
277
- rubygems_version: 3.2.22
281
+ rubygems_version: 3.3.7
278
282
  signing_key:
279
283
  specification_version: 4
280
284
  summary: An opinionated static website generator for Org