archival 0.0.0 → 0.15.4

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.
package/README.md CHANGED
@@ -1,10 +1,37 @@
1
- # Archival
1
+ <a href="https://archival.dev">
2
+ <p align="center">
3
+ <img src="https://archival.dev/img/header.png" alt="archival" height="200px">
4
+ </p>
5
+ </a>
2
6
 
3
- [![Rspec tests](https://github.com/jesseditson/archival/actions/workflows/rspec.yml/badge.svg)](https://github.com/jesseditson/archival/actions/workflows/rspec.yml)
7
+ [![license](https://img.shields.io/crates/l/archival)](LICENSE.md) [![Chat](https://img.shields.io/discord/1257848212744568853?label=chat&logo=discord)](https://archival.dev/chat.html)
4
8
 
5
- https://jesseditson.com/the-simplest-cms-part-1
9
+ ## What is archival?
6
10
 
7
- Additional resources:
11
+ archival is a library for building database-free content-oriented websites.
8
12
 
9
- - https://shopify.github.io/liquid/basics/introduction/
10
- - https://github.com/toml-lang/toml/wiki
13
+ Learn more at [archival.dev](https://archival.dev).
14
+
15
+ ## Examples
16
+
17
+ Lots of websites are built on archival, including https://archival.dev, which you can check out here:
18
+
19
+ - https://github.com/jesseditson/archival-docs
20
+
21
+ Another example of a super simple website is a blog:
22
+
23
+ https://github.com/jesseditson/jesseditson.com
24
+
25
+ Most websites built on archival are built with our editor:
26
+
27
+ https://editor.archival.dev/new
28
+
29
+ They can all be previewed directly in your browser, and when you're ready you can set up your own site with one click.
30
+
31
+ ## Contributing
32
+
33
+ Please see the [Contributing Guide](CONTRIBUTING.md) for help and guidelines!
34
+
35
+ ## License
36
+
37
+ [MIT](LICENSE.md)
package/install.js ADDED
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const { execSync } = require('child_process');
5
+ const {
6
+ createWriteStream,
7
+ existsSync,
8
+ mkdirSync,
9
+ chmodSync,
10
+ writeFileSync,
11
+ unlinkSync,
12
+ } = require('fs');
13
+ const { join } = require('path');
14
+ const https = require('https');
15
+
16
+ const pkg = require('./package.json');
17
+ const version = pkg.version;
18
+
19
+ const TARGETS = {
20
+ 'linux-x64': 'x86_64-unknown-linux-musl',
21
+ 'linux-arm64': 'aarch64-unknown-linux-musl',
22
+ 'darwin-x64': 'x86_64-apple-darwin',
23
+ 'darwin-arm64': 'aarch64-apple-darwin',
24
+ 'win32-x64': 'x86_64-pc-windows-msvc',
25
+ };
26
+
27
+ const platformKey = `${process.platform}-${process.arch}`;
28
+ const target = TARGETS[platformKey];
29
+ if (!target) {
30
+ console.error(`archival: unsupported platform: ${platformKey}`);
31
+ process.exit(1);
32
+ }
33
+
34
+ const isWindows = process.platform === 'win32';
35
+ const binExt = isWindows ? '.exe' : '';
36
+ const binDir = join(__dirname, 'bin');
37
+ const binPath = join(binDir, `archival${binExt}`);
38
+
39
+ const tagName = `v${version}`;
40
+ const tarName = `archival-${tagName}-${target}.tar.gz`;
41
+ const releaseDir = `archival-${tagName}-${target}`;
42
+ const url = `https://github.com/jesseditson/archival/releases/download/${tagName}/${tarName}`;
43
+ const tmpTar = join(binDir, tarName);
44
+
45
+ if (!existsSync(binDir)) mkdirSync(binDir, { recursive: true });
46
+
47
+ function download(url, dest) {
48
+ return new Promise((resolve, reject) => {
49
+ function get(currentUrl) {
50
+ https
51
+ .get(currentUrl, (res) => {
52
+ if (res.statusCode === 301 || res.statusCode === 302) {
53
+ return get(res.headers.location);
54
+ }
55
+ if (res.statusCode !== 200) {
56
+ return reject(new Error(`HTTP ${res.statusCode}: ${currentUrl}`));
57
+ }
58
+ const file = createWriteStream(dest);
59
+ res.pipe(file);
60
+ file.on('finish', () => file.close(resolve));
61
+ file.on('error', reject);
62
+ })
63
+ .on('error', reject);
64
+ }
65
+ get(url);
66
+ });
67
+ }
68
+
69
+ console.log(`Downloading archival ${version} for ${target}...`);
70
+ download(url, tmpTar)
71
+ .then(() => {
72
+ try {
73
+ const tarTarget = `${releaseDir}/archival${binExt}`;
74
+ execSync(
75
+ `tar xzf "${tmpTar}" -C "${binDir}" "${tarTarget}" --strip-components=1`,
76
+ { stdio: 'inherit' }
77
+ );
78
+
79
+ if (isWindows) {
80
+ // The extracted binary is bin/archival.exe; create a .cmd shim so that
81
+ // npm bin symlinks (which point to bin/archival) work in CMD/PowerShell.
82
+ // Note: npm itself creates shims for the bin/archival entry that invoke
83
+ // node, which won't work for a native binary. Use `bin\archival.exe`
84
+ // directly on Windows if the npm bin shim does not work.
85
+ writeFileSync(join(binDir, 'archival.cmd'), `@"%~dp0archival.exe" %*\r\n`);
86
+ } else {
87
+ chmodSync(binPath, 0o755);
88
+ }
89
+
90
+ unlinkSync(tmpTar);
91
+ console.log('archival installed successfully.');
92
+ } catch (err) {
93
+ console.error(`archival: installation failed: ${err.message}`);
94
+ process.exit(1);
95
+ }
96
+ })
97
+ .catch((err) => {
98
+ console.error(`archival: download failed: ${err.message}`);
99
+ process.exit(1);
100
+ });
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "archival",
3
- "version": "0.0.0",
4
- "description": "An incredibly simple CMS for durable websites",
5
- "bin": "build.rb",
6
- "directories": {
7
- "lib": "lib"
8
- },
3
+ "version": "0.15.4",
4
+ "description": "The simplest CMS in existence",
5
+ "license": "Unlicense",
9
6
  "repository": {
10
7
  "type": "git",
11
- "url": "git+https://github.com/jesseditson/archival.git"
8
+ "url": "https://github.com/jesseditson/archival"
12
9
  },
13
- "author": "Jesse Ditson <jesse.ditson@gmail.com>",
14
- "license": "Unlicense",
15
- "bugs": {
16
- "url": "https://github.com/jesseditson/archival/issues"
10
+ "bin": {
11
+ "archival": "bin/archival"
12
+ },
13
+ "scripts": {
14
+ "postinstall": "node install.js"
17
15
  },
18
- "homepage": "https://github.com/jesseditson/archival#readme"
16
+ "files": [
17
+ "install.js"
18
+ ]
19
19
  }
@@ -1,24 +0,0 @@
1
- name: Rspec tests
2
- on:
3
- push:
4
- branches: [ $default-branch ]
5
- pull_request:
6
- branches: [ $default-branch ]
7
-
8
- jobs:
9
- test:
10
-
11
- runs-on: ubuntu-latest
12
- strategy:
13
- matrix:
14
- ruby-version: ['2.6', '2.7', '3.0']
15
-
16
- steps:
17
- - uses: actions/checkout@v2
18
- - name: Set up Ruby
19
- uses: ruby/setup-ruby@v1
20
- with:
21
- ruby-version: ${{ matrix.ruby-version }}
22
- bundler-cache: true # runs 'bundle install' and caches installed gems automatically
23
- - name: Run tests
24
- run: bundle exec rspec
package/.rspec DELETED
@@ -1 +0,0 @@
1
- --require spec_helper
@@ -1,43 +0,0 @@
1
- {
2
- // Use IntelliSense to learn about possible attributes.
3
- // Hover to view descriptions of existing attributes.
4
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
- "version": "0.2.0",
6
- "configurations": [
7
- {
8
- "type": "ruby-debug",
9
- "request": "launch",
10
- "name": "Ruby",
11
- "program": "${file}",
12
- "programArgs": [],
13
- "useBundler": false
14
- },
15
- {
16
- "type": "ruby-debug",
17
- "request": "launch",
18
- "name": "RSpec All",
19
- "program": "rspec",
20
- "programArgs": [
21
- "-I",
22
- "${workspaceFolder}",
23
- ],
24
- "useBundler": false
25
- },
26
- {
27
- "type": "ruby-debug",
28
- "request": "launch",
29
- "name": "RSpec LocalFile",
30
- "program": "rspec",
31
- "programArgs": ["${relativeFile}"],
32
- "useBundler": true
33
- },
34
- {
35
- "type": "ruby-debug",
36
- "request": "launch",
37
- "name": "RSpec Selected Line",
38
- "program": "rspec",
39
- "programArgs": ["${relativeFile}:${lineNumber}"],
40
- "useBundler": true
41
- }
42
- ]
43
- }
package/Gemfile DELETED
@@ -1,8 +0,0 @@
1
- source 'https://rubygems.org'
2
- gem 'liquid'
3
- gem 'tomlrb'
4
-
5
- group :test do
6
- gem 'rspec'
7
- gem 'rspec-snapshot'
8
- end
package/Gemfile.lock DELETED
@@ -1,35 +0,0 @@
1
- GEM
2
- remote: https://rubygems.org/
3
- specs:
4
- awesome_print (1.9.2)
5
- diff-lcs (1.4.4)
6
- liquid (5.1.0)
7
- rspec (3.10.0)
8
- rspec-core (~> 3.10.0)
9
- rspec-expectations (~> 3.10.0)
10
- rspec-mocks (~> 3.10.0)
11
- rspec-core (3.10.1)
12
- rspec-support (~> 3.10.0)
13
- rspec-expectations (3.10.1)
14
- diff-lcs (>= 1.2.0, < 2.0)
15
- rspec-support (~> 3.10.0)
16
- rspec-mocks (3.10.2)
17
- diff-lcs (>= 1.2.0, < 2.0)
18
- rspec-support (~> 3.10.0)
19
- rspec-snapshot (2.0.1)
20
- awesome_print (> 1.0.0)
21
- rspec (> 3.0.0)
22
- rspec-support (3.10.2)
23
- tomlrb (2.0.1)
24
-
25
- PLATFORMS
26
- x86_64-darwin-20
27
-
28
- DEPENDENCIES
29
- liquid
30
- rspec
31
- rspec-snapshot
32
- tomlrb
33
-
34
- BUNDLED WITH
35
- 2.2.29
package/action.yml DELETED
@@ -1,14 +0,0 @@
1
- name: 'Archival Build'
2
- description: 'Packages a website built with Archival'
3
- author: 'Jesse Ditson'
4
- branding:
5
- color: green
6
- icon: box
7
- runs:
8
- using: 'composite'
9
- steps:
10
- - uses: ruby/setup-ruby@v1
11
- with:
12
- ruby-version: 3.0
13
- bundler-cache: true
14
- - run: ${{ github.action_path }}/build.rb
package/archival.gemspec DELETED
@@ -1,12 +0,0 @@
1
- Gem::Specification.new do |s|
2
- s.name = 'archival'
3
- s.version = '0.0.0'
4
- s.summary = "An incredibly simple CMS for durable websites"
5
- s.description = "https://jesseditson.com/the-simplest-cms-part-1"
6
- s.authors = ["Jesse Ditson"]
7
- s.email = 'jesse.ditson@gmail.com'
8
- s.files = ["lib/archival.rb"]
9
- s.homepage =
10
- 'https://rubygems.org/gems/archival'
11
- s.license = 'Unlicense'
12
- end
package/bin/bundle DELETED
@@ -1,114 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- #
5
- # This file was generated by Bundler.
6
- #
7
- # The application 'bundle' is installed as part of a gem, and
8
- # this file is here to facilitate running it.
9
- #
10
-
11
- require "rubygems"
12
-
13
- m = Module.new do
14
- module_function
15
-
16
- def invoked_as_script?
17
- File.expand_path($0) == File.expand_path(__FILE__)
18
- end
19
-
20
- def env_var_version
21
- ENV["BUNDLER_VERSION"]
22
- end
23
-
24
- def cli_arg_version
25
- return unless invoked_as_script? # don't want to hijack other binstubs
26
- return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
27
- bundler_version = nil
28
- update_index = nil
29
- ARGV.each_with_index do |a, i|
30
- if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
31
- bundler_version = a
32
- end
33
- next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
34
- bundler_version = $1
35
- update_index = i
36
- end
37
- bundler_version
38
- end
39
-
40
- def gemfile
41
- gemfile = ENV["BUNDLE_GEMFILE"]
42
- return gemfile if gemfile && !gemfile.empty?
43
-
44
- File.expand_path("../../Gemfile", __FILE__)
45
- end
46
-
47
- def lockfile
48
- lockfile =
49
- case File.basename(gemfile)
50
- when "gems.rb" then gemfile.sub(/\.rb$/, gemfile)
51
- else "#{gemfile}.lock"
52
- end
53
- File.expand_path(lockfile)
54
- end
55
-
56
- def lockfile_version
57
- return unless File.file?(lockfile)
58
- lockfile_contents = File.read(lockfile)
59
- return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
60
- Regexp.last_match(1)
61
- end
62
-
63
- def bundler_requirement
64
- @bundler_requirement ||=
65
- env_var_version || cli_arg_version ||
66
- bundler_requirement_for(lockfile_version)
67
- end
68
-
69
- def bundler_requirement_for(version)
70
- return "#{Gem::Requirement.default}.a" unless version
71
-
72
- bundler_gem_version = Gem::Version.new(version)
73
-
74
- requirement = bundler_gem_version.approximate_recommendation
75
-
76
- return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0")
77
-
78
- requirement += ".a" if bundler_gem_version.prerelease?
79
-
80
- requirement
81
- end
82
-
83
- def load_bundler!
84
- ENV["BUNDLE_GEMFILE"] ||= gemfile
85
-
86
- activate_bundler
87
- end
88
-
89
- def activate_bundler
90
- gem_error = activation_error_handling do
91
- gem "bundler", bundler_requirement
92
- end
93
- return if gem_error.nil?
94
- require_error = activation_error_handling do
95
- require "bundler/version"
96
- end
97
- return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
98
- warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
99
- exit 42
100
- end
101
-
102
- def activation_error_handling
103
- yield
104
- nil
105
- rescue StandardError, LoadError => e
106
- e
107
- end
108
- end
109
-
110
- m.load_bundler!
111
-
112
- if m.invoked_as_script?
113
- load Gem.bin_path("bundler", "bundle")
114
- end
package/bin/coderay DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- #
5
- # This file was generated by Bundler.
6
- #
7
- # The application 'coderay' is installed as part of a gem, and
8
- # this file is here to facilitate running it.
9
- #
10
-
11
- require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
14
-
15
- bundle_binstub = File.expand_path("../bundle", __FILE__)
16
-
17
- if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
- load(bundle_binstub)
20
- else
21
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
- Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
- end
24
- end
25
-
26
- require "rubygems"
27
- require "bundler/setup"
28
-
29
- load Gem.bin_path("coderay", "coderay")
package/bin/faker DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- #
5
- # This file was generated by Bundler.
6
- #
7
- # The application 'faker' is installed as part of a gem, and
8
- # this file is here to facilitate running it.
9
- #
10
-
11
- require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
14
-
15
- bundle_binstub = File.expand_path("../bundle", __FILE__)
16
-
17
- if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
- load(bundle_binstub)
20
- else
21
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
- Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
- end
24
- end
25
-
26
- require "rubygems"
27
- require "bundler/setup"
28
-
29
- load Gem.bin_path("faker", "faker")
package/bin/htmldiff DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- #
5
- # This file was generated by Bundler.
6
- #
7
- # The application 'htmldiff' is installed as part of a gem, and
8
- # this file is here to facilitate running it.
9
- #
10
-
11
- require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
14
-
15
- bundle_binstub = File.expand_path("../bundle", __FILE__)
16
-
17
- if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
- load(bundle_binstub)
20
- else
21
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
- Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
- end
24
- end
25
-
26
- require "rubygems"
27
- require "bundler/setup"
28
-
29
- load Gem.bin_path("diff-lcs", "htmldiff")
package/bin/ldiff DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- #
5
- # This file was generated by Bundler.
6
- #
7
- # The application 'ldiff' is installed as part of a gem, and
8
- # this file is here to facilitate running it.
9
- #
10
-
11
- require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
14
-
15
- bundle_binstub = File.expand_path("../bundle", __FILE__)
16
-
17
- if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
- load(bundle_binstub)
20
- else
21
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
- Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
- end
24
- end
25
-
26
- require "rubygems"
27
- require "bundler/setup"
28
-
29
- load Gem.bin_path("diff-lcs", "ldiff")
package/bin/pry DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- #
5
- # This file was generated by Bundler.
6
- #
7
- # The application 'pry' is installed as part of a gem, and
8
- # this file is here to facilitate running it.
9
- #
10
-
11
- require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
14
-
15
- bundle_binstub = File.expand_path("../bundle", __FILE__)
16
-
17
- if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
- load(bundle_binstub)
20
- else
21
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
- Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
- end
24
- end
25
-
26
- require "rubygems"
27
- require "bundler/setup"
28
-
29
- load Gem.bin_path("pry", "pry")
package/bin/readapt DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- #
5
- # This file was generated by Bundler.
6
- #
7
- # The application 'readapt' is installed as part of a gem, and
8
- # this file is here to facilitate running it.
9
- #
10
-
11
- require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
14
-
15
- bundle_binstub = File.expand_path("../bundle", __FILE__)
16
-
17
- if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
- load(bundle_binstub)
20
- else
21
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
- Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
- end
24
- end
25
-
26
- require "rubygems"
27
- require "bundler/setup"
28
-
29
- load Gem.bin_path("readapt", "readapt")
package/bin/rspec DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- #
5
- # This file was generated by Bundler.
6
- #
7
- # The application 'rspec' is installed as part of a gem, and
8
- # this file is here to facilitate running it.
9
- #
10
-
11
- require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
14
-
15
- bundle_binstub = File.expand_path("../bundle", __FILE__)
16
-
17
- if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
- load(bundle_binstub)
20
- else
21
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
- Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
- end
24
- end
25
-
26
- require "rubygems"
27
- require "bundler/setup"
28
-
29
- load Gem.bin_path("rspec-core", "rspec")
package/bin/thor DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- #
5
- # This file was generated by Bundler.
6
- #
7
- # The application 'thor' is installed as part of a gem, and
8
- # this file is here to facilitate running it.
9
- #
10
-
11
- require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
14
-
15
- bundle_binstub = File.expand_path("../bundle", __FILE__)
16
-
17
- if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
- load(bundle_binstub)
20
- else
21
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
- Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
- end
24
- end
25
-
26
- require "rubygems"
27
- require "bundler/setup"
28
-
29
- load Gem.bin_path("thor", "thor")
package/build.rb DELETED
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require_relative 'lib/builder'
4
-
5
- build_dir = ARGV[0] || Dir.pwd
6
-
7
- builder = Builder.new("root" => build_dir)
8
-
9
- builder.write_all()
package/lib/archival.rb DELETED
@@ -1,3 +0,0 @@
1
-
2
- class Archival
3
- end
package/lib/builder.rb DELETED
@@ -1,99 +0,0 @@
1
- require 'liquid'
2
- require 'tomlrb'
3
- require_relative 'tags/layout'
4
-
5
- Liquid::Template.error_mode = :strict
6
- Liquid::Template.register_tag("layout", Layout)
7
-
8
- class Builder
9
- attr_reader :page_templates
10
-
11
- def initialize(config, *args)
12
- @pages_dir = config["pages"] || "pages"
13
- @objects_dir = config["objects"] || "objects"
14
- @root = config["root"] || Dir.pwd
15
- @build_dir = config["build_dir"] || File.join(@root, "dist")
16
-
17
- @file_system = Liquid::LocalFileSystem.new(@root, "%s.liquid")
18
- @variables = {}
19
- @object_types = {}
20
- @page_templates = {}
21
-
22
- Liquid::Template.file_system = @file_system
23
-
24
- objects_definition_file = File.join(@root, "objects.toml")
25
- if File.file? objects_definition_file
26
- @object_types = read_toml(objects_definition_file)
27
- end
28
-
29
- add_pages(File.join(@root, @pages_dir))
30
- add_objects(File.join(@root, @objects_dir))
31
- end
32
-
33
- def add_pages(dir, prefix = nil)
34
- add_prefix = -> (entry) { prefix ? File.join(prefix, entry) : entry }
35
- Dir.foreach(dir) { |entry|
36
- if File.directory? entry
37
- unless entry == "." or entry == ".."
38
- add_pages(File.join(dir, entry), add_prefix(entry))
39
- end
40
- elsif File.file? File.join(dir, entry)
41
- if entry.end_with? ".liquid"
42
- unless entry.start_with? "_"
43
- page_name = File.basename(entry, ".liquid")
44
- content = @file_system.read_template_file(File.join(@pages_dir, add_prefix.(page_name)))
45
- @page_templates[add_prefix.(page_name)] = Liquid::Template.parse(content)
46
- end
47
- end
48
- end
49
- }
50
- end
51
-
52
- def add_objects(dir)
53
- objects = {}
54
- @object_types.each { |name, definition|
55
- objects[name] = []
56
- obj_dir = File.join(dir, name)
57
- if File.directory? obj_dir
58
- Dir.foreach(obj_dir) { |file|
59
- if file.end_with? ".toml"
60
- object = read_toml(File.join(obj_dir, file))
61
- object[:name] = File.basename(file, ".toml")
62
- objects[name].push object
63
- end
64
- }
65
- end
66
- objects[name] = objects[name].sort { |a, b| "#{a["order"] || a[:name]}" <=> "#{b["order"] || b[:name]}" }
67
- }
68
- @variables["objects"] = objects
69
- end
70
-
71
- def read_toml(file_path)
72
- Tomlrb.load_file(file_path)
73
- end
74
-
75
- def set_var(name, value)
76
- @variables[name] = value
77
- end
78
-
79
- def render(page)
80
- template = @page_templates[page]
81
- template.render(@variables)
82
- end
83
-
84
- def write_all()
85
- if !File.exist? @build_dir
86
- Dir.mkdir(@build_dir)
87
- end
88
- for template in @page_templates.keys
89
- out_dir = File.join(@build_dir, File.dirname(template))
90
- if !File.exist? out_dir
91
- Dir.mkdir(out_dir)
92
- end
93
- out_path = File.join(@build_dir, template + ".html")
94
- File.open(out_path, "w+") { |file|
95
- file.write(render(template))
96
- }
97
- end
98
- end
99
- end
@@ -1,96 +0,0 @@
1
- require 'liquid'
2
-
3
-
4
- class Layout < Liquid::Tag
5
- prepend Liquid::Tag::Disableable
6
- @@layout_cache = {}
7
-
8
- SYNTAX = /(#{Liquid::QuotedFragment}+)/o
9
-
10
- attr_reader :layout_name_expr, :attributes
11
-
12
- def self.reset_cache()
13
- @@layout_cache = {}
14
- end
15
-
16
- def initialize(tag_name, markup, tokens)
17
- super
18
-
19
- @page_content = []
20
-
21
- if markup =~ SYNTAX
22
-
23
- layout_name = Regexp.last_match(1)
24
- @layout_name_expr = parse_expression(layout_name)
25
- @attributes = {}
26
-
27
- markup.scan(Liquid::TagAttributes) do |key, value|
28
- @attributes[key] = parse_expression(value)
29
- end
30
-
31
- else
32
- raise "Invalid layout syntax"
33
- end
34
- end
35
-
36
- def load_layout(context)
37
- layout_name = context.evaluate(@layout_name_expr)
38
- raise "Bad layout name argument" unless layout_name
39
- if @@layout_cache[layout_name]
40
- return @@layout_cache[layout_name]
41
- end
42
- base_path = Dir.pwd
43
- layout_dir = "layout"
44
- layout_path = File.join(base_path, layout_dir)
45
- if !File.exist? layout_path then raise "Layout dir #{layout_path} not found" end
46
- found_layout = nil
47
- for f in Dir.entries(layout_path)
48
- if !File.file? File.join(layout_path, f)
49
- next
50
- end
51
- if File.basename(f, ".*") == layout_name
52
- if found_layout
53
- raise "More than one layout named #{layout_name} found."
54
- end
55
- found_layout = File.join(layout_path, f)
56
- end
57
- end
58
- if found_layout == nil then
59
- raise "No layouts named #{layout_name} found."
60
- end
61
- layout = File.read(found_layout)
62
- @@layout_cache[layout_name] = Liquid::Template.parse(layout)
63
- return @@layout_cache[layout_name]
64
- end
65
-
66
- def parse(tokens)
67
- while t = tokens.shift() do
68
- @page_content.push t
69
- end
70
- end
71
-
72
- def render_to_output_buffer(context, output)
73
- layout_name = context.evaluate(@layout_name_expr)
74
- layout = load_layout(context)
75
-
76
- old_template_name = context.template_name
77
- old_partial = context.partial
78
- begin
79
- context.template_name = layout_name
80
- context.partial = true
81
- context.stack do
82
- @attributes.each do |key, value|
83
- context[key] = context.evaluate(value)
84
- end
85
- rendered_page = Liquid::Template.parse(@page_content.join).render(context)
86
- context['page_content'] = rendered_page
87
- layout.render_to_output_buffer(context, output)
88
- end
89
- ensure
90
- context.template_name = old_template_name
91
- context.partial = old_partial
92
- end
93
-
94
- output
95
- end
96
- end
@@ -1,33 +0,0 @@
1
- require 'builder'
2
-
3
- FIXTURES_DIR = File.join(File.dirname(__FILE__), "fixtures")
4
-
5
- def write_snapshot(name, content)
6
- File.open(File.join(FIXTURES_DIR, "snapshots", name), "w+") { |file|
7
- file.write(content)
8
- }
9
- end
10
- def snapshot(name)
11
- File.read(File.join(FIXTURES_DIR, "snapshots", name))
12
- end
13
-
14
- RSpec.describe Builder do
15
- context "simple website" do
16
- before(:each) do
17
- root = File.join(FIXTURES_DIR, "simple_website")
18
- Layout.reset_cache()
19
- @builder = Builder.new("root" => root)
20
- Dir.chdir root
21
- end
22
- it "has the right pages" do
23
- expect(@builder.page_templates.keys).to eq ["index"]
24
- end
25
- it "renders the index page" do
26
- out = @builder.render("index")
27
- if ENV["WRITE_SNAPSHOT"]
28
- write_snapshot("simple_website_index", out)
29
- end
30
- expect(out).to eq snapshot("simple_website_index")
31
- end
32
- end
33
- end
@@ -1,14 +0,0 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
- <meta name="viewport" content="width=device-width,initial-scale=1">
7
- <title>{{name}}</title>
8
- </head>
9
- <body>
10
- <main role="main" tabindex="-1">
11
- {{ page_content }}
12
- </main>
13
- </body>
14
- </html>
@@ -1,6 +0,0 @@
1
- name = "this is an item"
2
- description = '''
3
- ### Test Markdown
4
-
5
- This contains some simple _formatting_
6
- '''
@@ -1 +0,0 @@
1
- name = "this is another item"
@@ -1,4 +0,0 @@
1
-
2
- [item]
3
- name = "string"
4
- description = "markdown"
@@ -1,16 +0,0 @@
1
- {% layout 'theme', name: "foo" %}
2
-
3
- Test Content
4
-
5
- <ol>
6
- {% for item in objects.item %}
7
- <li>
8
- <h3>Name: {{ item.name }}</h3>
9
- {% if item.description %}
10
- <p>
11
- Description: {{ item.description }}
12
- </p>
13
- {% endif %}
14
- </li>
15
- {% endfor %}
16
- </ol>
@@ -1,37 +0,0 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
- <meta name="viewport" content="width=device-width,initial-scale=1">
7
- <title>foo</title>
8
- </head>
9
- <body>
10
- <main role="main" tabindex="-1">
11
-
12
-
13
- Test Content
14
-
15
- <ol>
16
-
17
- <li>
18
- <h3>Name: this is an item</h3>
19
-
20
- <p>
21
- Description: ### Test Markdown
22
-
23
- This contains some simple _formatting_
24
-
25
- </p>
26
-
27
- </li>
28
-
29
- <li>
30
- <h3>Name: this is another item</h3>
31
-
32
- </li>
33
-
34
- </ol>
35
- </main>
36
- </body>
37
- </html>
@@ -1,100 +0,0 @@
1
- # This file was generated by the `rspec --init` command. Conventionally, all
2
- # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
- # The generated `.rspec` file contains `--require spec_helper` which will cause
4
- # this file to always be loaded, without a need to explicitly require it in any
5
- # files.
6
- #
7
- # Given that it is always loaded, you are encouraged to keep this file as
8
- # light-weight as possible. Requiring heavyweight dependencies from this file
9
- # will add to the boot time of your test suite on EVERY test run, even for an
10
- # individual file that may not need all of that loaded. Instead, consider making
11
- # a separate helper file that requires the additional dependencies and performs
12
- # the additional setup, and require it from the spec files that actually need
13
- # it.
14
- #
15
- # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
16
- RSpec.configure do |config|
17
- # rspec-expectations config goes here. You can use an alternate
18
- # assertion/expectation library such as wrong or the stdlib/minitest
19
- # assertions if you prefer.
20
- config.expect_with :rspec do |expectations|
21
- # This option will default to `true` in RSpec 4. It makes the `description`
22
- # and `failure_message` of custom matchers include text for helper methods
23
- # defined using `chain`, e.g.:
24
- # be_bigger_than(2).and_smaller_than(4).description
25
- # # => "be bigger than 2 and smaller than 4"
26
- # ...rather than:
27
- # # => "be bigger than 2"
28
- expectations.include_chain_clauses_in_custom_matcher_descriptions = true
29
- end
30
-
31
- # rspec-mocks config goes here. You can use an alternate test double
32
- # library (such as bogus or mocha) by changing the `mock_with` option here.
33
- config.mock_with :rspec do |mocks|
34
- # Prevents you from mocking or stubbing a method that does not exist on
35
- # a real object. This is generally recommended, and will default to
36
- # `true` in RSpec 4.
37
- mocks.verify_partial_doubles = true
38
- end
39
-
40
- # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
41
- # have no way to turn it off -- the option exists only for backwards
42
- # compatibility in RSpec 3). It causes shared context metadata to be
43
- # inherited by the metadata hash of host groups and examples, rather than
44
- # triggering implicit auto-inclusion in groups with matching metadata.
45
- config.shared_context_metadata_behavior = :apply_to_host_groups
46
-
47
- # The settings below are suggested to provide a good initial experience
48
- # with RSpec, but feel free to customize to your heart's content.
49
- =begin
50
- # This allows you to limit a spec run to individual examples or groups
51
- # you care about by tagging them with `:focus` metadata. When nothing
52
- # is tagged with `:focus`, all examples get run. RSpec also provides
53
- # aliases for `it`, `describe`, and `context` that include `:focus`
54
- # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
55
- config.filter_run_when_matching :focus
56
-
57
- # Allows RSpec to persist some state between runs in order to support
58
- # the `--only-failures` and `--next-failure` CLI options. We recommend
59
- # you configure your source control system to ignore this file.
60
- config.example_status_persistence_file_path = "spec/examples.txt"
61
-
62
- # Limits the available syntax to the non-monkey patched syntax that is
63
- # recommended. For more details, see:
64
- # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
65
- # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
66
- # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
67
- config.disable_monkey_patching!
68
-
69
- # This setting enables warnings. It's recommended, but in some cases may
70
- # be too noisy due to issues in dependencies.
71
- config.warnings = true
72
-
73
- # Many RSpec users commonly either run the entire suite or an individual
74
- # file, and it's useful to allow more verbose output when running an
75
- # individual spec file.
76
- if config.files_to_run.one?
77
- # Use the documentation formatter for detailed output,
78
- # unless a formatter has already been configured
79
- # (e.g. via a command-line flag).
80
- config.default_formatter = "doc"
81
- end
82
-
83
- # Print the 10 slowest examples and example groups at the
84
- # end of the spec run, to help surface which specs are running
85
- # particularly slow.
86
- config.profile_examples = 10
87
-
88
- # Run specs in random order to surface order dependencies. If you find an
89
- # order dependency and want to debug it, you can fix the order by providing
90
- # the seed, which is printed after each run.
91
- # --seed 1234
92
- config.order = :random
93
-
94
- # Seed global randomization in this process using the `--seed` CLI option.
95
- # Setting this allows you to use `--seed` to deterministically reproduce
96
- # test failures related to randomization by passing the same `--seed` value
97
- # as the one that triggered the failure.
98
- Kernel.srand config.seed
99
- =end
100
- end
@@ -1,149 +0,0 @@
1
- require 'tags/layout'
2
- require 'tmpdir'
3
- require 'fileutils'
4
-
5
- theme_content = """
6
- THEME_FILE {{ name }}
7
- {{page_content}}
8
- END_THEME
9
- """
10
- partial_content = """
11
- PARTIAL_CONTENT
12
- {{ name }}
13
- """
14
- basic_content = """
15
- THEME_FILE
16
-
17
- END_THEME
18
- """
19
- string_var_content = """
20
- THEME_FILE foo
21
-
22
- END_THEME
23
- """
24
- var_var_content = """
25
- THEME_FILE foo_var
26
-
27
- END_THEME
28
- """
29
- wrapped_content = """
30
- THEME_FILE
31
- page content
32
- END_THEME
33
- """
34
- wrapped_var_template = """
35
- {% assign name = 'name var' %}
36
- {% layout 'theme', name = {{ name }}%}
37
- Here is some page content for {{ name }}
38
- """
39
- wrapped_var_content = """
40
-
41
-
42
- THEME_FILE name var
43
-
44
- Here is some page content for name var
45
-
46
- END_THEME
47
- """
48
- partial_template = """
49
- {% assign name = 'partialpage' %}
50
- {% layout 'theme', name = {{ name }}%}
51
- The partial is here:
52
- {% include 'partial' %}
53
- and this is below it
54
- """
55
- partial_render_content = """
56
-
57
-
58
- THEME_FILE partialpage
59
-
60
- The partial is here:
61
-
62
- PARTIAL_CONTENT
63
- partialpage
64
-
65
- and this is below it
66
-
67
- END_THEME
68
- """
69
-
70
- RSpec.describe Layout do
71
- before(:all) do
72
- @cwd = Dir.mktmpdir
73
- Dir.chdir @cwd
74
- Dir.mkdir("layout")
75
- File.open("layout/theme.liquid", "w+") { |file|
76
- file.write(theme_content)
77
- }
78
- File.open("_partial.liquid", "w+") { |file|
79
- file.write(partial_content)
80
- }
81
- Liquid::Template.error_mode = :strict
82
- Liquid::Template.register_tag("layout", Layout)
83
- Layout.reset_cache()
84
- Liquid::Template.file_system = Liquid::LocalFileSystem.new(@cwd)
85
- end
86
-
87
- after(:all) do
88
- # puts "tmpdir: #{@cwd}"
89
- # FileUtils.rm_r(@cwd)
90
- end
91
-
92
- context "loading layouts" do
93
- it "loads layouts from a relative 'layout' dir" do
94
- content = Liquid::Template.parse("{% layout 'theme' %}")
95
- out = content.render()
96
- expect(out).to eq basic_content
97
- end
98
- it "errors when layout name doesn't exist" do
99
- content = Liquid::Template.parse("{% layout 'teme' %}")
100
- out = content.render()
101
- # Would be nice if this were a better error...
102
- expect(out).to eq "Liquid error: internal"
103
- end
104
- it "errors when syntax is wrong" do
105
- content = Liquid::Template.parse("{% layout teme pork %}")
106
- out = content.render()
107
- # Would be nice if this were a better error...
108
- expect(out).to eq "Liquid error: internal"
109
- end
110
- end
111
- context "variables" do
112
- it "accepts variable arguments that get rendered" do
113
- content = Liquid::Template.parse("{% layout 'theme', name: 'foo' %}")
114
- out = content.render()
115
- expect(out).to eq string_var_content
116
- end
117
- it "renders variable arguments that are variables" do
118
- content = Liquid::Template.parse("{% assign foo = 'foo_var' %}{% layout 'theme', name: {{foo}} %}")
119
- out = content.render()
120
- expect(out).to eq var_var_content
121
- end
122
- it "renders variable arguments that are passed in" do
123
- content = Liquid::Template.parse("{% layout 'theme', name: {{foo}} %}")
124
- out = content.render("foo" => "test")
125
- expect(out).to eq """
126
- THEME_FILE test
127
-
128
- END_THEME
129
- """
130
- end
131
- end
132
- context "wrapping & API" do
133
- it "wraps other content inside the layout" do
134
- content = Liquid::Template.parse("{% layout 'theme' %} page content")
135
- out = content.render()
136
- expect(out).to eq wrapped_content
137
- end
138
- it "properly renders variables in the inner content" do
139
- content = Liquid::Template.parse(wrapped_var_template)
140
- out = content.render()
141
- expect(out).to eq wrapped_var_content
142
- end
143
- it "properly renders partials in the inner content" do
144
- content = Liquid::Template.parse(partial_template)
145
- out = content.render()
146
- expect(out).to eq partial_render_content
147
- end
148
- end
149
- end