From c9b551f366dace119d117d82de675f58265c28da Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Fri, 19 Apr 2024 16:30:19 +0300 Subject: [PATCH 01/17] fix(layouts): Revamp pocket book layout matching a5trim usage --- layouts/cep.lua | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/layouts/cep.lua b/layouts/cep.lua index 087826a4..7be0161c 100644 --- a/layouts/cep.lua +++ b/layouts/cep.lua @@ -4,32 +4,39 @@ return function (class) if class._name == "cabook" then - class:loadPackage("masters", {{ - id = "right", - firstContentFrame = "content", - frames = { - content = { + class.defaultFrameset = { + content = { left = "left(page) + 20mm", right = "right(page) - 10mm", top = "top(page) + 20mm", bottom = "top(footnotes)" - }, - runningHead = { + }, + runningHead = { left = "left(content)", right = "right(content)", top = "top(content) - 10mm", bottom = "top(content) - 2mm" - }, - footnotes = { + }, + footnotes = { left = "left(content)", right = "right(content)", height = "0", bottom = "bottom(page) - 15mm" - } - } - }}) + }, + } - SILE.setCommandDefaults("imprint:font", { size = "7pt" }) + class:registerPostinit(function (_) + SILE.setCommandDefaults("imprint:font", { size = "7pt" }) + end) + + -- Hack to avoid SILE bug in print editions + -- See https://github.com/simoncozens/sile/issues/355 + class:registerCommand("href", function (options, content) + if class.options.verseindex then + SILE.call("markverse", options, content) + end + SILE.process(content) + end) end From 4b5ea005bf3bfdd2d99a9d159d6513c9ebae6823 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Sat, 20 Apr 2024 00:07:08 +0300 Subject: [PATCH 02/17] fix(renderings): Bring dark color support back to soft-cover crease emulator --- rules/functions.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/functions.mk b/rules/functions.mk index 06f18a21..ba98d5f2 100644 --- a/rules/functions.mk +++ b/rules/functions.mk @@ -267,7 +267,7 @@ define magick_crease ?= -blur 0x$(call scale,$(call mmtopx,0.2)) \ -level "0x40%!" \ \) \ - -compose Divide -composite + -compose Difference -composite endef define magick_fray ?= From c394e99132d2cc1b0446f55170ee8a8ffc8848a9 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Mon, 22 Apr 2024 15:33:26 +0300 Subject: [PATCH 03/17] fix(layouts): Correct square promotianals to not be a bound layout --- layouts/square.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/layouts/square.lua b/layouts/square.lua index 7ec0718b..07f175f6 100644 --- a/layouts/square.lua +++ b/layouts/square.lua @@ -1,5 +1,6 @@ return function (class) + class.options.binding = "print" class.options.papersize = 1024 / 300 .. "in x " .. 1024 / 300 .. "in" end From 02fcb546497be24e4ba9d658f5e575c2c0aed2d8 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Tue, 23 Apr 2024 15:00:46 +0300 Subject: [PATCH 04/17] fix(functions): Don't let requireSpace function force blank pages --- packages/cabook-commands.lua | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/cabook-commands.lua b/packages/cabook-commands.lua index b8f3078f..bddd261b 100644 --- a/packages/cabook-commands.lua +++ b/packages/cabook-commands.lua @@ -22,9 +22,15 @@ local spreadHook = function () spread_counter = spread_counter + 1 end +local _requireSpaceSamePage +local function _abortRequireSpace () + _requireSpaceSamePage = false +end + function package:_init () base._init(self) self.class:registerHook("newpage", spreadHook) + self.class:registerHook("newpage", _abortRequireSpace) end function package:registerCommands () @@ -599,14 +605,18 @@ function package:registerCommands () end, "Output publication dates in proper format for imprint page") self:registerCommand("requireSpace", function (options, content) + _requireSpaceSamePage = true local required = SILE.length(options.height or 0) SILE.typesetter:leaveHmode() SILE.call("hbox", {}, content) -- push content we want to fit - local heightOfPageSoFar = SILE.pagebuilder:collateVboxes(SILE.typesetter.state.outputQueue).height local heightOfFrame = SU.cast("length", SILE.typesetter.frame:height()) + local heightOfPageSoFar = SILE.pagebuilder:collateVboxes(SILE.typesetter.state.outputQueue).height table.remove(SILE.typesetter.state.nodes) -- steal it back + SILE.typesetter:leaveHmode() if heightOfFrame - heightOfPageSoFar < required then - SILE.call("supereject") + if _requireSpaceSamePage then + SILE.call("supereject") + end end end) From 5ec9c76613a19afb286bc7372106881f830b5240 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Thu, 25 Apr 2024 21:39:01 +0300 Subject: [PATCH 05/17] fix(layouts): Set non-bound page formats to get regular covers not front-back ones --- classes/cabinding.lua | 2 +- classes/cabook.lua | 12 +++++++----- cover.xml | 2 +- rules/rules.mk | 3 +++ 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/classes/cabinding.lua b/classes/cabinding.lua index aa6c49c5..9126734f 100644 --- a/classes/cabinding.lua +++ b/classes/cabinding.lua @@ -89,7 +89,7 @@ function class:declareOptions () if size then self.papersize = size local parsed = SILE.papersize(size) - if binding == "print" or CASILE.layout == "print" then + if binding == "print" or CASILE.binding == "print" then self.defaultFrameset = posterFrameset SILE.documentState.paperSize = { parsed[1], parsed[2] } else diff --git a/classes/cabook.lua b/classes/cabook.lua index 077ae706..fb2df003 100644 --- a/classes/cabook.lua +++ b/classes/cabook.lua @@ -103,17 +103,19 @@ function class:declareOptions () end function class:setOptions (options) - options.binding = options.binding or "print" -- print, paperback, hardcover, coil, stapled + options.binding = options.binding or CASILE.binding or "print" -- print, paperback, hardcover, coil, stapled + -- Set binding first if we have it so that the layout can adapt the papersize based on the binding + self.options.binding = options.binding options.crop = options.crop or (options.binding ~= "print") - options.background = options.background or true - options.verseindex = options.verseindex or false - options.layout = options.layout or CASILE.layout or "a4" - -- Set layout first because it resets paper size. If we don't a random race + -- Set layout next because it resets paper size. If we don't a random race -- condition picks the default papersize *or* our layout to be set first. + options.layout = options.layout or CASILE.layout or "a4" self.options.layout = options.layout -- Now set the rest but with the papersize reset to whatever layout wanted options.papersize = self.options.papersize options.layout = nil + options.background = options.background or true + options.verseindex = options.verseindex or false book.setOptions(self, options) end diff --git a/cover.xml b/cover.xml index 2e9f7ff6..fc159544 100644 --- a/cover.xml +++ b/cover.xml @@ -1,4 +1,4 @@ - + diff --git a/rules/rules.mk b/rules/rules.mk index ae24b9ac..a7c0b6e4 100644 --- a/rules/rules.mk +++ b/rules/rules.mk @@ -727,6 +727,7 @@ $(BINDINGFRAGMENTS): $(BUILDDIR)/%-$(_binding)-$(_text).pdf: local metadatafile = "$(filter %-manifest.yml,$^)" CASILE.metadata = require("readmeta").load(metadatafile) CASILE.layout = "$(or $(__$(call parse_papersize,$@)),$(call parse_papersize,$@))" + CASILE.binding = "$(or $(__$(call parse_binding,$@)),$(call parse_binding,$@))" CASILE.language = "$(LANGUAGE)" CASILE.spine = "$(call spinemm,$(filter %.pdf,$^))mm" return { _name = "$*", type = "casile" } @@ -788,6 +789,7 @@ $(COVERFRAGMENTS): $(BUILDDIR)/%-$(_text).pdf: local metadatafile = "$(filter %-manifest.yml,$^)" CASILE.metadata = require("readmeta").load(metadatafile) CASILE.layout = "$(or $(__$(call parse_papersize,$@)),$(call parse_papersize,$@))" + CASILE.binding = "$(or $(__$(call parse_binding,$@)),$(call parse_binding,$@))" CASILE.language = "$(LANGUAGE)" return { _name = "casile", type = "casile" } EOF @@ -899,6 +901,7 @@ $(EMPTYGEOMETRIES): $(BUILDDIR)/$(_geometry)-%.pdf: $(CASILEDIR)/geometry.xml | cat <<- EOF > $(BUILDDIR)/$*.lua CASILE.versioninfo = "$(call versioninfo,$@)" CASILE.layout = "$(or $(__$(call parse_papersize,$@)),$(call parse_papersize,$@))" + CASILE.binding = "$(or $(__$(call parse_binding,$@)),$(call parse_binding,$@))" CASILE.language = "$(LANGUAGE)" return { _name = "$*", type = "casile" } EOF From 9797090bc48ec948a54d9afaae326d935f77a7b4 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Wed, 1 May 2024 15:31:05 +0300 Subject: [PATCH 06/17] chore(deps): Bump minor version updates to crates --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 014738c4..e97022f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ futures = "0.3" itertools = "0.12" lazy_static = "1.4" num_cpus = "1.16" -rayon = "1.8" +rayon = "1.10" rust-embed = "8.3" rustc-hash = "1.1" subprocess = "0.2" From 02c43fff060451e824072a6e22a5693ecd4a550d Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Wed, 1 May 2024 15:31:41 +0300 Subject: [PATCH 07/17] chore(deps): Refresh pinned crates --- Cargo.lock | 233 ++++++++++++++++++++++++++++------------------------- 1 file changed, 125 insertions(+), 108 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2963b8fa..a9b866c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,9 +73,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" [[package]] name = "arc-swap" @@ -100,9 +100,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.78" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", @@ -111,9 +111,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "bitflags" @@ -222,12 +222,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.90" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "065a29261d53ba54260972629f9ca6bffa69bac13cd1fed61420f7fa68b9f8bd" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -244,9 +245,9 @@ checksum = "bb7bdea464ae038f09197b82430b921c53619fc8d2bcaf7b151013b3ca008017" [[package]] name = "clap" -version = "4.5.3" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", "clap_derive", @@ -267,18 +268,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.1" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "885e4d7d5af40bfb99ae6f9433e292feac98d452dcb3ec3d25dfe7552b77da8c" +checksum = "dd79504325bf38b10165b02e89b4347300f855f273c4cb30c4a3209e6583275e" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.3" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90239a040c80f5e14809ca132ddc4176ab33d5e17e49691793296e3fcb34d72f" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ "heck", "proc-macro2", @@ -443,9 +444,9 @@ checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "either" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "encode_unicode" @@ -471,9 +472,9 @@ checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "filetime" @@ -483,15 +484,15 @@ checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.4.1", "windows-sys 0.52.0", ] [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -675,9 +676,9 @@ dependencies = [ [[package]] name = "git-warp-time" -version = "0.7.0" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33cc90e8c8964edcf67b0d02167fa193755efd7727bb090dccc61102bd3f1cb0" +checksum = "a7a45626a8931c8a912a70fc004d02aa00177dab30ba9e350c2b0dc0f47335ca" dependencies = [ "filetime", "git2", @@ -1143,9 +1144,9 @@ dependencies = [ [[package]] name = "gix-trace" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b838b2db8f62c9447d483a4c28d251b67fee32741a82cb4d35e9eb4e9fdc5ab" +checksum = "f924267408915fddcd558e3f37295cc7d6a3e50f8bd8b606cee0808c3915157e" [[package]] name = "gix-traverse" @@ -1179,9 +1180,9 @@ dependencies = [ [[package]] name = "gix-utils" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0066432d4c277f9877f091279a597ea5331f68ca410efc874f0bdfb1cd348f92" +checksum = "35192df7fd0fa112263bad8021e2df7167df4cc2a6e6d15892e1e55621d3d4dc" dependencies = [ "fastrand", "unicode-normalization", @@ -1199,9 +1200,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" @@ -1288,15 +1289,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] @@ -1309,9 +1310,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] name = "libgit2-sys" @@ -1351,9 +1352,9 @@ checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1367,9 +1368,9 @@ checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "memmap2" @@ -1459,9 +1460,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" dependencies = [ "lock_api", "parking_lot_core", @@ -1469,15 +1470,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.1", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] @@ -1494,9 +1495,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1554,9 +1555,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] @@ -1569,18 +1570,18 @@ checksum = "744a264d26b88a6a7e37cbad97953fa233b94d585236310bcbc88474b4092d79" [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] [[package]] name = "rayon" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -1605,6 +1606,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags 2.5.0", +] + [[package]] name = "regex" version = "1.10.4" @@ -1630,9 +1640,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "roff" @@ -1682,9 +1692,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.5.0", "errno", @@ -1695,9 +1705,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" [[package]] name = "ryu" @@ -1746,18 +1756,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.197" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" dependencies = [ "proc-macro2", "quote", @@ -1766,9 +1776,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "itoa", "ryu", @@ -1804,9 +1814,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -1828,9 +1838,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subprocess" @@ -1844,9 +1854,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.53" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", @@ -1883,18 +1893,18 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" dependencies = [ "proc-macro2", "quote", @@ -1903,9 +1913,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -1926,9 +1936,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -2026,9 +2036,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" [[package]] name = "url" @@ -2111,11 +2121,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -2139,7 +2149,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -2159,17 +2169,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -2180,9 +2191,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -2192,9 +2203,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -2204,9 +2215,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -2216,9 +2233,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -2228,9 +2245,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -2240,9 +2257,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -2252,9 +2269,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" From 969c4a51f1e0335a5e55d4bd9a6eec208d607b1b Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Wed, 1 May 2024 15:33:54 +0300 Subject: [PATCH 08/17] feat(rules): Add dedicated format target for manifests --- rules/rules.mk | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/rules/rules.mk b/rules/rules.mk index a7c0b6e4..dad020aa 100644 --- a/rules/rules.mk +++ b/rules/rules.mk @@ -42,7 +42,7 @@ MOCKUPFACTOR ?= 1 FIGURES ?= # Default output formats and parameters (often overridden) -FORMATS ?= pdfs epub mobi odt docx mdbook zola $(and $(ISBNS),play) app html +FORMATS ?= manifest pdfs epub mobi odt docx mdbook zola $(and $(ISBNS),play) app html BLEED ?= 3 TRIM ?= 10 NOBLEED ?= 0 @@ -275,6 +275,10 @@ endef $(foreach FORMAT,$(FORMATS),$(eval $(call format_template,$(FORMAT),$(TARGETS)))) +VIRTUALMANIFESTS := $(call pattern_list,$(SOURCES),.manifest) +.PHONY: $(VIRTUALMANIFESTS) +$(VIRTUALMANIFESTS): %.manifest: %-manifest.yml + VIRTUALPDFS := $(call pattern_list,$(SOURCES),.pdfs) VIRTUALEDITPDFS := $(and $(EDITS),$(call pattern_list,$(SOURCES),$(EDITS),.pdfs)) .PHONY: $(VIRTUALPDFS) $(VIRTUALEDITPDFS) @@ -314,8 +318,12 @@ $(VIRTUALPROMOTIONALS): %.promotionals: $(call pattern_list,$$*,$(PLACARDS),-$(_ ifneq ($(words $(TARGETS)),1) promotionals: series_promotionals renderings: series_renderings +manifest: series_manifest endif +.PHONY: series_manifest +series_manifest: $(call pattern_list,$(PROJECT),manifest,.yml) + .PHONY: series_promotionals series_promotionals: $(PROJECT)-epub-$(_poster)-$(_montage).jpg $(PROJECT)-$(_square)-$(_poster)-$(_montage).jpg From a936fbea9d88befff493bd695a176e618b991fa7 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Mon, 6 May 2024 02:09:32 +0300 Subject: [PATCH 09/17] chore(deps): Refresh pinned crates --- Cargo.lock | 88 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9b866c7..17e4cd10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,47 +25,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -111,9 +112,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" @@ -305,15 +306,15 @@ dependencies = [ [[package]] name = "clru" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8191fa7302e03607ff0e237d4246cc043ff5b3cb9409d995172ba3bea16b807" +checksum = "cbd0f76e066e64fdc5631e3bb46381254deab9ef1158292f27c8c57e3bf3fe59" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "config" @@ -509,9 +510,9 @@ dependencies = [ [[package]] name = "fluent" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61f69378194459db76abd2ce3952b790db103ceb003008d3d50d97c41ff847a7" +checksum = "bb74634707bebd0ce645a981148e8fb8c7bccd4c33c652aeffd28bf2f96d555a" dependencies = [ "fluent-bundle", "unic-langid", @@ -519,9 +520,9 @@ dependencies = [ [[package]] name = "fluent-bundle" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e242c601dec9711505f6d5bbff5bedd4b61b2469f2e8bb8e57ee7c9747a87ffd" +checksum = "7fe0a21ee80050c678013f82edf4b705fe2f26f1f9877593d13198612503f493" dependencies = [ "fluent-langneg", "fluent-syntax", @@ -535,15 +536,16 @@ dependencies = [ [[package]] name = "fluent-fallback" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08fdcccdeb6c01cb085f2bb3420506e6c67f025cee5db047529838c673a7d82b" +checksum = "1010c29cde3a7eeb231c59d95411dcea1c1d91ad00dd733b076dbd885815024a" dependencies = [ "async-trait", "chunky-vec", "fluent-bundle", "futures", "once_cell", + "pin-cell", "rustc-hash", "unic-langid", ] @@ -559,9 +561,9 @@ dependencies = [ [[package]] name = "fluent-syntax" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0abed97648395c902868fee9026de96483933faa54ea3b40d652f7dfe61ca78" +checksum = "2a530c4694a6a8d528794ee9bbd8ba0122e779629ac908d15ad5a7ae7763a33d" dependencies = [ "thiserror", ] @@ -1261,9 +1263,9 @@ dependencies = [ [[package]] name = "intl-memoizer" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c310433e4a310918d6ed9243542a6b83ec1183df95dff8f23f87bb88a264a66f" +checksum = "fe22e020fce238ae18a6d5d8c502ee76a52a6e880d99477657e6acc30ec57bda" dependencies = [ "type-map", "unic-langid", @@ -1278,6 +1280,12 @@ dependencies = [ "unic-langid", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.12.1" @@ -1420,9 +1428,9 @@ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -1493,6 +1501,12 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-cell" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1f4c4ebd3c5f82080164b7d9cc8e505cd9536fda8c750b779daceb4b7180a7b" + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -1736,14 +1750,14 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d" dependencies = [ - "self_cell 1.0.3", + "self_cell 1.0.4", ] [[package]] name = "self_cell" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba" +checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" [[package]] name = "semver" @@ -1756,18 +1770,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.199" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a" +checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.199" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" +checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ "proc-macro2", "quote", @@ -1970,9 +1984,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "type-map" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d3364c5e96cb2ad1603037ab253ddd34d7fb72a58bdddf4b7350760fc69a46" +checksum = "deb68604048ff8fa93347f02441e4487594adc20bb8a084f9e564d2b827a0a9f" dependencies = [ "rustc-hash", ] From a6408c364bb44b17931ac1011235293ff0a98c43 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Tue, 7 May 2024 16:42:41 +0300 Subject: [PATCH 10/17] fix(rules): Work around PNG conversion issue in current ImageMagick --- rules/rules.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rules/rules.mk b/rules/rules.mk index dad020aa..64cb4d38 100644 --- a/rules/rules.mk +++ b/rules/rules.mk @@ -1121,9 +1121,12 @@ $(BUILDDIR)/%-$(_barcode).png: $(BUILDDIR)/%-$(_barcode).svg $< \ -bordercolor white -border 10 \ -font Hack-Regular -pointsize 72 \ + -fill black \ label:" ISBN $(shell $(_ENV) isbn_format.py $*-manifest.yml paperback mask)" +swap -gravity Center -append \ -bordercolor white -border 0x10 \ -resize $(call scale,1200)x \ + -alpha off \ + -fill '#fffffe' -draw 'point 2,2' \ $@ if [[ $(shell $(_ENV) isbn_format.py $*-manifest.yml paperback) == 9786056644504 ]]; then $(MAGICK) \ From 9b74394e4b33d112e243f25b8367e5a00d50cc11 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Tue, 7 May 2024 16:53:15 +0300 Subject: [PATCH 11/17] feat(rules): Include cropped versions of PDFS in pdfs build by default --- rules/rules.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rules/rules.mk b/rules/rules.mk index 64cb4d38..8f57c1af 100644 --- a/rules/rules.mk +++ b/rules/rules.mk @@ -285,6 +285,8 @@ VIRTUALEDITPDFS := $(and $(EDITS),$(call pattern_list,$(SOURCES),$(EDITS),.pdfs) $(VIRTUALPDFS) $(VIRTUALEDITPDFS): %.pdfs: $(call pattern_list,$$*,$(LAYOUTS),.pdf) $(VIRTUALPDFS): %.pdfs: $(and $(EDITIONS),$(call pattern_list,$$*,$(EDITIONS),$(LAYOUTS),.pdf)) $(VIRTUALEDITPDFS): %.pdfs: $$(and $(EDITIONS),$(EDITS),$$(call pattern_list,$$(call parse_bookid,$$*),$(EDITIONS),$(EDITS),$(LAYOUTS),.pdf)) +ACTIVEBOUNDLAYOUTS = $(filter $(BOUNDLAYOUTS),$(LAYOUTS)) +$(VIRTUALPDFS): %.pdfs: $(and $(ACTIVEBOUNDLAYOUTS),$(call pattern_list,$$*,$(ACTIVEBOUNDLAYOUTS),$(_cropped),.pdf)) # Setup target dependencies to mimic stages of a CI pipeline ifeq ($(MAKECMDGOALS),ci) From 28599582d25cd870850bbb9dd2e21d9a247fdc8d Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Wed, 8 May 2024 14:02:54 +0300 Subject: [PATCH 12/17] fix(covers): Put selectable text behind rendered covers --- rules/rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/rules.mk b/rules/rules.mk index 8f57c1af..bef6f44c 100644 --- a/rules/rules.mk +++ b/rules/rules.mk @@ -722,7 +722,7 @@ $(COVERPDFS): $(BUILDDIR)/%-$(_cover).pdf: $(BUILDDIR)/%-$(_cover).png $(BUILDDI +repage \ $$bg $(PDFTK) $(filter %.pdf,$^) cat 1 output $$text - $(PDFTK) $$text background $$bg output $@ + $(PDFTK) $$bg background $$text output $@ BINDINGFRAGMENTS := $(addprefix $(BUILDDIR)/,$(call pattern_list,$(EDITIONEDITSOURCES),$(BOUNDLAYOUTS),-$(_binding)-$(_text).pdf)) $(BINDINGFRAGMENTS): .EXTRA_PREREQS = $(LUAINCLUDES) From 0b7c7f705b5b8266eba75ba96c76e2fc3575d0a4 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Wed, 8 May 2024 17:49:43 +0300 Subject: [PATCH 13/17] chore(covers): Use stamp instead of reversed background so page size is preserved --- rules/rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/rules.mk b/rules/rules.mk index bef6f44c..65e02fb5 100644 --- a/rules/rules.mk +++ b/rules/rules.mk @@ -722,7 +722,7 @@ $(COVERPDFS): $(BUILDDIR)/%-$(_cover).pdf: $(BUILDDIR)/%-$(_cover).png $(BUILDDI +repage \ $$bg $(PDFTK) $(filter %.pdf,$^) cat 1 output $$text - $(PDFTK) $$bg background $$text output $@ + $(PDFTK) $$text stamp $$bg output $@ BINDINGFRAGMENTS := $(addprefix $(BUILDDIR)/,$(call pattern_list,$(EDITIONEDITSOURCES),$(BOUNDLAYOUTS),-$(_binding)-$(_text).pdf)) $(BINDINGFRAGMENTS): .EXTRA_PREREQS = $(LUAINCLUDES) From 7561e22d8f9c8a93e3096ade15ac4b8250b2662e Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Thu, 2 May 2024 16:20:46 +0300 Subject: [PATCH 14/17] refactor(cli): Note the TUI is only a UI, and we might have others --- Makefile.am | 2 +- src/lib.rs | 2 +- src/main.rs | 2 +- src/make/mod.rs | 4 ++-- src/run/mod.rs | 2 +- src/setup/mod.rs | 2 +- src/status/mod.rs | 2 +- src/{tui.rs => ui.rs} | 24 ++++++++++++------------ 8 files changed, 20 insertions(+), 20 deletions(-) rename src/{tui.rs => ui.rs} (93%) diff --git a/Makefile.am b/Makefile.am index cb196407..e382a2a9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -32,7 +32,7 @@ nobase_data_DATA = rules/casile.mk $(reverse_lang_key_files) nobase_dist_data_DATA = rules/rules.mk rules/functions.mk rules/translation.mk rules/utilities.mk $(lang_key_files) nobase_dist_data_DATA += rules/ebooks.mk rules/mdbook.mk rules/renderings.mk rules/zola.mk nobase_dist_pkgdata_DATA = $(LUALIBRARIES) -_casile_libs = src/lib.rs src/cli.rs src/config.rs src/i18n.rs src/tui.rs +_casile_libs = src/lib.rs src/cli.rs src/config.rs src/i18n.rs src/ui.rs _casile_modules = src/make/mod.rs src/run/mod.rs src/setup/mod.rs src/status/mod.rs _casile_assets = assets/en-US/cli.ftl assets/tr-TR/cli.ftl bin_PROGRAMS = casile diff --git a/src/lib.rs b/src/lib.rs index f39cfcc0..628b6b4d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,7 @@ use std::{error, fmt, path, result, str}; pub mod cli; pub mod config; pub mod i18n; -pub mod tui; +pub mod ui; // Subcommands pub mod make; diff --git a/src/main.rs b/src/main.rs index 1812de1a..310cc7a4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ use clap::{Args, Command, FromArgMatches as _}; use casile::cli::{Cli, Commands}; use casile::config::CONF; -use casile::tui::*; +use casile::ui::*; use casile::{make, run, setup, status}; use casile::{Result, VERSION}; diff --git a/src/make/mod.rs b/src/make/mod.rs index 81bc4a46..08b5836d 100644 --- a/src/make/mod.rs +++ b/src/make/mod.rs @@ -1,5 +1,5 @@ use crate::i18n::LocalText; -use crate::tui::*; +use crate::ui::*; use crate::*; use console::style; @@ -238,7 +238,7 @@ pub fn run(target: Vec) -> Result<()> { fn dump_backlog(backlog: &[String]) { let bar = ProgressBar::new_spinner().with_style(ProgressStyle::with_template("{msg}").unwrap()); - let bar = TUI.add(bar); + let bar = UI.add(bar); let mut dump = String::new(); let start = LocalText::new("make-backlog-start").fmt(); let start = format!("{} {start}\n", style(style("┄┄┄┄┄┄").cyan())); diff --git a/src/run/mod.rs b/src/run/mod.rs index e8e916a0..8db335f7 100644 --- a/src/run/mod.rs +++ b/src/run/mod.rs @@ -1,4 +1,4 @@ -use crate::tui::*; +use crate::ui::*; use crate::*; use std::io::prelude::*; diff --git a/src/setup/mod.rs b/src/setup/mod.rs index c3d9d1ff..7b0cf8dc 100644 --- a/src/setup/mod.rs +++ b/src/setup/mod.rs @@ -1,5 +1,5 @@ use crate::i18n::LocalText; -use crate::tui::*; +use crate::ui::*; use crate::*; use console::style; diff --git a/src/status/mod.rs b/src/status/mod.rs index 34e79003..e1be09af 100644 --- a/src/status/mod.rs +++ b/src/status/mod.rs @@ -1,4 +1,4 @@ -use crate::tui::*; +use crate::ui::*; use crate::*; use git2::{DescribeFormatOptions, DescribeOptions}; diff --git a/src/tui.rs b/src/ui.rs similarity index 93% rename from src/tui.rs rename to src/ui.rs index 89acba4c..e1cc0c47 100644 --- a/src/tui.rs +++ b/src/ui.rs @@ -9,20 +9,21 @@ use std::str; use std::sync::RwLock; use std::time::Instant; -static ERROR_TUI_WRITE: &str = "Unable to gain write lock on tui status wrapper"; +static ERROR_UI_WRITE: &str = "Unable to gain write lock on ui status wrapper"; lazy_static! { - pub static ref TUI: RwLock = RwLock::new(Progress::new()); + pub static ref UI: RwLock = RwLock::new(Progress::new()); } -impl TUI { +impl UI { pub fn add(&self, bar: ProgressBar) -> ProgressBar { - let tui = self.write().expect(ERROR_TUI_WRITE); - tui.add(bar) + let ui = self.write().expect(ERROR_UI_WRITE); + ui.add(bar) } pub fn remove(&self, bar: &ProgressBar) { - let tui = self.write().expect(ERROR_TUI_WRITE); - tui.remove(bar); + let ui = self.write().expect(ERROR_UI_WRITE); + bar.finish(); + ui.remove(bar); } } @@ -69,7 +70,6 @@ impl CommandStatus { } pub fn bar(&self) -> ProgressBar { let prefix = style("⛫").cyan().to_string(); - ProgressBar::new_spinner() .with_style(ProgressStyle::with_template("{prefix} {msg}").unwrap()) .with_prefix(prefix) @@ -107,7 +107,7 @@ impl SubcommandStatus { let bar = ProgressBar::new_spinner() .with_style(ProgressStyle::with_template("{prefix} {msg}").unwrap()) .with_prefix(prefix); - let bar = TUI.add(bar); + let bar = UI.add(bar); bar.set_message(msg); let good_msg = style(LocalText::new(good_key).fmt()) .green() @@ -171,7 +171,7 @@ impl MakeTargetStatus { let bar = ProgressBar::new_spinner() .with_style(pstyle) .with_message(msg); - let bar = TUI.add(bar); + let bar = UI.add(bar); bar.tick(); MakeTargetStatus { bar, target } } @@ -189,7 +189,7 @@ impl MakeTargetStatus { let target = self.target.clone(); let allow_hide = !CONF.get_bool("debug").unwrap() && !CONF.get_bool("verbose").unwrap(); if allow_hide && target.starts_with(".casile") { - TUI.remove(&self.bar); + UI.remove(&self.bar); } else { let msg = style( LocalText::new("make-report-pass") @@ -235,7 +235,7 @@ impl SetupCheck { .with_finish(ProgressFinish::AbandonWithMessage( format!("{msg} {no}").into(), )); - TUI.add(bar) + UI.add(bar) } else { ProgressBar::hidden() }; From 7db1850232e84b8d62deeb07e1ed308a54e6ed69 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Thu, 2 May 2024 17:46:22 +0300 Subject: [PATCH 15/17] refactor(cli): Make the UI a trait object so we can have more than one --- Makefile.am | 2 +- src/lib.rs | 1 + src/main.rs | 7 +- src/make/mod.rs | 38 ++---- src/run/mod.rs | 5 +- src/setup/mod.rs | 17 +-- src/status/mod.rs | 14 ++- src/ui.rs | 280 ++++++++------------------------------------ src/ui_indicatif.rs | 273 ++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 355 insertions(+), 282 deletions(-) create mode 100644 src/ui_indicatif.rs diff --git a/Makefile.am b/Makefile.am index e382a2a9..d4e13f4e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -32,7 +32,7 @@ nobase_data_DATA = rules/casile.mk $(reverse_lang_key_files) nobase_dist_data_DATA = rules/rules.mk rules/functions.mk rules/translation.mk rules/utilities.mk $(lang_key_files) nobase_dist_data_DATA += rules/ebooks.mk rules/mdbook.mk rules/renderings.mk rules/zola.mk nobase_dist_pkgdata_DATA = $(LUALIBRARIES) -_casile_libs = src/lib.rs src/cli.rs src/config.rs src/i18n.rs src/ui.rs +_casile_libs = src/lib.rs src/cli.rs src/config.rs src/i18n.rs src/ui.rs src/ui_indicatif.rs _casile_modules = src/make/mod.rs src/run/mod.rs src/setup/mod.rs src/status/mod.rs _casile_assets = assets/en-US/cli.ftl assets/tr-TR/cli.ftl bin_PROGRAMS = casile diff --git a/src/lib.rs b/src/lib.rs index 628b6b4d..ed00af95 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,6 +17,7 @@ pub mod cli; pub mod config; pub mod i18n; pub mod ui; +pub mod ui_indicatif; // Subcommands pub mod make; diff --git a/src/main.rs b/src/main.rs index 310cc7a4..1734a713 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ use clap::{Args, Command, FromArgMatches as _}; use casile::cli::{Cli, Commands}; use casile::config::CONF; -use casile::ui::*; +use casile::ui::{UserInterface, CASILEUI}; use casile::{make, run, setup, status}; use casile::{Result, VERSION}; @@ -15,8 +15,7 @@ fn main() -> Result<()> { let matches = cli.get_matches(); let args = Cli::from_arg_matches(&matches).expect("Unable to parse arguments"); CONF.merge_args(&args)?; - let command_status = CommandStatus::new(); - command_status.welcome(); + CASILEUI.welcome(); let subcommand = Commands::from_arg_matches(&matches)?; let ret = match subcommand { Commands::Make { target } => make::run(target), @@ -24,6 +23,6 @@ fn main() -> Result<()> { Commands::Setup {} => setup::run(), Commands::Status {} => status::run(), }; - command_status.farewell(); + CASILEUI.farewell(); ret } diff --git a/src/make/mod.rs b/src/make/mod.rs index 08b5836d..668b54ed 100644 --- a/src/make/mod.rs +++ b/src/make/mod.rs @@ -3,7 +3,6 @@ use crate::ui::*; use crate::*; use console::style; -use indicatif::{ProgressBar, ProgressStyle}; use regex::Regex; use std::collections::HashMap; use std::io::prelude::*; @@ -13,9 +12,8 @@ use subprocess::{Exec, ExitStatus, Redirection}; // FTL: help-subcommand-make /// Build specified target(s) pub fn run(target: Vec) -> Result<()> { - let subcommand_status = SubcommandStatus::new("status-header", "status-good", "status-bad"); - setup::is_setup(subcommand_status)?; - let subcommand_status = SubcommandStatus::new("make-header", "make-good", "make-bad"); + setup::is_setup()?; + let subcommand_status = CASILEUI.new_subcommand("make-header", "make-good", "make-bad"); let mut makeflags: Vec = Vec::new(); let cpus = &num_cpus::get().to_string(); makeflags.push(OsString::from(format!("--jobs={cpus}"))); @@ -96,7 +94,7 @@ pub fn run(target: Vec) -> Result<()> { "CASILE" => match fields[1] { "PRE" => { let target = fields[2].to_owned(); - let target_status = MakeTargetStatus::new(target.clone()); + let target_status = CASILEUI.new_target(target.clone()); target_statuses.insert(target, target_status); } "STDOUT" => { @@ -182,19 +180,19 @@ pub fn run(target: Vec) -> Result<()> { || targets.contains(&"debug".into()) || targets.contains(&"-p".into()) { - dump_backlog(&backlog) + subcommand_status.dump(&backlog) }; Ok(()) } 1 => { - dump_backlog(&backlog); + subcommand_status.dump(&backlog); Err(Box::new(io::Error::new( io::ErrorKind::InvalidInput, LocalText::new("make-error-unfinished").fmt(), ))) } 2 => { - dump_backlog(&backlog); + subcommand_status.dump(&backlog); Err(Box::new(io::Error::new( io::ErrorKind::InvalidInput, LocalText::new("make-error-build").fmt(), @@ -202,7 +200,7 @@ pub fn run(target: Vec) -> Result<()> { } 3 => { if !CONF.get_bool("verbose")? { - dump_backlog(&backlog); + subcommand_status.dump(&backlog); } Err(Box::new(io::Error::new( io::ErrorKind::InvalidInput, @@ -211,7 +209,7 @@ pub fn run(target: Vec) -> Result<()> { } 137 => { if !CONF.get_bool("verbose")? { - dump_backlog(&backlog); + subcommand_status.dump(&backlog); } Err(Box::new(io::Error::new( io::ErrorKind::InvalidInput, @@ -219,7 +217,7 @@ pub fn run(target: Vec) -> Result<()> { ))) } _ => { - dump_backlog(&backlog); + subcommand_status.dump(&backlog); Err(Box::new(io::Error::new( io::ErrorKind::InvalidInput, LocalText::new("make-error-unknown").fmt(), @@ -235,21 +233,3 @@ pub fn run(target: Vec) -> Result<()> { subcommand_status.end(ret.is_ok()); Ok(ret?) } - -fn dump_backlog(backlog: &[String]) { - let bar = ProgressBar::new_spinner().with_style(ProgressStyle::with_template("{msg}").unwrap()); - let bar = UI.add(bar); - let mut dump = String::new(); - let start = LocalText::new("make-backlog-start").fmt(); - let start = format!("{} {start}\n", style(style("┄┄┄┄┄┄").cyan())); - dump.push_str(start.as_str()); - for line in backlog.iter() { - dump.push_str(line.as_str()); - dump.push('\n'); - } - let end = LocalText::new("make-backlog-end").fmt(); - let end = format!("{} {end}", style(style("┄┄┄┄┄").cyan())); - dump.push_str(end.as_str()); - bar.set_message(dump); - bar.finish(); -} diff --git a/src/run/mod.rs b/src/run/mod.rs index 8db335f7..71350378 100644 --- a/src/run/mod.rs +++ b/src/run/mod.rs @@ -8,8 +8,8 @@ use subprocess::{Exec, Redirection}; // FTL: help-subcommand-run /// Run helper script inside CaSILE environment pub fn run(name: String, arguments: Vec) -> Result<()> { - let subcommand_status = SubcommandStatus::new("run-header", "run-good", "run-bad"); - setup::is_setup(subcommand_status)?; + setup::is_setup()?; + let subcommand_status = CASILEUI.new_subcommand("run-header", "run-good", "run-bad"); let cpus = &num_cpus::get().to_string(); let mut process = Exec::cmd(format!("{CONFIGURE_DATADIR}/scripts/{name}")).args(&arguments); let gitname = status::get_gitname()?; @@ -40,5 +40,6 @@ pub fn run(name: String, arguments: Vec) -> Result<()> { } let status = popen.wait().expect("Failed for foo"); dbg!(status); + subcommand_status.end(true); Ok(()) } diff --git a/src/setup/mod.rs b/src/setup/mod.rs index 7b0cf8dc..0fb7c8a2 100644 --- a/src/setup/mod.rs +++ b/src/setup/mod.rs @@ -13,7 +13,7 @@ use subprocess::{Exec, NullFile, Redirection}; // FTL: help-subcommand-setup /// Setup a publishing project for use with CaSILE pub fn run() -> Result<()> { - let subcommand_status = SubcommandStatus::new("setup-header", "setup-good", "setup_bad"); + let subcommand_status = CASILEUI.new_subcommand("setup-header", "setup-good", "setup_bad"); let path = &CONF.get_string("path")?; let metadata = fs::metadata(path)?; let ret = match metadata.is_dir() { @@ -41,7 +41,8 @@ pub fn run() -> Result<()> { } /// Evaluate whether this project is properly configured -pub fn is_setup(subcommand_status: SubcommandStatus) -> Result { +pub fn is_setup() -> Result { + let subcommand_status = CASILEUI.new_subcommand("status-header", "status-good", "status-bad"); let results = Arc::new(RwLock::new(Vec::new())); // First round of tests, entirely independent @@ -81,7 +82,7 @@ pub fn is_setup(subcommand_status: SubcommandStatus) -> Result { /// Are we in a git repo? pub fn is_repo() -> Result { - let status = SetupCheck::start("setup-is-repo"); + let status = CASILEUI.new_check("setup-is-repo"); let ret = get_repo().is_ok(); (ret).then(|| status.pass()); Ok(ret) @@ -89,15 +90,15 @@ pub fn is_repo() -> Result { /// Is this repo a deep clone? pub fn is_deep() -> Result { + let status = CASILEUI.new_check("setup-is-deep"); let ret = !get_repo()?.is_shallow(); - let status = SetupCheck::start("setup-is-deep"); (ret).then(|| status.pass()); Ok(ret) } /// Are we not in the CaSILE source repo? pub fn is_not_casile_source() -> Result { - let status = SetupCheck::start("setup-is-not-casile"); + let status = CASILEUI.new_check("setup-is-not-casile"); let repo = get_repo()?; let workdir = repo.workdir().unwrap(); let testfile = workdir.join("make-shell.zsh.in"); @@ -108,7 +109,7 @@ pub fn is_not_casile_source() -> Result { /// Is the git repo we are in writable? pub fn is_writable() -> Result { - let status = SetupCheck::start("setup-is-writable"); + let status = CASILEUI.new_check("setup-is-writable"); let repo = get_repo()?; let workdir = repo.workdir().unwrap(); let testfile = workdir.join(".casile-write-test"); @@ -122,7 +123,7 @@ pub fn is_writable() -> Result { /// Check if we can execute the system's `make` utility pub fn is_make_exectuable() -> Result { - let status = SetupCheck::start("setup-is-make-executable"); + let status = CASILEUI.new_check("setup-is-make-executable"); let ret = Exec::cmd("make") .arg("-v") .stdout(NullFile) @@ -135,7 +136,7 @@ pub fn is_make_exectuable() -> Result { /// Check that the system's `make` utility is GNU Make pub fn is_make_gnu() -> Result { - let status = SetupCheck::start("setup-is-make-gnu"); + let status = CASILEUI.new_check("setup-is-make-gnu"); let out = Exec::cmd("make") .arg("-v") .stdout(Redirection::Pipe) diff --git a/src/status/mod.rs b/src/status/mod.rs index e1be09af..1dda44cb 100644 --- a/src/status/mod.rs +++ b/src/status/mod.rs @@ -8,9 +8,11 @@ use std::{env, path}; // FTL: help-subcommand-status /// Dump what we know about the repo pub fn run() -> Result<()> { - let subcommand_status = SubcommandStatus::new("status-header", "status-good", "status-bad"); + setup::is_setup()?; + let subcommand_status = CASILEUI.new_subcommand("status-header", "status-good", "status-bad"); CONF.set_bool("verbose", true)?; - setup::is_setup(subcommand_status)?; + eprintln!("foo"); + subcommand_status.end(false); Ok(()) } @@ -32,16 +34,16 @@ fn run_as() -> RunAsMode { /// Check to see if we're running in GitHub Actions pub fn is_gha() -> Result { let ret = env::var("GITHUB_ACTIONS").is_ok(); - // let status = SetupCheck::start("setup-is-gha"); - // (ret).then(|| status.pass()); + let status = CASILEUI.new_check("setup-is-gha"); + (ret).then(|| status.pass()); Ok(ret) } /// Check to see if we're running in GitLab CI pub fn is_glc() -> Result { let ret = env::var("GITLAB_CI").is_ok(); - // let status = SetupCheck::start("setup-is-glc"); - // (ret).then(|| status.pass()); + let status = CASILEUI.new_check("setup-is-glc"); + (ret).then(|| status.pass()); Ok(ret) } diff --git a/src/ui.rs b/src/ui.rs index e1cc0c47..825b0c43 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,259 +1,75 @@ -use crate::i18n::LocalText; - -use crate::config::CONF; -use crate::VERSION; - -use console::style; -use indicatif::{HumanDuration, MultiProgress, ProgressBar, ProgressFinish, ProgressStyle}; +use console::user_attended; use std::str; use std::sync::RwLock; -use std::time::Instant; + +use crate::ui_indicatif::IndicatifInterface; static ERROR_UI_WRITE: &str = "Unable to gain write lock on ui status wrapper"; lazy_static! { - pub static ref UI: RwLock = RwLock::new(Progress::new()); -} - -impl UI { - pub fn add(&self, bar: ProgressBar) -> ProgressBar { - let ui = self.write().expect(ERROR_UI_WRITE); - ui.add(bar) - } - pub fn remove(&self, bar: &ProgressBar) { - let ui = self.write().expect(ERROR_UI_WRITE); - bar.finish(); - ui.remove(bar); - } + #[derive(Debug)] + pub static ref CASILEUI: RwLock> = RwLock::new(UISwitcher::new()); } -#[derive(Debug)] -pub struct Progress(MultiProgress); - -impl Default for Progress { - fn default() -> Self { - Self::new() - } -} +#[derive(Debug, Default)] +pub struct UISwitcher {} -impl Progress { - pub fn new() -> Progress { - let progress = MultiProgress::new(); - progress.set_move_cursor(true); - Progress(progress) - } -} - -impl std::ops::Deref for Progress { - type Target = MultiProgress; - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -/// Top command level status handler -#[derive(Debug)] -pub struct CommandStatus { - started: Instant, -} - -impl Default for CommandStatus { - fn default() -> Self { - Self::new() - } -} - -impl CommandStatus { - pub fn new() -> CommandStatus { - let started = Instant::now(); - CommandStatus { started } - } - pub fn bar(&self) -> ProgressBar { - let prefix = style("⛫").cyan().to_string(); - ProgressBar::new_spinner() - .with_style(ProgressStyle::with_template("{prefix} {msg}").unwrap()) - .with_prefix(prefix) - } - pub fn show(&self, msg: String) { - let bar = self.bar(); - let msg = style(msg).cyan().bright().to_string(); - bar.finish_with_message(msg); - } - pub fn welcome(&self) { - let msg = LocalText::new("welcome").arg("version", *VERSION).fmt(); - self.show(msg); - } - pub fn farewell(&self) { - let time = HumanDuration(self.started.elapsed()); - let msg = LocalText::new("farewell").arg("duration", time).fmt(); - self.show(msg); - } -} - -#[derive(Debug)] -pub struct SubcommandStatus { - bar: ProgressBar, - good_msg: String, - bad_msg: String, -} - -impl SubcommandStatus { - pub fn new(key: &str, good_key: &str, bad_key: &str) -> SubcommandStatus { - let msg = style(LocalText::new(key).fmt()) - .yellow() - .bright() - .to_string(); - let prefix = style("⟳").yellow().to_string(); - let bar = ProgressBar::new_spinner() - .with_style(ProgressStyle::with_template("{prefix} {msg}").unwrap()) - .with_prefix(prefix); - let bar = UI.add(bar); - bar.set_message(msg); - let good_msg = style(LocalText::new(good_key).fmt()) - .green() - .bright() - .to_string(); - let bad_msg = style(LocalText::new(bad_key).fmt()) - .red() - .bright() - .to_string(); - SubcommandStatus { - bar, - good_msg, - bad_msg, +impl UISwitcher { + pub fn new() -> Box { + if user_attended() { + Box::::default() + } else { + Box::::default() } } - pub fn end(&self, status: bool) { - (status).then(|| self.pass()).unwrap_or_else(|| self.fail()); - } - pub fn pass(&self) { - let prefix = style("✔").green().to_string(); - self.set_prefix(prefix); - let msg = self.good_msg.to_owned(); - self.finish_with_message(msg); - } - pub fn fail(&self) { - let prefix = style("✗").red().to_string(); - self.set_prefix(prefix); - let msg = self.bad_msg.to_owned(); - self.finish_with_message(msg); - } } -impl std::ops::Deref for SubcommandStatus { - type Target = ProgressBar; - fn deref(&self) -> &Self::Target { - &self.bar - } -} - -#[derive(Debug)] -pub struct MakeTargetStatus { - bar: ProgressBar, - target: String, +pub trait UserInterface: Send + Sync { + fn welcome(&self); + fn farewell(&self); + fn new_subcommand(&self, key: &str, good_key: &str, bad_key: &str) + -> Box; + fn new_check(&self, key: &str) -> Box; + fn new_target(&self, target: String) -> Box; } -impl MakeTargetStatus { - pub fn new(mut target: String) -> MakeTargetStatus { - // Withouth this, copying the string in the terminal as a word brings a U+2069 with it - target.push(' '); - let msg = style( - LocalText::new("make-report-start") - .arg("target", style(target.clone()).white().bold()) - .fmt(), - ) - .yellow() - .bright() - .to_string(); - let pstyle = ProgressStyle::with_template("{spinner} {msg}") - .unwrap() - .tick_strings(&["↻", "✔"]); - let bar = ProgressBar::new_spinner() - .with_style(pstyle) - .with_message(msg); - let bar = UI.add(bar); - bar.tick(); - MakeTargetStatus { bar, target } +impl UserInterface for CASILEUI { + fn welcome(&self) { + self.write().expect(ERROR_UI_WRITE).welcome() } - pub fn stdout(&self, line: &str) { - let target = style(self.target.clone()).white().bold().to_string(); - let line = style(line).dim(); - self.println(format!("{target}: {line}")); + fn farewell(&self) { + self.write().expect(ERROR_UI_WRITE).farewell() } - pub fn stderr(&self, line: &str) { - let target = style(self.target.clone()).white().to_string(); - let line = style(line).dim(); - self.println(format!("{target}: {line}")); + fn new_subcommand( + &self, + key: &str, + good_key: &str, + bad_key: &str, + ) -> Box { + self.write() + .expect(ERROR_UI_WRITE) + .new_subcommand(key, good_key, bad_key) } - pub fn pass(&self) { - let target = self.target.clone(); - let allow_hide = !CONF.get_bool("debug").unwrap() && !CONF.get_bool("verbose").unwrap(); - if allow_hide && target.starts_with(".casile") { - UI.remove(&self.bar); - } else { - let msg = style( - LocalText::new("make-report-pass") - .arg("target", style(target).white().bold()) - .fmt(), - ) - .green() - .bright() - .to_string(); - self.finish_with_message(msg); - } + fn new_check(&self, key: &str) -> Box { + self.write().expect(ERROR_UI_WRITE).new_check(key) } - pub fn fail(&self) { - let msg = style( - LocalText::new("make-report-fail") - .arg("target", style(self.target.clone()).white().bold()) - .fmt(), - ) - .red() - .bright() - .to_string(); - self.finish_with_message(msg); + fn new_target(&self, target: String) -> Box { + self.write().expect(ERROR_UI_WRITE).new_target(target) } } -impl std::ops::Deref for MakeTargetStatus { - type Target = ProgressBar; - fn deref(&self) -> &Self::Target { - &self.bar - } +pub trait SubcommandStatus: Send + Sync { + fn end(&self, status: bool); + fn dump(&self, backlog: &[String]); } -#[derive(Debug)] -pub struct SetupCheck(ProgressBar); - -impl SetupCheck { - pub fn start(key: &str) -> SetupCheck { - let msg = LocalText::new(key).fmt(); - let bar = if CONF.get_bool("debug").unwrap() || CONF.get_bool("verbose").unwrap() { - let no = style(LocalText::new("setup-false").fmt()).red().to_string(); - let bar = ProgressBar::new_spinner() - .with_style(ProgressStyle::with_template("{msg}").unwrap()) - .with_finish(ProgressFinish::AbandonWithMessage( - format!("{msg} {no}").into(), - )); - UI.add(bar) - } else { - ProgressBar::hidden() - }; - bar.set_message(msg); - SetupCheck(bar) - } - pub fn pass(&self) { - let msg = self.0.message(); - let yes = style(LocalText::new("setup-true").fmt()) - .green() - .to_string(); - self.finish_with_message(format!("{msg} {yes}")) - } +pub trait SetupCheck: Send + Sync { + fn pass(&self); } -impl std::ops::Deref for SetupCheck { - type Target = ProgressBar; - fn deref(&self) -> &Self::Target { - &self.0 - } +pub trait MakeTargetStatus: Send + Sync { + fn stdout(&self, line: &str); + fn stderr(&self, line: &str); + fn pass(&self); + fn fail(&self); } diff --git a/src/ui_indicatif.rs b/src/ui_indicatif.rs new file mode 100644 index 00000000..f8f53c0d --- /dev/null +++ b/src/ui_indicatif.rs @@ -0,0 +1,273 @@ +use crate::i18n::LocalText; + +use crate::config::CONF; +use crate::ui::*; +use crate::VERSION; + +use console::style; +use indicatif::{HumanDuration, MultiProgress, ProgressBar, ProgressFinish, ProgressStyle}; +use std::time::Instant; + +#[derive(Debug)] +pub struct IndicatifInterface { + progress: MultiProgress, + started: Instant, +} + +impl std::ops::Deref for IndicatifInterface { + type Target = MultiProgress; + fn deref(&self) -> &Self::Target { + &self.progress + } +} + +impl Default for IndicatifInterface { + fn default() -> Self { + let progress = MultiProgress::new(); + progress.set_move_cursor(true); + let started = Instant::now(); + IndicatifInterface { progress, started } + } +} + +impl IndicatifInterface { + pub fn bar(&self) -> ProgressBar { + let prefix = style("⛫").cyan().to_string(); + ProgressBar::new_spinner() + .with_style(ProgressStyle::with_template("{prefix} {msg}").unwrap()) + .with_prefix(prefix) + } + pub fn show(&self, msg: String) { + let bar = self.bar(); + let msg = style(msg).cyan().bright().to_string(); + bar.finish_with_message(msg); + } +} + +impl UserInterface for IndicatifInterface { + fn welcome(&self) { + let msg = LocalText::new("welcome").arg("version", *VERSION).fmt(); + self.show(msg); + } + fn farewell(&self) { + let time = HumanDuration(self.started.elapsed()); + let msg = LocalText::new("farewell").arg("duration", time).fmt(); + self.show(msg); + } + fn new_subcommand( + &self, + key: &str, + good_key: &str, + bad_key: &str, + ) -> Box { + Box::new(IndicatifSubcommandStatus::new(self, key, good_key, bad_key)) + } + fn new_check(&self, key: &str) -> Box { + Box::new(IndicatifSetupCheck::new(self, key)) + } + fn new_target(&self, target: String) -> Box { + Box::new(IndicatifMakeTargetStatus::new(self, target)) + } +} + +#[derive(Debug)] +pub struct IndicatifSubcommandStatus { + progress: MultiProgress, + bar: ProgressBar, + good_msg: String, + bad_msg: String, +} + +impl std::ops::Deref for IndicatifSubcommandStatus { + type Target = ProgressBar; + fn deref(&self) -> &Self::Target { + &self.bar + } +} + +impl IndicatifSubcommandStatus { + pub fn new( + ui: &IndicatifInterface, + key: &str, + good_key: &str, + bad_key: &str, + ) -> IndicatifSubcommandStatus { + let msg = style(LocalText::new(key).fmt()) + .yellow() + .bright() + .to_string(); + let prefix = style("⟳").yellow().to_string(); + let bar = ProgressBar::new_spinner() + .with_style(ProgressStyle::with_template("{prefix} {msg}").unwrap()) + .with_prefix(prefix); + let bar = ui.add(bar); + bar.set_message(msg); + let good_msg = style(LocalText::new(good_key).fmt()) + .green() + .bright() + .to_string(); + let bad_msg = style(LocalText::new(bad_key).fmt()) + .red() + .bright() + .to_string(); + IndicatifSubcommandStatus { + progress: ui.progress.clone(), + bar, + good_msg, + bad_msg, + } + } + pub fn pass(&self) { + let prefix = style("✔").green().to_string(); + self.set_prefix(prefix); + let msg = self.good_msg.to_owned(); + self.finish_with_message(msg); + } + pub fn fail(&self) { + let prefix = style("✗").red().to_string(); + self.set_prefix(prefix); + let msg = self.bad_msg.to_owned(); + self.finish_with_message(msg); + } +} + +impl SubcommandStatus for IndicatifSubcommandStatus { + fn end(&self, status: bool) { + (status).then(|| self.pass()).unwrap_or_else(|| self.fail()); + } + fn dump(&self, backlog: &[String]) { + let bar = + ProgressBar::new_spinner().with_style(ProgressStyle::with_template("{msg}").unwrap()); + let bar = self.progress.add(bar); + let mut dump = String::new(); + let start = LocalText::new("make-backlog-start").fmt(); + let start = format!("{} {start}\n", style(style("┄┄┄┄┄┄").cyan())); + dump.push_str(start.as_str()); + for line in backlog.iter() { + dump.push_str(line.as_str()); + dump.push('\n'); + } + let end = LocalText::new("make-backlog-end").fmt(); + let end = format!("{} {end}", style(style("┄┄┄┄┄").cyan())); + dump.push_str(end.as_str()); + bar.set_message(dump); + bar.finish(); + } +} + +#[derive(Debug)] +pub struct IndicatifMakeTargetStatus { + bar: ProgressBar, + target: String, +} + +impl std::ops::Deref for IndicatifMakeTargetStatus { + type Target = ProgressBar; + fn deref(&self) -> &Self::Target { + &self.bar + } +} + +impl IndicatifMakeTargetStatus { + pub fn new(ui: &IndicatifInterface, mut target: String) -> IndicatifMakeTargetStatus { + // Withouth this, copying the string in the terminal as a word brings a U+2069 with it + target.push(' '); + let msg = style( + LocalText::new("make-report-start") + .arg("target", style(target.clone()).white().bold()) + .fmt(), + ) + .yellow() + .bright() + .to_string(); + let pstyle = ProgressStyle::with_template("{spinner} {msg}") + .unwrap() + .tick_strings(&["↻", "✔"]); + let bar = ProgressBar::new_spinner() + .with_style(pstyle) + .with_message(msg); + let bar = ui.add(bar); + bar.tick(); + IndicatifMakeTargetStatus { bar, target } + } +} + +impl MakeTargetStatus for IndicatifMakeTargetStatus { + fn stdout(&self, line: &str) { + let target = style(self.target.clone()).white().bold().to_string(); + let line = style(line).dim(); + self.println(format!("{target}: {line}")); + } + fn stderr(&self, line: &str) { + let target = style(self.target.clone()).white().to_string(); + let line = style(line).dim(); + self.println(format!("{target}: {line}")); + } + fn pass(&self) { + let target = self.target.clone(); + let allow_hide = !CONF.get_bool("debug").unwrap() && !CONF.get_bool("verbose").unwrap(); + if allow_hide && target.starts_with(".casile") { + // UI.remove(&self.bar); + } else { + let msg = style( + LocalText::new("make-report-pass") + .arg("target", style(target).white().bold()) + .fmt(), + ) + .green() + .bright() + .to_string(); + self.finish_with_message(msg); + } + } + fn fail(&self) { + let msg = style( + LocalText::new("make-report-fail") + .arg("target", style(self.target.clone()).white().bold()) + .fmt(), + ) + .red() + .bright() + .to_string(); + self.finish_with_message(msg); + } +} + +#[derive(Debug)] +pub struct IndicatifSetupCheck(ProgressBar); + +impl std::ops::Deref for IndicatifSetupCheck { + type Target = ProgressBar; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl IndicatifSetupCheck { + pub fn new(ui: &IndicatifInterface, key: &str) -> IndicatifSetupCheck { + let msg = LocalText::new(key).fmt(); + let bar = if CONF.get_bool("debug").unwrap() || CONF.get_bool("verbose").unwrap() { + let no = style(LocalText::new("setup-false").fmt()).red().to_string(); + let bar = ProgressBar::new_spinner() + .with_style(ProgressStyle::with_template("{msg}").unwrap()) + .with_finish(ProgressFinish::AbandonWithMessage( + format!("{msg} {no}").into(), + )); + ui.add(bar) + } else { + ProgressBar::hidden() + }; + bar.set_message(msg); + IndicatifSetupCheck(bar) + } +} + +impl SetupCheck for IndicatifSetupCheck { + fn pass(&self) { + let msg = self.message(); + let yes = style(LocalText::new("setup-true").fmt()) + .green() + .to_string(); + self.finish_with_message(format!("{msg} {yes}")) + } +} From 6154d96fad6e502d091a3b56b26a07767b52a9ef Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Fri, 10 May 2024 11:54:40 +0300 Subject: [PATCH 16/17] refactor(cli): Move some message handling where it will be easier to reuse --- src/make/mod.rs | 2 +- src/run/mod.rs | 2 +- src/setup/mod.rs | 4 ++-- src/status/mod.rs | 2 +- src/ui.rs | 45 +++++++++++++++++++++++++++++--------------- src/ui_indicatif.rs | 46 +++++++++++++++------------------------------ 6 files changed, 50 insertions(+), 51 deletions(-) diff --git a/src/make/mod.rs b/src/make/mod.rs index 668b54ed..82932840 100644 --- a/src/make/mod.rs +++ b/src/make/mod.rs @@ -13,7 +13,7 @@ use subprocess::{Exec, ExitStatus, Redirection}; /// Build specified target(s) pub fn run(target: Vec) -> Result<()> { setup::is_setup()?; - let subcommand_status = CASILEUI.new_subcommand("make-header", "make-good", "make-bad"); + let subcommand_status = CASILEUI.new_subcommand("make"); let mut makeflags: Vec = Vec::new(); let cpus = &num_cpus::get().to_string(); makeflags.push(OsString::from(format!("--jobs={cpus}"))); diff --git a/src/run/mod.rs b/src/run/mod.rs index 71350378..8f91ddce 100644 --- a/src/run/mod.rs +++ b/src/run/mod.rs @@ -9,7 +9,7 @@ use subprocess::{Exec, Redirection}; /// Run helper script inside CaSILE environment pub fn run(name: String, arguments: Vec) -> Result<()> { setup::is_setup()?; - let subcommand_status = CASILEUI.new_subcommand("run-header", "run-good", "run-bad"); + let subcommand_status = CASILEUI.new_subcommand("run"); let cpus = &num_cpus::get().to_string(); let mut process = Exec::cmd(format!("{CONFIGURE_DATADIR}/scripts/{name}")).args(&arguments); let gitname = status::get_gitname()?; diff --git a/src/setup/mod.rs b/src/setup/mod.rs index 0fb7c8a2..9c86ccab 100644 --- a/src/setup/mod.rs +++ b/src/setup/mod.rs @@ -13,7 +13,7 @@ use subprocess::{Exec, NullFile, Redirection}; // FTL: help-subcommand-setup /// Setup a publishing project for use with CaSILE pub fn run() -> Result<()> { - let subcommand_status = CASILEUI.new_subcommand("setup-header", "setup-good", "setup_bad"); + let subcommand_status = CASILEUI.new_subcommand("setup"); let path = &CONF.get_string("path")?; let metadata = fs::metadata(path)?; let ret = match metadata.is_dir() { @@ -42,7 +42,7 @@ pub fn run() -> Result<()> { /// Evaluate whether this project is properly configured pub fn is_setup() -> Result { - let subcommand_status = CASILEUI.new_subcommand("status-header", "status-good", "status-bad"); + let subcommand_status = CASILEUI.new_subcommand("status"); let results = Arc::new(RwLock::new(Vec::new())); // First round of tests, entirely independent diff --git a/src/status/mod.rs b/src/status/mod.rs index 1dda44cb..f240ca5b 100644 --- a/src/status/mod.rs +++ b/src/status/mod.rs @@ -9,7 +9,7 @@ use std::{env, path}; /// Dump what we know about the repo pub fn run() -> Result<()> { setup::is_setup()?; - let subcommand_status = CASILEUI.new_subcommand("status-header", "status-good", "status-bad"); + let subcommand_status = CASILEUI.new_subcommand("status"); CONF.set_bool("verbose", true)?; eprintln!("foo"); subcommand_status.end(false); diff --git a/src/ui.rs b/src/ui.rs index 825b0c43..dcac78c7 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,21 +1,22 @@ +use crate::i18n::LocalText; +use crate::ui_indicatif::IndicatifInterface; + use console::user_attended; use std::str; use std::sync::RwLock; -use crate::ui_indicatif::IndicatifInterface; - static ERROR_UI_WRITE: &str = "Unable to gain write lock on ui status wrapper"; lazy_static! { #[derive(Debug)] - pub static ref CASILEUI: RwLock> = RwLock::new(UISwitcher::new()); + pub static ref CASILEUI: RwLock> = RwLock::new(UISwitcher::pick()); } #[derive(Debug, Default)] pub struct UISwitcher {} impl UISwitcher { - pub fn new() -> Box { + pub fn pick() -> Box { if user_attended() { Box::::default() } else { @@ -27,8 +28,7 @@ impl UISwitcher { pub trait UserInterface: Send + Sync { fn welcome(&self); fn farewell(&self); - fn new_subcommand(&self, key: &str, good_key: &str, bad_key: &str) - -> Box; + fn new_subcommand(&self, key: &str) -> Box; fn new_check(&self, key: &str) -> Box; fn new_target(&self, target: String) -> Box; } @@ -40,15 +40,8 @@ impl UserInterface for CASILEUI { fn farewell(&self) { self.write().expect(ERROR_UI_WRITE).farewell() } - fn new_subcommand( - &self, - key: &str, - good_key: &str, - bad_key: &str, - ) -> Box { - self.write() - .expect(ERROR_UI_WRITE) - .new_subcommand(key, good_key, bad_key) + fn new_subcommand(&self, key: &str) -> Box { + self.write().expect(ERROR_UI_WRITE).new_subcommand(key) } fn new_check(&self, key: &str) -> Box { self.write().expect(ERROR_UI_WRITE).new_check(key) @@ -73,3 +66,25 @@ pub trait MakeTargetStatus: Send + Sync { fn pass(&self); fn fail(&self); } + +#[derive(Debug)] +pub struct SubcommandHeaderMessages { + pub msg: String, + pub good_msg: String, + pub bad_msg: String, +} + +impl SubcommandHeaderMessages { + pub fn new(key: &str) -> Self { + let msg = LocalText::new(key).fmt().to_string(); + let good_key = format!("{key}-good"); + let good_msg = LocalText::new(good_key.as_str()).fmt(); + let bad_key = format!("{key}-bad"); + let bad_msg = LocalText::new(bad_key.as_str()).fmt(); + Self { + msg, + good_msg, + bad_msg, + } + } +} diff --git a/src/ui_indicatif.rs b/src/ui_indicatif.rs index f8f53c0d..c5613142 100644 --- a/src/ui_indicatif.rs +++ b/src/ui_indicatif.rs @@ -54,13 +54,8 @@ impl UserInterface for IndicatifInterface { let msg = LocalText::new("farewell").arg("duration", time).fmt(); self.show(msg); } - fn new_subcommand( - &self, - key: &str, - good_key: &str, - bad_key: &str, - ) -> Box { - Box::new(IndicatifSubcommandStatus::new(self, key, good_key, bad_key)) + fn new_subcommand(&self, key: &str) -> Box { + Box::new(IndicatifSubcommandStatus::new(self, key)) } fn new_check(&self, key: &str) -> Box { Box::new(IndicatifSetupCheck::new(self, key)) @@ -74,8 +69,7 @@ impl UserInterface for IndicatifInterface { pub struct IndicatifSubcommandStatus { progress: MultiProgress, bar: ProgressBar, - good_msg: String, - bad_msg: String, + messages: SubcommandHeaderMessages, } impl std::ops::Deref for IndicatifSubcommandStatus { @@ -86,47 +80,37 @@ impl std::ops::Deref for IndicatifSubcommandStatus { } impl IndicatifSubcommandStatus { - pub fn new( - ui: &IndicatifInterface, - key: &str, - good_key: &str, - bad_key: &str, - ) -> IndicatifSubcommandStatus { - let msg = style(LocalText::new(key).fmt()) - .yellow() - .bright() - .to_string(); + pub fn new(ui: &IndicatifInterface, key: &str) -> IndicatifSubcommandStatus { + let messages = SubcommandHeaderMessages::new(key); let prefix = style("⟳").yellow().to_string(); let bar = ProgressBar::new_spinner() .with_style(ProgressStyle::with_template("{prefix} {msg}").unwrap()) .with_prefix(prefix); let bar = ui.add(bar); + let msg = style(messages.msg.to_owned()).yellow().bright().to_string(); bar.set_message(msg); - let good_msg = style(LocalText::new(good_key).fmt()) - .green() - .bright() - .to_string(); - let bad_msg = style(LocalText::new(bad_key).fmt()) - .red() - .bright() - .to_string(); IndicatifSubcommandStatus { progress: ui.progress.clone(), bar, - good_msg, - bad_msg, + messages, } } pub fn pass(&self) { let prefix = style("✔").green().to_string(); self.set_prefix(prefix); - let msg = self.good_msg.to_owned(); + let msg = style(self.messages.good_msg.to_owned()) + .green() + .bright() + .to_string(); self.finish_with_message(msg); } pub fn fail(&self) { let prefix = style("✗").red().to_string(); self.set_prefix(prefix); - let msg = self.bad_msg.to_owned(); + let msg = style(self.messages.bad_msg.to_owned()) + .red() + .bright() + .to_string(); self.finish_with_message(msg); } } From 1753ad32e2b85a4fbd30186732ceaf77d5f2f00d Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Fri, 10 May 2024 12:14:58 +0300 Subject: [PATCH 17/17] feat(cli): Add alternative plain interface to the CLI --- Makefile.am | 2 +- src/lib.rs | 1 + src/ui.rs | 21 ++++++++- src/ui_ascii.rs | 103 ++++++++++++++++++++++++++++++++++++++++++++ src/ui_indicatif.rs | 99 ++++++++++++++++++++++-------------------- 5 files changed, 177 insertions(+), 49 deletions(-) create mode 100644 src/ui_ascii.rs diff --git a/Makefile.am b/Makefile.am index d4e13f4e..8d5be76c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -32,7 +32,7 @@ nobase_data_DATA = rules/casile.mk $(reverse_lang_key_files) nobase_dist_data_DATA = rules/rules.mk rules/functions.mk rules/translation.mk rules/utilities.mk $(lang_key_files) nobase_dist_data_DATA += rules/ebooks.mk rules/mdbook.mk rules/renderings.mk rules/zola.mk nobase_dist_pkgdata_DATA = $(LUALIBRARIES) -_casile_libs = src/lib.rs src/cli.rs src/config.rs src/i18n.rs src/ui.rs src/ui_indicatif.rs +_casile_libs = src/lib.rs src/cli.rs src/config.rs src/i18n.rs src/ui.rs src/ui_indicatif.rs src/ui_ascii.rs _casile_modules = src/make/mod.rs src/run/mod.rs src/setup/mod.rs src/status/mod.rs _casile_assets = assets/en-US/cli.ftl assets/tr-TR/cli.ftl bin_PROGRAMS = casile diff --git a/src/lib.rs b/src/lib.rs index ed00af95..1215be13 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,6 +17,7 @@ pub mod cli; pub mod config; pub mod i18n; pub mod ui; +pub mod ui_ascii; pub mod ui_indicatif; // Subcommands diff --git a/src/ui.rs b/src/ui.rs index dcac78c7..d664f025 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,5 +1,7 @@ use crate::i18n::LocalText; +use crate::ui_ascii::AsciiInterface; use crate::ui_indicatif::IndicatifInterface; +use crate::VERSION; use console::user_attended; use std::str; @@ -20,7 +22,7 @@ impl UISwitcher { if user_attended() { Box::::default() } else { - Box::::default() + Box::::default() } } } @@ -67,6 +69,23 @@ pub trait MakeTargetStatus: Send + Sync { fn fail(&self); } +#[derive(Debug, Default)] +pub struct UserInterfaceMessages { + pub welcome: String, + // pub farewell: String, +} + +impl UserInterfaceMessages { + pub fn new() -> Self { + let welcome = LocalText::new("welcome").arg("version", *VERSION).fmt(); + // let farewell = LocalText::new("farewell").arg("duration", time).fmt(); + Self { + welcome, + // farewell, + } + } +} + #[derive(Debug)] pub struct SubcommandHeaderMessages { pub msg: String, diff --git a/src/ui_ascii.rs b/src/ui_ascii.rs new file mode 100644 index 00000000..44da4f4c --- /dev/null +++ b/src/ui_ascii.rs @@ -0,0 +1,103 @@ +use crate::i18n::LocalText; +use crate::ui::*; + +use indicatif::HumanDuration; +use std::time::Instant; + +#[derive(Debug)] +pub struct AsciiInterface { + messages: UserInterfaceMessages, + started: Instant, +} + +impl Default for AsciiInterface { + fn default() -> Self { + let started = Instant::now(); + let messages = UserInterfaceMessages::new(); + Self { messages, started } + } +} + +impl UserInterface for AsciiInterface { + fn welcome(&self) { + let welcome = &self.messages.welcome; + println!("{welcome}"); + } + fn farewell(&self) { + let time = HumanDuration(self.started.elapsed()); + let farewell = LocalText::new("farewell").arg("duration", time).fmt(); + println!("{farewell}"); + } + fn new_subcommand(&self, key: &str) -> Box { + Box::new(AsciiSubcommandStatus::new(key)) + } + fn new_check(&self, key: &str) -> Box { + Box::new(AsciiSetupCheck::new(self, key)) + } + fn new_target(&self, target: String) -> Box { + Box::new(AsciiMakeTargetStatus::new(target)) + } +} + +#[derive(Debug, Default)] +pub struct AsciiSubcommandStatus {} + +impl AsciiSubcommandStatus { + fn new(_key: &str) -> Self { + Self {} + } +} + +impl SubcommandStatus for AsciiSubcommandStatus { + fn end(&self, _status: bool) {} + fn dump(&self, _backlog: &[String]) {} +} + +#[derive(Debug, Default)] +pub struct AsciiSetupCheck {} + +impl AsciiSetupCheck { + fn new(_ui: &AsciiInterface, _key: &str) -> Self { + Self {} + } +} + +impl SetupCheck for AsciiSetupCheck { + fn pass(&self) {} +} + +#[derive(Debug, Default)] +pub struct AsciiMakeTargetStatus { + target: String, +} + +impl AsciiMakeTargetStatus { + fn new(target: String) -> Self { + let msg = LocalText::new("make-report-start") + .arg("target", &target) + .fmt(); + println!("{msg}"); + Self { target } + } +} + +impl MakeTargetStatus for AsciiMakeTargetStatus { + fn stdout(&self, line: &str) { + println!("{}: {line}", &self.target); + } + fn stderr(&self, line: &str) { + eprintln!("{}: {line}", &self.target); + } + fn pass(&self) { + let msg = LocalText::new("make-report-pass") + .arg("target", &self.target) + .fmt(); + println!("{msg}"); + } + fn fail(&self) { + let msg = LocalText::new("make-report-fail") + .arg("target", &self.target) + .fmt(); + eprintln!("{msg}"); + } +} diff --git a/src/ui_indicatif.rs b/src/ui_indicatif.rs index c5613142..2b43b730 100644 --- a/src/ui_indicatif.rs +++ b/src/ui_indicatif.rs @@ -2,7 +2,6 @@ use crate::i18n::LocalText; use crate::config::CONF; use crate::ui::*; -use crate::VERSION; use console::style; use indicatif::{HumanDuration, MultiProgress, ProgressBar, ProgressFinish, ProgressStyle}; @@ -11,6 +10,7 @@ use std::time::Instant; #[derive(Debug)] pub struct IndicatifInterface { progress: MultiProgress, + messages: UserInterfaceMessages, started: Instant, } @@ -26,7 +26,12 @@ impl Default for IndicatifInterface { let progress = MultiProgress::new(); progress.set_move_cursor(true); let started = Instant::now(); - IndicatifInterface { progress, started } + let messages = UserInterfaceMessages::new(); + Self { + progress, + messages, + started, + } } } @@ -46,8 +51,8 @@ impl IndicatifInterface { impl UserInterface for IndicatifInterface { fn welcome(&self) { - let msg = LocalText::new("welcome").arg("version", *VERSION).fmt(); - self.show(msg); + let msg = &self.messages.welcome; + self.show(msg.to_string()); } fn farewell(&self) { let time = HumanDuration(self.started.elapsed()); @@ -80,7 +85,7 @@ impl std::ops::Deref for IndicatifSubcommandStatus { } impl IndicatifSubcommandStatus { - pub fn new(ui: &IndicatifInterface, key: &str) -> IndicatifSubcommandStatus { + pub fn new(ui: &IndicatifInterface, key: &str) -> Self { let messages = SubcommandHeaderMessages::new(key); let prefix = style("⟳").yellow().to_string(); let bar = ProgressBar::new_spinner() @@ -89,7 +94,7 @@ impl IndicatifSubcommandStatus { let bar = ui.add(bar); let msg = style(messages.msg.to_owned()).yellow().bright().to_string(); bar.set_message(msg); - IndicatifSubcommandStatus { + Self { progress: ui.progress.clone(), bar, messages, @@ -139,6 +144,45 @@ impl SubcommandStatus for IndicatifSubcommandStatus { } } +#[derive(Debug)] +pub struct IndicatifSetupCheck(ProgressBar); + +impl std::ops::Deref for IndicatifSetupCheck { + type Target = ProgressBar; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl IndicatifSetupCheck { + pub fn new(ui: &IndicatifInterface, key: &str) -> Self { + let msg = LocalText::new(key).fmt(); + let bar = if CONF.get_bool("debug").unwrap() || CONF.get_bool("verbose").unwrap() { + let no = style(LocalText::new("setup-false").fmt()).red().to_string(); + let bar = ProgressBar::new_spinner() + .with_style(ProgressStyle::with_template("{msg}").unwrap()) + .with_finish(ProgressFinish::AbandonWithMessage( + format!("{msg} {no}").into(), + )); + ui.add(bar) + } else { + ProgressBar::hidden() + }; + bar.set_message(msg); + Self(bar) + } +} + +impl SetupCheck for IndicatifSetupCheck { + fn pass(&self) { + let msg = self.message(); + let yes = style(LocalText::new("setup-true").fmt()) + .green() + .to_string(); + self.finish_with_message(format!("{msg} {yes}")) + } +} + #[derive(Debug)] pub struct IndicatifMakeTargetStatus { bar: ProgressBar, @@ -153,7 +197,7 @@ impl std::ops::Deref for IndicatifMakeTargetStatus { } impl IndicatifMakeTargetStatus { - pub fn new(ui: &IndicatifInterface, mut target: String) -> IndicatifMakeTargetStatus { + pub fn new(ui: &IndicatifInterface, mut target: String) -> Self { // Withouth this, copying the string in the terminal as a word brings a U+2069 with it target.push(' '); let msg = style( @@ -172,7 +216,7 @@ impl IndicatifMakeTargetStatus { .with_message(msg); let bar = ui.add(bar); bar.tick(); - IndicatifMakeTargetStatus { bar, target } + Self { bar, target } } } @@ -216,42 +260,3 @@ impl MakeTargetStatus for IndicatifMakeTargetStatus { self.finish_with_message(msg); } } - -#[derive(Debug)] -pub struct IndicatifSetupCheck(ProgressBar); - -impl std::ops::Deref for IndicatifSetupCheck { - type Target = ProgressBar; - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl IndicatifSetupCheck { - pub fn new(ui: &IndicatifInterface, key: &str) -> IndicatifSetupCheck { - let msg = LocalText::new(key).fmt(); - let bar = if CONF.get_bool("debug").unwrap() || CONF.get_bool("verbose").unwrap() { - let no = style(LocalText::new("setup-false").fmt()).red().to_string(); - let bar = ProgressBar::new_spinner() - .with_style(ProgressStyle::with_template("{msg}").unwrap()) - .with_finish(ProgressFinish::AbandonWithMessage( - format!("{msg} {no}").into(), - )); - ui.add(bar) - } else { - ProgressBar::hidden() - }; - bar.set_message(msg); - IndicatifSetupCheck(bar) - } -} - -impl SetupCheck for IndicatifSetupCheck { - fn pass(&self) { - let msg = self.message(); - let yes = style(LocalText::new("setup-true").fmt()) - .green() - .to_string(); - self.finish_with_message(format!("{msg} {yes}")) - } -}