syntropy 0.11 → 0.12

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: 6f33d7721410d70a9d5b86977c73b36f6a410a6534c253269df5f2d47123a54f
4
- data.tar.gz: 6f961a74dd9fa299296d6699244076dfc09fa3697faad7c28cc6c2db81f5fb46
3
+ metadata.gz: 18d6c37aa12dcf2315d95bc656d1cbf196ada1dd0e2309b0f1bf1ca8b65a1cbb
4
+ data.tar.gz: 04f12a324d704814f45d9218e6e02d0d38469dbed753dc8202009568f447d400
5
5
  SHA512:
6
- metadata.gz: 158e46fd1e09da1af72a5ffd50a1ccde7699ce52f9a9d7a317903e3aa29234a5f924371712571b4d0188bcc5e7484b7bced4be7ee7440140ba5cfb07b492bccf
7
- data.tar.gz: 6a45ef64e1ef65cf5c86c15dd5858a3f028343c55f68be253d07626800c4f534782898e4e7d83697fb324b4169050ce913a911575d31936c5a852e12f0eb4be0
6
+ metadata.gz: c62d9b26c9754c23bfc53dd25c1d698733e1d01b703d580db17cfeed1505c36f3f382fcd762ef0e91e641505cda26af03a328e549a840f9f7af4b2ab7c582bc0
7
+ data.tar.gz: 0577b8d2fda40cb40c81419c31c7f515230f7948ab49158a7ca2d647fe71a323d51b176003d976b1e5428fe4ead6415064321340c0e20b5c84806d1e52266ce0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ # 0.12 2025-08-28
2
+
3
+ - Add routing info to request: `#route`, `#route_params`
4
+ - Improve validations
5
+ - Improve errors
6
+ - Reimplement `App`
7
+ - Add support for parametric routes
8
+ - Reimplement `RoutingTree` (was `Router`)
9
+
1
10
  ## 0.11 2025-08-17
2
11
 
3
12
  - Upgrade to P2 2.8
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ end
10
10
  task :release do
11
11
  require_relative './lib/syntropy/version'
12
12
  version = Syntropy::VERSION
13
-
13
+
14
14
  puts 'Building syntropy...'
15
15
  `gem build syntropy.gemspec`
16
16
 
data/TODO.md CHANGED
@@ -1,137 +1,182 @@
1
- - a way to inject cookies into the response
2
-
3
- - add support for applets
4
-
5
- - can be implemented as separate gems
6
- - can route requests to a different directory (i.e. inside the gem directory)
7
- - simple way to instantiate and setup the applet
8
- - as a first example, implement an auth/signin applet:
9
- - session hook
10
- - session persistence
11
- - login page
12
- - support for custom behaviour and custom workflows (2FA, signin using OTP etc.)
13
-
14
- - Some standard middleware:
15
-
16
- - request rewriter
17
- - logger
18
- - auth
19
- - selector + terminator
20
-
21
- ```Ruby
22
- # For the chainable DSL shown below, we need to create a custom class:
23
- class Syntropy::Middleware::Selector
24
- def initialize(select_proc, terminator_proc = nil)
25
- @select_proc = select_proc
26
- @terminator_proc = terminator_proc
27
- end
28
-
29
- def to_proc
30
- ->(req, proc) {
31
- @select_proc.(req) ? @terminator_proc.(req) : proc(req)
32
- }
33
- end
34
-
35
- def terminate(&proc)
36
- @terminator_proc = proc
37
- end
1
+ ## Support for applets
2
+
3
+ - can be implemented as separate gems
4
+ - can route requests to a different directory (i.e. inside the gem directory)
5
+ - simple way to instantiate and setup the applet
6
+ - as a first example, implement an auth/signin applet:
7
+ - session hook
8
+ - session persistence
9
+ - login page
10
+ - support for custom behaviour and custom workflows (2FA, signin using OTP etc.)
11
+
12
+ Example usage:
13
+
14
+ ```ruby
15
+ # /admin+.rb
16
+ require 'syntropy/admin'
17
+
18
+ export Syntropy::Admin.new(@ref, @env)
19
+ ```
20
+
21
+ Implementation:
22
+
23
+ ```ruby
24
+ # syntropy-admin/lib/syntropy/admin.rb
25
+ APP_ROOT = File.expand_path(File.join(__dir__, '../../app'))
26
+
27
+ class Syntropy::Admin < Syntropy::App
28
+ def new(mount_path, env)
29
+ super(env[:machine], APP_ROOT, mount_path, env)
30
+ end
31
+ end
32
+ ```
33
+
34
+ ## Response: cookies and headers
35
+
36
+ We need a way to inject cookies into the response. This probably should be done
37
+ in the TP2 code:
38
+
39
+ ```ruby
40
+ @@default_set_cookie_attr = 'HttpOnly'
41
+ def self.default_set_cookie_attr=(v)
42
+ @@default_set_cookie_attr = v
43
+ end
44
+
45
+ def set_cookie(key, value, attr = @@default_set_cookie_attr)
46
+ @buffered_headers ||= +''
47
+ @buffered_headers << format(
48
+ "Set-Cookie: %<key>s=%<value>s; %<attr>s\n",
49
+ key:, value:, attr:
50
+ )
51
+ end
52
+
53
+ def set_headers(headers)
54
+ @buffered_headers ||= +''
55
+ @buffered_headers << format_headers(headers)
56
+ end
57
+
58
+ ...
59
+
60
+ req.set_cookie('at', 'foobar', 'SameSite=none; Secure; HttpOnly')
61
+ ```
62
+
63
+ ## Middleware
64
+
65
+ Some standard middleware:
66
+
67
+ - request rewriter
68
+ - logger
69
+ - auth
70
+ - selector + terminator
71
+
72
+ ```Ruby
73
+ # For the chainable DSL shown below, we need to create a custom class:
74
+ class Syntropy::Middleware::Selector
75
+ def initialize(select_proc, terminator_proc = nil)
76
+ @select_proc = select_proc
77
+ @terminator_proc = terminator_proc
38
78
  end
39
79
 
40
- def Syntropy
41
- ```
42
-
43
- ```Ruby
44
- # a _site.rb file can be used to wrap a whole app
45
- # site/_site.rb
46
-
47
- # this means we route according to the host header, with each
48
- export Syntropy.route_by_host
49
-
50
- # we can also rewrite requests:
51
- rewriter = Syntropy
52
- .select { it.host =~ /^tolkora\.(org|com)$/ }
53
- .terminate { it.redirect_permanent('https://tolkora.net') }
54
-
55
- # This is actuall a pretty interesting DSL design:
56
- # a chain of operations that compose functions. So, we can select a
57
- export rewriter.wrap(default_app)
58
-
59
- # composing
60
- export rewriter.wrap(Syntropy.some_custom_app.wrap(app))
61
-
62
- # or maybe
63
- export rewriter << some_other_middleware << app
64
- ```
65
-
66
-
67
-
68
-
69
- - CLI tool for setting up a site repo:
70
-
71
- ```bash
72
- # clone a newly created repo
73
- ~/repo$ git clone https://github.com/foo/bar
74
- ...
75
- ~/repo$ syntropy setup bar
76
-
77
- (syntropy banner)
78
-
79
- Setting up Syntropy project in /home/sharon/repo/bar:
80
-
81
- bar/
82
- bin/
83
- start
84
- stop
85
- restart
86
- console
87
- server
88
- docker-compose.yml
89
- Dockerfile
90
- Gemfile
91
- proxy/
92
-
93
- README.md
94
- site/
95
- _layout/
96
- default.rb
97
- _lib/
98
- about.md
99
- articles/
100
- long-form.md
101
- assets/
102
- js/
103
- css/
104
- style.css
105
- img/
106
- syntropy.png
107
- index.rb
108
- ```
109
-
110
- - Some of the files might need templating, but we can maybe do without, or at
111
- least make it as generic as possible.
112
-
113
- - `syntropy setup` steps:
114
-
115
- 1. Verify existence of target directory
116
- 2. Copy files from Syntropy template to target directory
117
- 3. Do chmod +x for bin/*
118
- 4. Do bundle install in the target directory
119
- 5. Show some information with regard to how to get started working with the
120
- repo
121
-
122
- - `syntropy provision` steps:
123
-
124
- 1. Verify Ubuntu 22.x or higher
125
- 2. Install git, docker, docker-compose
126
-
127
- - `syntropy deploy` steps:
128
-
129
- 1. Verify no uncommitted changes.
130
- 2. SSH to remote machine.
131
- 2.1. If not exists, clone repo
132
- 2.2. Otherwise, verify remote machine repo is on same branch as local repo
133
- 2.3. Do a git pull (what about credentials?)
134
- 2.4. If gem bundle has changed, do a docker compose build
135
- 2.5. If docker compose services are running, restart
136
- 2.6. Otherwise, start services
137
- 2.7. Verify service is running correctly
80
+ def to_proc
81
+ ->(req, proc) {
82
+ @select_proc.(req) ? @terminator_proc.(req) : proc(req)
83
+ }
84
+ end
85
+
86
+ def terminate(&proc)
87
+ @terminator_proc = proc
88
+ end
89
+ end
90
+ ```
91
+
92
+ ```Ruby
93
+ # a _site.rb file can be used to wrap a whole app
94
+ # site/_site.rb
95
+
96
+ # this means we route according to the host header, with each
97
+ export Syntropy.route_by_host
98
+
99
+ # we can also rewrite requests:
100
+ rewriter = Syntropy
101
+ .select { it.host =~ /^tolkora\.(org|com)$/ }
102
+ .terminate { it.redirect_permanent('https://tolkora.net') }
103
+
104
+ # This is actuall a pretty interesting DSL design:
105
+ # a chain of operations that compose functions. So, we can select a
106
+ export rewriter.wrap(default_app)
107
+
108
+ # composing
109
+ export rewriter.wrap(Syntropy.some_custom_app.wrap(app))
110
+
111
+ # or maybe
112
+ export rewriter << some_other_middleware << app
113
+ ```
114
+
115
+ ## CLI tool for setting up a site repo:
116
+
117
+ ```bash
118
+ # clone a newly created repo
119
+ ~/repo$ git clone https://github.com/foo/bar
120
+ ...
121
+ ~/repo$ syntropy setup bar
122
+
123
+ (syntropy banner)
124
+
125
+ Setting up Syntropy project in /home/sharon/repo/bar:
126
+
127
+ bar/
128
+ bin/
129
+ start
130
+ stop
131
+ restart
132
+ console
133
+ server
134
+ docker-compose.yml
135
+ Dockerfile
136
+ Gemfile
137
+ proxy/
138
+ README.md
139
+ site/
140
+ _layout/
141
+ default.rb
142
+ _lib/
143
+ about.md
144
+ articles/
145
+ long-form.md
146
+ assets/
147
+ js/
148
+ css/
149
+ style.css
150
+ img/
151
+ syntropy.png
152
+ index.rb
153
+ ```
154
+
155
+ Some of the files might need templating, but we can maybe do without, or at
156
+ least make it as generic as possible.
157
+
158
+ `syntropy setup` steps:
159
+
160
+ 1. Verify existence of target directory
161
+ 2. Copy files from Syntropy template to target directory
162
+ 3. Do chmod +x for bin/*
163
+ 4. Do bundle install in the target directory
164
+ 5. Show some information with regard to how to get started working with the
165
+ repo
166
+
167
+ `syntropy provision` steps:
168
+
169
+ 1. Verify Ubuntu 22.x or higher
170
+ 2. Install git, docker, docker-compose
171
+
172
+ `syntropy deploy` steps:
173
+
174
+ 1. Verify no uncommitted changes.
175
+ 2. SSH to remote machine.
176
+ 2.1. If not exists, clone repo
177
+ 2.2. Otherwise, verify remote machine repo is on same branch as local repo
178
+ 2.3. Do a git pull (what about credentials?)
179
+ 2.4. If gem bundle has changed, do a docker compose build
180
+ 2.5. If docker compose services are running, restart
181
+ 2.6. Otherwise, start services
182
+ 2.7. Verify service is running correctly
data/bin/syntropy CHANGED
@@ -5,6 +5,7 @@ require 'syntropy'
5
5
  require 'optparse'
6
6
 
7
7
  opts = {
8
+ mount_path: '/',
8
9
  banner: Syntropy::BANNER,
9
10
  logger: true
10
11
  }
@@ -32,6 +33,10 @@ parser = OptionParser.new do |o|
32
33
  exit
33
34
  end
34
35
 
36
+ o.on('-m', '--mount', 'Set mount path (default: /)') do
37
+ opts[:mount_path] = it
38
+ end
39
+
35
40
  o.on('-v', '--version', 'Show version') do
36
41
  require 'syntropy/version'
37
42
  puts "Syntropy version #{Syntropy::VERSION}"
@@ -49,10 +54,10 @@ rescue StandardError => e
49
54
  exit
50
55
  end
51
56
 
52
- opts[:location] = ARGV.shift || '.'
57
+ opts[:root_dir] = ARGV.shift || '.'
53
58
 
54
- if !File.directory?(opts[:location])
55
- puts "#{File.expand_path(opts[:location])} Not a directory"
59
+ if !File.directory?(opts[:root_dir])
60
+ puts "#{File.expand_path(opts[:root_dir])} Not a directory"
56
61
  exit
57
62
  end
58
63