sup 1.1 → 1.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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/checks.yml +40 -38
  3. data/.gitmodules +1 -0
  4. data/CONTRIBUTORS +3 -1
  5. data/History.txt +32 -3
  6. data/Manifest.txt +34 -1
  7. data/README.md +0 -1
  8. data/bin/sup-sync-back-maildir +1 -1
  9. data/contrib/nix/Gemfile +24 -0
  10. data/contrib/nix/Gemfile.lock +101 -0
  11. data/contrib/nix/README +7 -0
  12. data/contrib/nix/gem-install-shell.nix +14 -0
  13. data/contrib/nix/gemset.nix +391 -0
  14. data/contrib/nix/ruby2.4-Gemfile.lock +85 -0
  15. data/contrib/nix/ruby2.4-gemset.nix +329 -0
  16. data/contrib/nix/ruby2.4-shell.nix +26 -0
  17. data/contrib/nix/ruby2.5-Gemfile.lock +85 -0
  18. data/contrib/nix/ruby2.5-gemset.nix +329 -0
  19. data/contrib/nix/ruby2.5-shell.nix +26 -0
  20. data/contrib/nix/ruby2.6-Gemfile.lock +87 -0
  21. data/contrib/nix/ruby2.6-gemset.nix +339 -0
  22. data/contrib/nix/ruby2.6-shell.nix +26 -0
  23. data/contrib/nix/ruby2.7-Gemfile.lock +91 -0
  24. data/contrib/nix/ruby2.7-gemset.nix +359 -0
  25. data/contrib/nix/ruby2.7-shell.nix +14 -0
  26. data/contrib/nix/ruby3.0-Gemfile.lock +91 -0
  27. data/contrib/nix/ruby3.0-gemset.nix +359 -0
  28. data/contrib/nix/ruby3.0-shell.nix +14 -0
  29. data/contrib/nix/ruby3.1-shell.nix +25 -0
  30. data/contrib/nix/ruby3.2-shell.nix +25 -0
  31. data/contrib/nix/ruby3.3-shell.nix +25 -0
  32. data/contrib/nix/ruby3.4-shell.nix +36 -0
  33. data/contrib/nix/test-all-rubies.sh +6 -0
  34. data/doc/Hooks.txt +1 -1
  35. data/ext/mkrf_conf_xapian.rb +2 -2
  36. data/lib/sup/crypto.rb +8 -6
  37. data/lib/sup/index.rb +2 -2
  38. data/lib/sup/maildir.rb +5 -1
  39. data/lib/sup/mbox.rb +26 -8
  40. data/lib/sup/message.rb +15 -12
  41. data/lib/sup/modes/console_mode.rb +1 -1
  42. data/lib/sup/modes/edit_message_mode.rb +5 -5
  43. data/lib/sup/thread.rb +20 -20
  44. data/lib/sup/util.rb +12 -7
  45. data/lib/sup/version.rb +1 -1
  46. data/man/sup-add.1 +40 -40
  47. data/man/sup-config.1 +30 -26
  48. data/man/sup-dump.1 +38 -38
  49. data/man/sup-import-dump.1 +41 -37
  50. data/man/sup-psych-ify-config-files.1 +32 -28
  51. data/man/sup-recover-sources.1 +39 -35
  52. data/man/sup-sync-back-maildir.1 +39 -34
  53. data/man/sup-sync.1 +50 -46
  54. data/man/sup-tweak-labels.1 +43 -38
  55. data/man/sup.1 +42 -38
  56. data/shell.nix +1 -0
  57. data/sup.gemspec +2 -0
  58. data/test/dummy_source.rb +6 -0
  59. data/test/fixtures/embedded-message-rfc6532.eml +33 -0
  60. data/test/fixtures/invalid-date.eml +8 -0
  61. data/test/gnupg_test_home/private-keys-v1.d/26C05E44706A8E230B3255BB9532B34DC9420232.key +42 -0
  62. data/test/gnupg_test_home/private-keys-v1.d/D187ADC90EC4DEB7047678EAA37E33A53A465D47.key +5 -0
  63. data/test/gnupg_test_home/private-keys-v1.d/FB2D9BD3B1BE90B5BCF697781F8404224B0FCF5B.key +5 -0
  64. data/test/gnupg_test_home/pubring.gpg +0 -0
  65. data/test/gnupg_test_home/receiver_pubring.gpg +0 -0
  66. data/test/gnupg_test_home/receiver_secring.gpg +0 -0
  67. data/test/gnupg_test_home/regen_keys.sh +11 -2
  68. data/test/gnupg_test_home/secring.gpg +0 -0
  69. data/test/gnupg_test_home/sup-test-2@foo.bar.asc +20 -20
  70. data/test/integration/test_maildir.rb +18 -1
  71. data/test/integration/test_mbox.rb +13 -0
  72. data/test/integration/test_sup-sync-back-maildir.rb +40 -0
  73. data/test/test_crypto.rb +108 -71
  74. data/test/test_header_parsing.rb +2 -2
  75. data/test/test_message.rb +42 -0
  76. data/test/unit/test_contact.rb +1 -1
  77. data/test/unit/test_edit_message_mode.rb +94 -0
  78. data/test/unit/test_person.rb +3 -3
  79. data/test/unit/test_rmail_message.rb +36 -0
  80. data/test/unit/util/test_string.rb +3 -3
  81. metadata +73 -5
  82. data/test/gnupg_test_home/private-keys-v1.d/306D2EE90FF0014B5B9FD07E265C751791674140.key +0 -0
@@ -0,0 +1,359 @@
1
+ {
2
+ ast = {
3
+ groups = ["default"];
4
+ platforms = [];
5
+ source = {
6
+ remotes = ["https://rubygems.org"];
7
+ sha256 = "04nc8x27hlzlrr5c2gn7mar4vdr0apw5xg22wp6m8dx3wqr04a0y";
8
+ type = "gem";
9
+ };
10
+ version = "2.4.2";
11
+ };
12
+ benchmark = {
13
+ groups = ["default"];
14
+ platforms = [];
15
+ source = {
16
+ remotes = ["https://rubygems.org"];
17
+ sha256 = "0jl71qcgamm96dzyqk695j24qszhcc7liw74qc83fpjljp2gh4hg";
18
+ type = "gem";
19
+ };
20
+ version = "0.4.0";
21
+ };
22
+ chronic = {
23
+ groups = ["default"];
24
+ platforms = [];
25
+ source = {
26
+ remotes = ["https://rubygems.org"];
27
+ sha256 = "1hrdkn4g8x7dlzxwb1rfgr8kw3bp4ywg5l4y4i9c2g5cwv62yvvn";
28
+ type = "gem";
29
+ };
30
+ version = "0.10.2";
31
+ };
32
+ coderay = {
33
+ groups = ["default"];
34
+ platforms = [];
35
+ source = {
36
+ remotes = ["https://rubygems.org"];
37
+ sha256 = "0jvxqxzply1lwp7ysn94zjhh57vc14mcshw1ygw14ib8lhc00lyw";
38
+ type = "gem";
39
+ };
40
+ version = "1.1.3";
41
+ };
42
+ fiddle = {
43
+ groups = ["default"];
44
+ platforms = [];
45
+ source = {
46
+ remotes = ["https://rubygems.org"];
47
+ sha256 = "1as92bp6pgkab73kj3mh5d1idjr9wykczz7r9i1pkn82wq4xks3r";
48
+ type = "gem";
49
+ };
50
+ version = "1.1.6";
51
+ };
52
+ gpgme = {
53
+ dependencies = ["mini_portile2"];
54
+ groups = ["default"];
55
+ platforms = [];
56
+ source = {
57
+ remotes = ["https://rubygems.org"];
58
+ sha256 = "0r1vmql7w7ka5xzj1aqf8pk2a4sv0znwj2zkg1fgvd5b89qcvv2k";
59
+ type = "gem";
60
+ };
61
+ version = "2.0.24";
62
+ };
63
+ highline = {
64
+ groups = ["default"];
65
+ platforms = [];
66
+ source = {
67
+ remotes = ["https://rubygems.org"];
68
+ sha256 = "02ghhvigqbq4252gsi4w8a9klkdkybmbz29ghfp1y6sqzlcb466a";
69
+ type = "gem";
70
+ };
71
+ version = "3.0.1";
72
+ };
73
+ json = {
74
+ groups = ["default"];
75
+ platforms = [];
76
+ source = {
77
+ remotes = ["https://rubygems.org"];
78
+ sha256 = "0b4qsi8gay7ncmigr0pnbxyb17y3h8kavdyhsh7nrlqwr35vb60q";
79
+ type = "gem";
80
+ };
81
+ version = "2.7.2";
82
+ };
83
+ language_server-protocol = {
84
+ groups = ["default"];
85
+ platforms = [];
86
+ source = {
87
+ remotes = ["https://rubygems.org"];
88
+ sha256 = "0gvb1j8xsqxms9mww01rmdl78zkd72zgxaap56bhv8j45z05hp1x";
89
+ type = "gem";
90
+ };
91
+ version = "3.17.0.3";
92
+ };
93
+ locale = {
94
+ groups = ["default"];
95
+ platforms = [];
96
+ source = {
97
+ remotes = ["https://rubygems.org"];
98
+ sha256 = "107pm4ccmla23z963kyjldgngfigvchnv85wr6m69viyxxrrjbsj";
99
+ type = "gem";
100
+ };
101
+ version = "2.1.4";
102
+ };
103
+ lockfile = {
104
+ groups = ["default"];
105
+ platforms = [];
106
+ source = {
107
+ remotes = ["https://rubygems.org"];
108
+ sha256 = "0dij3ijywylvfgrpi2i0k17f6w0wjhnjjw0k9030f54z56cz7jrr";
109
+ type = "gem";
110
+ };
111
+ version = "2.1.3";
112
+ };
113
+ method_source = {
114
+ groups = ["default"];
115
+ platforms = [];
116
+ source = {
117
+ remotes = ["https://rubygems.org"];
118
+ sha256 = "1igmc3sq9ay90f8xjvfnswd1dybj1s3fi0dwd53inwsvqk4h24qq";
119
+ type = "gem";
120
+ };
121
+ version = "1.1.0";
122
+ };
123
+ mime-types = {
124
+ dependencies = ["mime-types-data"];
125
+ groups = ["default"];
126
+ platforms = [];
127
+ source = {
128
+ remotes = ["https://rubygems.org"];
129
+ sha256 = "1r64z0m5zrn4k37wabfnv43wa6yivgdfk6cf2rpmmirlz889yaf1";
130
+ type = "gem";
131
+ };
132
+ version = "3.5.2";
133
+ };
134
+ mime-types-data = {
135
+ groups = ["default"];
136
+ platforms = [];
137
+ source = {
138
+ remotes = ["https://rubygems.org"];
139
+ sha256 = "00x7w5xqsj9m33v3vkmy23wipkkysafksib53ypzn27p5g81w455";
140
+ type = "gem";
141
+ };
142
+ version = "3.2024.0305";
143
+ };
144
+ mini_portile2 = {
145
+ groups = ["default"];
146
+ platforms = [];
147
+ source = {
148
+ remotes = ["https://rubygems.org"];
149
+ sha256 = "149r94xi6b3jbp6bv72f8383b95ndn0p5sxnq11gs1j9jadv0ajf";
150
+ type = "gem";
151
+ };
152
+ version = "2.8.6";
153
+ };
154
+ minitest = {
155
+ groups = ["default"];
156
+ platforms = [];
157
+ source = {
158
+ remotes = ["https://rubygems.org"];
159
+ sha256 = "07lq26b86giy3ha3fhrywk9r1ajhc2pm2mzj657jnpnbj1i6g17a";
160
+ type = "gem";
161
+ };
162
+ version = "5.22.3";
163
+ };
164
+ ncursesw = {
165
+ groups = ["default"];
166
+ platforms = [];
167
+ source = {
168
+ remotes = ["https://rubygems.org"];
169
+ sha256 = "0qlfhp9b445g0qp9kkdiylfjlpfzrv6nqvry4ar6y0yacn0zr5y8";
170
+ type = "gem";
171
+ };
172
+ version = "1.4.11";
173
+ };
174
+ optimist = {
175
+ groups = ["default"];
176
+ platforms = [];
177
+ source = {
178
+ remotes = ["https://rubygems.org"];
179
+ sha256 = "0q4jqq3v1bxlfr9jgqmahnygkvl81lr6s1rhm8qg66c9xr9nz241";
180
+ type = "gem";
181
+ };
182
+ version = "3.1.0";
183
+ };
184
+ parallel = {
185
+ groups = ["default"];
186
+ platforms = [];
187
+ source = {
188
+ remotes = ["https://rubygems.org"];
189
+ sha256 = "15wkxrg1sj3n1h2g8jcrn7gcapwcgxr659ypjf75z1ipkgxqxwsv";
190
+ type = "gem";
191
+ };
192
+ version = "1.24.0";
193
+ };
194
+ parser = {
195
+ dependencies = ["ast" "racc"];
196
+ groups = ["default"];
197
+ platforms = [];
198
+ source = {
199
+ remotes = ["https://rubygems.org"];
200
+ sha256 = "11r6kp8wam0nkfvnwyc1fmvky102r1vcfr84vi2p1a2wa0z32j3p";
201
+ type = "gem";
202
+ };
203
+ version = "3.3.0.5";
204
+ };
205
+ pry = {
206
+ dependencies = ["coderay" "method_source"];
207
+ groups = ["default"];
208
+ platforms = [];
209
+ source = {
210
+ remotes = ["https://rubygems.org"];
211
+ sha256 = "0k9kqkd9nps1w1r1rb7wjr31hqzkka2bhi8b518x78dcxppm9zn4";
212
+ type = "gem";
213
+ };
214
+ version = "0.14.2";
215
+ };
216
+ racc = {
217
+ groups = ["default"];
218
+ platforms = [];
219
+ source = {
220
+ remotes = ["https://rubygems.org"];
221
+ sha256 = "01b9662zd2x9bp4rdjfid07h09zxj7kvn7f5fghbqhzc625ap1dp";
222
+ type = "gem";
223
+ };
224
+ version = "1.7.3";
225
+ };
226
+ rainbow = {
227
+ groups = ["default"];
228
+ platforms = [];
229
+ source = {
230
+ remotes = ["https://rubygems.org"];
231
+ sha256 = "0smwg4mii0fm38pyb5fddbmrdpifwv22zv3d3px2xx497am93503";
232
+ type = "gem";
233
+ };
234
+ version = "3.1.1";
235
+ };
236
+ rake = {
237
+ groups = ["default"];
238
+ platforms = [];
239
+ source = {
240
+ remotes = ["https://rubygems.org"];
241
+ sha256 = "17850wcwkgi30p7yqh60960ypn7yibacjjha0av78zaxwvd3ijs6";
242
+ type = "gem";
243
+ };
244
+ version = "13.2.1";
245
+ };
246
+ regexp_parser = {
247
+ groups = ["default"];
248
+ platforms = [];
249
+ source = {
250
+ remotes = ["https://rubygems.org"];
251
+ sha256 = "1ndxm0xnv27p4gv6xynk6q41irckj76q1jsqpysd9h6f86hhp841";
252
+ type = "gem";
253
+ };
254
+ version = "2.9.0";
255
+ };
256
+ rexml = {
257
+ groups = ["default"];
258
+ platforms = [];
259
+ source = {
260
+ remotes = ["https://rubygems.org"];
261
+ sha256 = "05i8518ay14kjbma550mv0jm8a6di8yp5phzrd8rj44z9qnrlrp0";
262
+ type = "gem";
263
+ };
264
+ version = "3.2.6";
265
+ };
266
+ rmail = {
267
+ groups = ["default"];
268
+ platforms = [];
269
+ source = {
270
+ remotes = ["https://rubygems.org"];
271
+ sha256 = "0m5npkmv764m725wzjzasgf3k8q5anf3vfr6k2cac1xj6jc8lcqi";
272
+ type = "gem";
273
+ };
274
+ version = "1.1.4";
275
+ };
276
+ rr = {
277
+ groups = ["default"];
278
+ platforms = [];
279
+ source = {
280
+ remotes = ["https://rubygems.org"];
281
+ sha256 = "1n9g78ba4c2zzmz8cdb97c38h1xm0clircag00vbcxwqs4dq0ymp";
282
+ type = "gem";
283
+ };
284
+ version = "1.2.1";
285
+ };
286
+ rubocop = {
287
+ dependencies = ["json" "language_server-protocol" "parallel" "parser" "rainbow" "regexp_parser" "rexml" "rubocop-ast" "ruby-progressbar" "unicode-display_width"];
288
+ groups = ["default"];
289
+ platforms = [];
290
+ source = {
291
+ remotes = ["https://rubygems.org"];
292
+ sha256 = "1dmj955zbvhlrzzag6hc77xdyyzn8ihvffpjalnzn5asxhz7jcdl";
293
+ type = "gem";
294
+ };
295
+ version = "1.63.2";
296
+ };
297
+ rubocop-ast = {
298
+ dependencies = ["parser"];
299
+ groups = ["default"];
300
+ platforms = [];
301
+ source = {
302
+ remotes = ["https://rubygems.org"];
303
+ sha256 = "1v3q8n48w8h809rqbgzihkikr4g3xk72m1na7s97jdsmjjq6y83w";
304
+ type = "gem";
305
+ };
306
+ version = "1.31.2";
307
+ };
308
+ rubocop-packaging = {
309
+ dependencies = ["rubocop"];
310
+ groups = ["default"];
311
+ platforms = [];
312
+ source = {
313
+ remotes = ["https://rubygems.org"];
314
+ sha256 = "1iqgsbpj7y8ksddbb9gj5vpzs2y8202khyk2mcc165kkfmvm6rx3";
315
+ type = "gem";
316
+ };
317
+ version = "0.5.2";
318
+ };
319
+ ruby-progressbar = {
320
+ groups = ["default"];
321
+ platforms = [];
322
+ source = {
323
+ remotes = ["https://rubygems.org"];
324
+ sha256 = "0cwvyb7j47m7wihpfaq7rc47zwwx9k4v7iqd9s1xch5nm53rrz40";
325
+ type = "gem";
326
+ };
327
+ version = "1.13.0";
328
+ };
329
+ unicode = {
330
+ groups = ["default"];
331
+ platforms = [];
332
+ source = {
333
+ remotes = ["https://rubygems.org"];
334
+ sha256 = "1mx9lwzy021lpcqql5kn4yi20njhf5h7c7wxm2fx51p1r2zr9wj2";
335
+ type = "gem";
336
+ };
337
+ version = "0.4.4.5";
338
+ };
339
+ unicode-display_width = {
340
+ groups = ["default"];
341
+ platforms = [];
342
+ source = {
343
+ remotes = ["https://rubygems.org"];
344
+ sha256 = "1d0azx233nags5jx3fqyr23qa2rhgzbhv8pxp46dgbg1mpf82xky";
345
+ type = "gem";
346
+ };
347
+ version = "2.5.0";
348
+ };
349
+ xapian-ruby = {
350
+ groups = ["default"];
351
+ platforms = [];
352
+ source = {
353
+ remotes = ["https://rubygems.org"];
354
+ sha256 = "0xlzgk2sis7nnasiplpg6x7mdvqa17ahq2d27i8fd5hs8dmqcsh2";
355
+ type = "gem";
356
+ };
357
+ version = "1.4.22";
358
+ };
359
+ }
@@ -0,0 +1,14 @@
1
+ let
2
+ pkgs = import (builtins.fetchGit {
3
+ url = "https://github.com/NixOS/nixpkgs";
4
+ ref = "refs/heads/master";
5
+ rev = "402cc3633cc60dfc50378197305c984518b30773";
6
+ }) {};
7
+ gems = pkgs.bundlerEnv {
8
+ name = "ruby3.0-gems-for-sup";
9
+ ruby = pkgs.ruby_3_0;
10
+ gemfile = ./Gemfile;
11
+ lockfile = ./ruby3.0-Gemfile.lock;
12
+ gemset = ./ruby3.0-gemset.nix;
13
+ };
14
+ in pkgs.mkShell { packages = [ gems gems.wrappedRuby pkgs.pandoc ]; }
@@ -0,0 +1,25 @@
1
+ let
2
+ pkgs = import (builtins.fetchGit {
3
+ url = "https://github.com/NixOS/nixpkgs";
4
+ ref = "refs/heads/master";
5
+ rev = "5d0ebea1934d80948ff7b84f3b06e4ec9d99ee49";
6
+ }) {};
7
+ gems = pkgs.bundlerEnv {
8
+ name = "ruby3.1-gems-for-sup";
9
+ ruby = pkgs.ruby_3_1;
10
+ gemfile = ./Gemfile;
11
+ lockfile = ./Gemfile.lock;
12
+ gemset = ./gemset.nix;
13
+ gemConfig = pkgs.defaultGemConfig // {
14
+ # Workaround for Sup issue #623
15
+ ncursesw = attrs: pkgs.defaultGemConfig.ncursesw attrs // {
16
+ src = pkgs.fetchFromGitHub {
17
+ owner = "danc86";
18
+ repo = "ncursesw-ruby";
19
+ rev = "43cfa21f781e9412dc73d0d4a44b3ec0bf4a3c8d";
20
+ hash = "sha256-MkXFwhbtL9aJOMqn1IR5DKMXcnKHzICjb/rVhDDLL94=";
21
+ };
22
+ };
23
+ };
24
+ };
25
+ in pkgs.mkShell { packages = [ gems gems.wrappedRuby pkgs.pandoc ]; }
@@ -0,0 +1,25 @@
1
+ let
2
+ pkgs = import (builtins.fetchGit {
3
+ url = "https://github.com/NixOS/nixpkgs";
4
+ ref = "refs/heads/master";
5
+ rev = "5d0ebea1934d80948ff7b84f3b06e4ec9d99ee49";
6
+ }) {};
7
+ gems = pkgs.bundlerEnv {
8
+ name = "ruby3.2-gems-for-sup";
9
+ ruby = pkgs.ruby_3_2;
10
+ gemfile = ./Gemfile;
11
+ lockfile = ./Gemfile.lock;
12
+ gemset = ./gemset.nix;
13
+ gemConfig = pkgs.defaultGemConfig // {
14
+ # Workaround for Sup issue #623
15
+ ncursesw = attrs: pkgs.defaultGemConfig.ncursesw attrs // {
16
+ src = pkgs.fetchFromGitHub {
17
+ owner = "danc86";
18
+ repo = "ncursesw-ruby";
19
+ rev = "43cfa21f781e9412dc73d0d4a44b3ec0bf4a3c8d";
20
+ hash = "sha256-MkXFwhbtL9aJOMqn1IR5DKMXcnKHzICjb/rVhDDLL94=";
21
+ };
22
+ };
23
+ };
24
+ };
25
+ in pkgs.mkShell { packages = [ gems gems.wrappedRuby pkgs.pandoc ]; }
@@ -0,0 +1,25 @@
1
+ let
2
+ pkgs = import (builtins.fetchGit {
3
+ url = "https://github.com/NixOS/nixpkgs";
4
+ ref = "refs/heads/master";
5
+ rev = "5d0ebea1934d80948ff7b84f3b06e4ec9d99ee49";
6
+ }) {};
7
+ gems = pkgs.bundlerEnv {
8
+ name = "ruby3.3-gems-for-sup";
9
+ ruby = pkgs.ruby_3_3;
10
+ gemfile = ./Gemfile;
11
+ lockfile = ./Gemfile.lock;
12
+ gemset = ./gemset.nix;
13
+ gemConfig = pkgs.defaultGemConfig // {
14
+ # Workaround for Sup issue #623
15
+ ncursesw = attrs: pkgs.defaultGemConfig.ncursesw attrs // {
16
+ src = pkgs.fetchFromGitHub {
17
+ owner = "danc86";
18
+ repo = "ncursesw-ruby";
19
+ rev = "43cfa21f781e9412dc73d0d4a44b3ec0bf4a3c8d";
20
+ hash = "sha256-MkXFwhbtL9aJOMqn1IR5DKMXcnKHzICjb/rVhDDLL94=";
21
+ };
22
+ };
23
+ };
24
+ };
25
+ in pkgs.mkShell { packages = [ gems gems.wrappedRuby pkgs.pandoc ]; }
@@ -0,0 +1,36 @@
1
+ let
2
+ pkgs = import (builtins.fetchGit {
3
+ url = "https://github.com/NixOS/nixpkgs";
4
+ ref = "refs/heads/master";
5
+ rev = "5d0ebea1934d80948ff7b84f3b06e4ec9d99ee49";
6
+ }) {};
7
+ gems = pkgs.bundlerEnv {
8
+ name = "ruby3.4-gems-for-sup";
9
+ ruby = pkgs.ruby_3_4;
10
+ gemfile = ./Gemfile;
11
+ lockfile = ./Gemfile.lock;
12
+ gemset = ./gemset.nix;
13
+ gemConfig = pkgs.defaultGemConfig // {
14
+ rmail = attrs: {
15
+ dontBuild = false;
16
+ patches = [
17
+ # Frozen string literals: https://github.com/terceiro/rmail/pull/13
18
+ (pkgs.fetchpatch2 {
19
+ name = "rmail-frozen-string-literals.patch";
20
+ url = "https://github.com/terceiro/rmail/pull/13/commits/27f455af1fea0be0aa09959cc2237cbdf68de2a1.patch";
21
+ hash = "sha256-N5X9zix+WPoEugp2DBTu7dRDmesrF5pT/8Td2wraYoA=";
22
+ })
23
+ ];
24
+ };
25
+ # Workaround for Sup issue #623
26
+ ncursesw = attrs: pkgs.defaultGemConfig.ncursesw attrs // {
27
+ src = pkgs.fetchFromGitHub {
28
+ owner = "danc86";
29
+ repo = "ncursesw-ruby";
30
+ rev = "43cfa21f781e9412dc73d0d4a44b3ec0bf4a3c8d";
31
+ hash = "sha256-MkXFwhbtL9aJOMqn1IR5DKMXcnKHzICjb/rVhDDLL94=";
32
+ };
33
+ };
34
+ };
35
+ };
36
+ in pkgs.mkShell { packages = [ gems gems.wrappedRuby pkgs.pandoc ]; }
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+ cd "$(dirname "$0")/../.."
4
+ for rubyversion in 2.4 2.5 2.6 2.7 3.0 3.1 3.2 3.3 3.4 ; do
5
+ nix-shell contrib/nix/ruby$rubyversion-shell.nix --run 'rake ci'
6
+ done
data/doc/Hooks.txt CHANGED
@@ -69,7 +69,7 @@ startup:
69
69
  set 'bgtask_pid' @bgtask_pid
70
70
  Process.detach(@bgtask_pid) # so we don't have to wait on it when we go to kill it
71
71
  else
72
- exec "background-task args 2&>1 >> /tmp/logfile"
72
+ exec "background-task args 2>&1 >> /tmp/logfile"
73
73
  end
74
74
 
75
75
  after-poll:
@@ -14,7 +14,7 @@ destination = File.writable?(Gem.dir) ? Gem.dir : Gem.user_dir
14
14
  inst = Gem::DependencyInstaller.new(:install_dir => destination)
15
15
  begin
16
16
 
17
- if !RbConfig::CONFIG['arch'].include?('openbsd')
17
+ if not ENV.include? "SUP_SKIP_XAPIAN_GEM_INSTALL"
18
18
  # update version in Gemfile as well
19
19
  name = "xapian-ruby"
20
20
  version =
@@ -37,7 +37,7 @@ begin
37
37
 
38
38
  end
39
39
  else
40
- STDERR.puts "xapian: openbsd: you have to install xapian-core and xapian-bindings manually, have a look at: https://github.com/sup-heliotrope/sup/wiki/Installation%3A-OpenBSD"
40
+ STDERR.puts "xapian: you have to install xapian-core and xapian-bindings manually"
41
41
  end
42
42
 
43
43
  rescue StandardError => e
data/lib/sup/crypto.rb CHANGED
@@ -177,6 +177,8 @@ EOS
177
177
  end
178
178
  gpg_opts = HookManager.run("gpg-options",
179
179
  {:operation => "encrypt", :options => gpg_opts}) || gpg_opts
180
+ ## On the sup side we use :signer for backwards compatibility, but GPGME wants :signers.
181
+ gpg_opts[:signers] = gpg_opts[:signer]
180
182
  recipients = to + [from]
181
183
  recipients = HookManager.run("gpg-expand-keys", { :recipients => recipients }) || recipients
182
184
  begin
@@ -198,17 +200,17 @@ EOS
198
200
  end
199
201
 
200
202
  encrypted_payload = RMail::Message.new
201
- encrypted_payload.header["Content-Type"] = "application/octet-stream"
202
- encrypted_payload.header["Content-Disposition"] = 'inline; filename="msg.asc"'
203
+ encrypted_payload.header["Content-Type"] = +"application/octet-stream"
204
+ encrypted_payload.header["Content-Disposition"] = +'inline; filename="msg.asc"'
203
205
  encrypted_payload.body = cipher
204
206
 
205
207
  control = RMail::Message.new
206
- control.header["Content-Type"] = "application/pgp-encrypted"
207
- control.header["Content-Disposition"] = "attachment"
208
+ control.header["Content-Type"] = +"application/pgp-encrypted"
209
+ control.header["Content-Disposition"] = +"attachment"
208
210
  control.body = "Version: 1\n"
209
211
 
210
212
  envelope = RMail::Message.new
211
- envelope.header["Content-Type"] = 'multipart/encrypted; protocol=application/pgp-encrypted'
213
+ envelope.header["Content-Type"] = +"multipart/encrypted; protocol=application/pgp-encrypted"
212
214
 
213
215
  envelope.add_part control
214
216
  envelope.add_part encrypted_payload
@@ -369,7 +371,7 @@ EOS
369
371
  def retrieve fingerprint
370
372
  require 'net/http'
371
373
  uri = URI($config[:keyserver_url] || KEYSERVER_URL)
372
- unless uri.scheme == "http" and not uri.host.nil?
374
+ unless uri.scheme == "http" and not uri.host.nil? and not uri.host.empty?
373
375
  return "Invalid url: #{uri}"
374
376
  end
375
377
 
data/lib/sup/index.rb CHANGED
@@ -99,14 +99,14 @@ EOS
99
99
  end
100
100
 
101
101
  def load failsafe=false
102
- SourceManager.load_sources
102
+ SourceManager.load_sources File.join(@dir, "sources.yaml")
103
103
  load_index failsafe
104
104
  end
105
105
 
106
106
  def save
107
107
  debug "saving index and sources..."
108
108
  FileUtils.mkdir_p @dir unless File.exist? @dir
109
- SourceManager.save_sources
109
+ SourceManager.save_sources File.join(@dir, "sources.yaml")
110
110
  save_index
111
111
  end
112
112
 
data/lib/sup/maildir.rb CHANGED
@@ -23,7 +23,7 @@ class Maildir < Source
23
23
  end
24
24
 
25
25
  raise ArgumentError, "not a maildir URI" unless uri.scheme == "maildir"
26
- raise ArgumentError, "maildir URI cannot have a host: #{uri.host}" if uri.host
26
+ raise ArgumentError, "maildir URI cannot have a host: #{uri.host}" unless uri.host.nil? || uri.host.empty?
27
27
  raise ArgumentError, "maildir URI must have a path component" unless uri.path
28
28
 
29
29
  @sync_back = sync_back
@@ -114,6 +114,10 @@ class Maildir < Source
114
114
  with_file_for(id) { |f| f.read }
115
115
  end
116
116
 
117
+ def fallback_date_for_message id
118
+ File.mtime File.join(@dir, id)
119
+ end
120
+
117
121
  ## XXX use less memory
118
122
  def poll
119
123
  added = []
data/lib/sup/mbox.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'uri'
2
2
  require 'set'
3
+ require 'time'
3
4
 
4
5
  module Redwood
5
6
 
@@ -30,7 +31,7 @@ class MBox < Source
30
31
  end
31
32
 
32
33
  raise ArgumentError, "not an mbox uri" unless uri.scheme == "mbox"
33
- raise ArgumentError, "mbox URI ('#{uri}') cannot have a host: #{uri.host}" if uri.host
34
+ raise ArgumentError, "mbox URI ('#{uri}') cannot have a host: #{uri.host}" unless uri.host.nil? || uri.host.empty?
34
35
  raise ArgumentError, "mbox URI must have a path component" unless uri.path
35
36
  @f = nil
36
37
  else
@@ -85,7 +86,7 @@ class MBox < Source
85
86
  begin
86
87
  ## don't use RMail::Mailbox::MBoxReader because it doesn't properly ignore
87
88
  ## "From" at the start of a message body line.
88
- string = ""
89
+ string = +""
89
90
  until @f.eof? || MBox::is_break_line?(l = @f.gets)
90
91
  string << l
91
92
  end
@@ -97,7 +98,7 @@ class MBox < Source
97
98
  end
98
99
 
99
100
  def raw_header offset
100
- ret = ""
101
+ ret = +""
101
102
  @mutex.synchronize do
102
103
  ensure_open
103
104
  @f.seek offset
@@ -109,9 +110,7 @@ class MBox < Source
109
110
  end
110
111
 
111
112
  def raw_message offset
112
- ret = ""
113
- each_raw_message_line(offset) { |l| ret << l }
114
- ret
113
+ enum_for(:each_raw_message_line, offset).reduce(:+)
115
114
  end
116
115
 
117
116
  def store_message date, from_email, &block
@@ -137,6 +136,26 @@ class MBox < Source
137
136
  end
138
137
  end
139
138
 
139
+ def fallback_date_for_message offset
140
+ ## This is a bit awkward... We treat the From line as a delimiter,
141
+ ## not part of the message. So the offset is pointing *after* the
142
+ ## From line for the desired message. With a bit of effort we can
143
+ ## scan backwards to find its From line and extract a date from it.
144
+ buf = @mutex.synchronize do
145
+ ensure_open
146
+ start = offset
147
+ loop do
148
+ start = (start - 200).clamp 0, 2**64
149
+ @f.seek start
150
+ buf = @f.read (offset - start)
151
+ break buf if buf.include? ?\n or start == 0
152
+ end
153
+ end
154
+ BREAK_RE.match buf.lines.last do |m|
155
+ Time.strptime m[1], "%a %b %d %H:%M:%S %Y"
156
+ end
157
+ end
158
+
140
159
  def default_labels
141
160
  [:inbox, :unread]
142
161
  end
@@ -179,8 +198,7 @@ class MBox < Source
179
198
  l =~ BREAK_RE or return false
180
199
  time = $1
181
200
  begin
182
- ## hack -- make Time.parse fail when trying to substitute values from Time.now
183
- Time.parse time, Time.at(0)
201
+ Time.strptime time, "%a %b %d %H:%M:%S %Y"
184
202
  true
185
203
  rescue NoMethodError, ArgumentError
186
204
  warn "found invalid date in potential mbox split line, not splitting: #{l.inspect}"