From b878bcf169473e86d34e7228daeba1bd93eabdf1 Mon Sep 17 00:00:00 2001 From: Peter Becich Date: Sat, 6 Jul 2024 22:10:49 -0700 Subject: [PATCH 1/8] search parent dirs for workspace https://github.com/purescript/spago/issues/1237 --- spago.lock | 1785 +++++++++++++++++++---------------------- src/Spago/Config.purs | 52 +- src/Spago/Paths.purs | 13 + test/Spago/Paths.purs | 21 + 4 files changed, 905 insertions(+), 966 deletions(-) create mode 100644 test/Spago/Paths.purs diff --git a/spago.lock b/spago.lock index 1d0f00734..ea0b151e9 100644 --- a/spago.lock +++ b/spago.lock @@ -2,977 +2,840 @@ workspace: packages: docs-search-client-halogen: path: docs-search/client-halogen - core: - dependencies: - - aff - - aff-promise - - arrays - - codec-json - - control - - css - - docs-search-common - - effect - - either - - foldable-traversable - - halogen - - halogen-css - - halogen-subscriptions - - js-uri - - json - - language-purescript - - lists - - markdown-it - - markdown-it-halogen - - maybe - - newtype - - ordered-collections - - prelude - - profunctor-lenses - - search-trie - - strings - - tuples - - web-dom - - web-events - - web-html - - web-storage - - web-uievents - build_plan: - - aff - - aff-promise - - argonaut-core - - arrays - - avar - - bifunctors - - catenable-lists - - codec - - codec-json - - colors - - console - - const - - contravariant - - control - - css - - datetime - - distributive - - docs-search-common - - dom-indexed - - effect - - either - - enums - - exceptions - - exists - - fixed-points - - foldable-traversable - - foreign - - foreign-object - - fork - - formatters - - free - - freeap - - functions - - functors - - gen - - halogen - - halogen-css - - halogen-subscriptions - - halogen-vdom - - html-parser-halogen - - identity - - integers - - invariant - - js-date - - js-promise - - js-uri - - json - - json-codecs - - language-purescript - - lazy - - lcg - - lists - - markdown-it - - markdown-it-halogen - - maybe - - media-types - - newtype - - nonempty - - now - - nullable - - numbers - - options - - ordered-collections - - orders - - parallel - - parsing - - partial - - prelude - - profunctor - - profunctor-lenses - - quickcheck - - quickcheck-laws - - random - - record - - refs - - safe-coerce - - search-trie - - st - - string-parsers - - strings - - tailrec - - these - - transformers - - tuples - - type-equality - - typelevel-prelude - - unfoldable - - unicode - - unsafe-coerce - - unsafe-reference - - variant - - versions - - web-clipboard - - web-dom - - web-events - - web-file - - web-html - - web-pointerevents - - web-storage - - web-touchevents - - web-uievents - test: - dependencies: [] - build_plan: [] + dependencies: + - aff + - aff-promise + - arrays + - codec-json + - control + - css + - docs-search-common + - effect + - either + - foldable-traversable + - halogen + - halogen-css + - halogen-subscriptions + - js-uri + - json + - language-purescript + - lists + - markdown-it + - markdown-it-halogen + - maybe + - newtype + - ordered-collections + - prelude + - profunctor-lenses + - search-trie + - strings + - tuples + - web-dom + - web-events + - web-html + - web-storage + - web-uievents + test_dependencies: [] + build_plan: + - aff + - aff-promise + - argonaut-core + - arrays + - avar + - bifunctors + - catenable-lists + - codec + - codec-json + - colors + - console + - const + - contravariant + - control + - css + - datetime + - distributive + - docs-search-common + - dom-indexed + - effect + - either + - enums + - exceptions + - exists + - fixed-points + - foldable-traversable + - foreign + - foreign-object + - fork + - formatters + - free + - freeap + - functions + - functors + - gen + - halogen + - halogen-css + - halogen-subscriptions + - halogen-vdom + - html-parser-halogen + - identity + - integers + - invariant + - js-date + - js-promise + - js-uri + - json + - json-codecs + - language-purescript + - lazy + - lcg + - lists + - markdown-it + - markdown-it-halogen + - maybe + - media-types + - newtype + - nonempty + - now + - nullable + - numbers + - options + - ordered-collections + - orders + - parallel + - parsing + - partial + - prelude + - profunctor + - profunctor-lenses + - quickcheck + - quickcheck-laws + - random + - record + - refs + - safe-coerce + - search-trie + - st + - string-parsers + - strings + - tailrec + - these + - transformers + - tuples + - type-equality + - typelevel-prelude + - unfoldable + - unicode + - unsafe-coerce + - unsafe-reference + - variant + - versions + - web-clipboard + - web-dom + - web-events + - web-file + - web-html + - web-pointerevents + - web-storage + - web-touchevents + - web-uievents docs-search-common: path: docs-search/common - core: - dependencies: - - aff - - aff-promise - - argonaut-core - - arrays - - bifunctors - - codec - - codec-json - - control - - effect - - either - - exceptions - - foldable-traversable - - json - - json-codecs - - language-purescript - - lists - - maybe - - newtype - - ordered-collections - - prelude - - profunctor - - profunctor-lenses - - safe-coerce - - search-trie - - string-parsers - - strings - - transformers - - tuples - - unsafe-coerce - - variant - build_plan: - - aff - - aff-promise - - argonaut-core - - arrays - - bifunctors - - codec - - codec-json - - console - - const - - contravariant - - control - - datetime - - distributive - - effect - - either - - enums - - exceptions - - exists - - fixed-points - - foldable-traversable - - foreign - - foreign-object - - formatters - - functions - - functors - - gen - - identity - - integers - - invariant - - json - - json-codecs - - language-purescript - - lazy - - lcg - - lists - - maybe - - newtype - - nonempty - - nullable - - numbers - - ordered-collections - - orders - - parallel - - parsing - - partial - - prelude - - profunctor - - profunctor-lenses - - quickcheck - - quickcheck-laws - - random - - record - - refs - - safe-coerce - - search-trie - - st - - string-parsers - - strings - - tailrec - - these - - transformers - - tuples - - type-equality - - typelevel-prelude - - unfoldable - - unicode - - unsafe-coerce - - variant - - versions - test: - dependencies: [] - build_plan: [] + dependencies: + - aff + - aff-promise + - argonaut-core + - arrays + - bifunctors + - codec + - codec-json + - control + - effect + - either + - exceptions + - foldable-traversable + - json + - json-codecs + - language-purescript + - lists + - maybe + - newtype + - ordered-collections + - prelude + - profunctor + - profunctor-lenses + - safe-coerce + - search-trie + - string-parsers + - strings + - transformers + - tuples + - unsafe-coerce + - variant + test_dependencies: [] + build_plan: + - aff + - aff-promise + - argonaut-core + - arrays + - bifunctors + - codec + - codec-json + - console + - const + - contravariant + - control + - datetime + - distributive + - effect + - either + - enums + - exceptions + - exists + - fixed-points + - foldable-traversable + - foreign + - foreign-object + - formatters + - functions + - functors + - gen + - identity + - integers + - invariant + - json + - json-codecs + - language-purescript + - lazy + - lcg + - lists + - maybe + - newtype + - nonempty + - nullable + - numbers + - ordered-collections + - orders + - parallel + - parsing + - partial + - prelude + - profunctor + - profunctor-lenses + - quickcheck + - quickcheck-laws + - random + - record + - refs + - safe-coerce + - search-trie + - st + - string-parsers + - strings + - tailrec + - these + - transformers + - tuples + - type-equality + - typelevel-prelude + - unfoldable + - unicode + - unsafe-coerce + - variant + - versions docs-search-index: path: docs-search/index - core: - dependencies: - - aff - - argonaut-core - - arrays - - codec-json - - console - - docs-search-common - - effect - - either - - foldable-traversable - - identity - - json - - json-codecs - - language-purescript - - lists - - maybe - - newtype - - node-buffer - - node-fs - - node-path - - node-process - - ordered-collections - - prelude - - profunctor - - search-trie - - string-parsers - - strings - - tuples - - unsafe-coerce - build_plan: - - aff - - aff-promise - - argonaut-core - - arraybuffer-types - - arrays - - bifunctors - - codec - - codec-json - - console - - const - - contravariant - - control - - datetime - - distributive - - docs-search-common - - effect - - either - - enums - - exceptions - - exists - - fixed-points - - foldable-traversable - - foreign - - foreign-object - - formatters - - functions - - functors - - gen - - identity - - integers - - invariant - - js-date - - json - - json-codecs - - language-purescript - - lazy - - lcg - - lists - - maybe - - newtype - - node-buffer - - node-event-emitter - - node-fs - - node-path - - node-process - - node-streams - - nonempty - - now - - nullable - - numbers - - ordered-collections - - orders - - parallel - - parsing - - partial - - posix-types - - prelude - - profunctor - - profunctor-lenses - - quickcheck - - quickcheck-laws - - random - - record - - refs - - safe-coerce - - search-trie - - st - - string-parsers - - strings - - tailrec - - these - - transformers - - tuples - - type-equality - - typelevel-prelude - - unfoldable - - unicode - - unsafe-coerce - - variant - - versions - test: - dependencies: - - exceptions - - spec - - spec-node - build_plan: - - aff - - ansi - - argonaut-codecs - - argonaut-core - - arraybuffer-types - - arrays - - avar - - bifunctors - - catenable-lists - - console - - const - - contravariant - - control - - datetime - - distributive - - effect - - either - - enums - - exceptions - - exists - - exitcodes - - foldable-traversable - - foreign - - foreign-object - - fork - - free - - functions - - functors - - gen - - identity - - integers - - invariant - - js-date - - lazy - - lists - - maybe - - mmorph - - newtype - - node-buffer - - node-event-emitter - - node-fs - - node-path - - node-process - - node-streams - - nonempty - - now - - nullable - - numbers - - open-memoize - - optparse - - ordered-collections - - orders - - parallel - - partial - - pipes - - posix-types - - prelude - - profunctor - - psci-support - - record - - refs - - safe-coerce - - spec - - spec-node - - st - - strings - - tailrec - - transformers - - tuples - - type-equality - - typelevel-prelude - - unfoldable - - unsafe-coerce + dependencies: + - aff + - argonaut-core + - arrays + - codec-json + - console + - docs-search-common + - effect + - either + - foldable-traversable + - identity + - json + - json-codecs + - language-purescript + - lists + - maybe + - newtype + - node-buffer + - node-fs + - node-path + - node-process + - ordered-collections + - prelude + - profunctor + - search-trie + - string-parsers + - strings + - tuples + - unsafe-coerce + test_dependencies: + - exceptions + - spec + - spec-node + build_plan: + - aff + - aff-promise + - ansi + - argonaut-codecs + - argonaut-core + - arraybuffer-types + - arrays + - avar + - bifunctors + - catenable-lists + - codec + - codec-json + - console + - const + - contravariant + - control + - datetime + - distributive + - docs-search-common + - effect + - either + - enums + - exceptions + - exists + - exitcodes + - fixed-points + - foldable-traversable + - foreign + - foreign-object + - fork + - formatters + - free + - functions + - functors + - gen + - identity + - integers + - invariant + - js-date + - json + - json-codecs + - language-purescript + - lazy + - lcg + - lists + - maybe + - mmorph + - newtype + - node-buffer + - node-event-emitter + - node-fs + - node-path + - node-process + - node-streams + - nonempty + - now + - nullable + - numbers + - open-memoize + - optparse + - ordered-collections + - orders + - parallel + - parsing + - partial + - pipes + - posix-types + - prelude + - profunctor + - profunctor-lenses + - psci-support + - quickcheck + - quickcheck-laws + - random + - record + - refs + - safe-coerce + - search-trie + - spec + - spec-node + - st + - string-parsers + - strings + - tailrec + - these + - transformers + - tuples + - type-equality + - typelevel-prelude + - unfoldable + - unicode + - unsafe-coerce + - variant + - versions spago: path: ./ - core: - dependencies: - - aff - - aff-promise - - affjax - - affjax-node - - ansi - - argonaut-core - - arrays - - avar - - codec - - codec-json - - console - - control - - datetime - - docs-search-common - - docs-search-index - - dodo-printer - - effect - - either - - enums - - filterable - - foldable-traversable - - foreign-object - - formatters - - functions - - graphs - - http-methods - - integers - - json - - lists - - maybe - - newtype - - node-buffer - - node-child-process - - node-execa - - node-fs - - node-path - - node-process - - now - - nullable - - ordered-collections - - parallel - - partial - - posix-types - - prelude - - profunctor - - record - - refs - - registry-lib - - routing-duplex - - spago-core - - strings - - strings-extra - - transformers - - tuples - - unfoldable - - unicode - - unsafe-coerce - build_plan: - - aff - - aff-promise - - affjax - - affjax-node - - ansi - - argonaut-core - - arraybuffer-types - - arrays - - assert - - avar - - bifunctors - - catenable-lists - - codec - - codec-json - - console - - const - - contravariant - - control - - datetime - - distributive - - docs-search-common - - docs-search-index - - dodo-printer - - effect - - either - - enums - - exceptions - - exists - - filterable - - fixed-points - - foldable-traversable - - foreign - - foreign-object - - form-urlencoded - - formatters - - free - - functions - - functors - - gen - - graphs - - http-methods - - identity - - integers - - invariant - - js-date - - js-timers - - js-uri - - json - - json-codecs - - language-cst-parser - - language-purescript - - lazy - - lcg - - lists - - maybe - - media-types - - newtype - - node-buffer - - node-child-process - - node-event-emitter - - node-execa - - node-fs - - node-human-signals - - node-os - - node-path - - node-process - - node-streams - - nonempty - - now - - nullable - - numbers - - ordered-collections - - orders - - parallel - - parsing - - partial - - posix-types - - prelude - - profunctor - - profunctor-lenses - - quickcheck - - quickcheck-laws - - random - - record - - refs - - registry-lib - - routing-duplex - - safe-coerce - - search-trie - - spago-core - - st - - string-parsers - - strings - - strings-extra - - stringutils - - tailrec - - these - - transformers - - tuples - - type-equality - - typelevel-prelude - - unfoldable - - unicode - - unsafe-coerce - - unsafe-reference - - variant - - versions - - web-dom - - web-events - - web-file - - web-html - - web-storage - - web-xhr - test: - dependencies: - - exceptions - - identity - - quickcheck - - spec - - spec-node - build_plan: - - aff - - ansi - - argonaut-codecs - - argonaut-core - - arraybuffer-types - - arrays - - avar - - bifunctors - - catenable-lists - - console - - const - - contravariant - - control - - datetime - - distributive - - effect - - either - - enums - - exceptions - - exists - - exitcodes - - foldable-traversable - - foreign - - foreign-object - - fork - - free - - functions - - functors - - gen - - identity - - integers - - invariant - - js-date - - lazy - - lcg - - lists - - maybe - - mmorph - - newtype - - node-buffer - - node-event-emitter - - node-fs - - node-path - - node-process - - node-streams - - nonempty - - now - - nullable - - numbers - - open-memoize - - optparse - - ordered-collections - - orders - - parallel - - partial - - pipes - - posix-types - - prelude - - profunctor - - psci-support - - quickcheck - - random - - record - - refs - - safe-coerce - - spec - - spec-node - - st - - strings - - tailrec - - transformers - - tuples - - type-equality - - typelevel-prelude - - unfoldable - - unsafe-coerce + dependencies: + - aff + - aff-promise + - affjax + - affjax-node + - ansi + - argonaut-core + - arrays + - avar + - codec + - codec-json + - console + - control + - datetime + - docs-search-common + - docs-search-index + - dodo-printer + - effect + - either + - enums + - filterable + - foldable-traversable + - foreign-object + - formatters + - functions + - graphs + - http-methods + - integers + - json + - lists + - maybe + - newtype + - node-buffer + - node-child-process + - node-execa + - node-fs + - node-path + - node-process + - now + - nullable + - ordered-collections + - parallel + - partial + - posix-types + - prelude + - profunctor + - record + - refs + - registry-lib + - routing-duplex + - spago-core + - strings + - strings-extra + - transformers + - tuples + - unfoldable + - unicode + - unsafe-coerce + test_dependencies: + - exceptions + - identity + - quickcheck + - spec + - spec-node + build_plan: + - aff + - aff-promise + - affjax + - affjax-node + - ansi + - argonaut-codecs + - argonaut-core + - arraybuffer-types + - arrays + - assert + - avar + - bifunctors + - catenable-lists + - codec + - codec-json + - console + - const + - contravariant + - control + - datetime + - distributive + - docs-search-common + - docs-search-index + - dodo-printer + - effect + - either + - enums + - exceptions + - exists + - exitcodes + - filterable + - fixed-points + - foldable-traversable + - foreign + - foreign-object + - fork + - form-urlencoded + - formatters + - free + - functions + - functors + - gen + - graphs + - http-methods + - identity + - integers + - invariant + - js-date + - js-timers + - js-uri + - json + - json-codecs + - language-cst-parser + - language-purescript + - lazy + - lcg + - lists + - maybe + - media-types + - mmorph + - newtype + - node-buffer + - node-child-process + - node-event-emitter + - node-execa + - node-fs + - node-human-signals + - node-os + - node-path + - node-process + - node-streams + - nonempty + - now + - nullable + - numbers + - open-memoize + - optparse + - ordered-collections + - orders + - parallel + - parsing + - partial + - pipes + - posix-types + - prelude + - profunctor + - profunctor-lenses + - psci-support + - quickcheck + - quickcheck-laws + - random + - record + - refs + - registry-lib + - routing-duplex + - safe-coerce + - search-trie + - spago-core + - spec + - spec-node + - st + - string-parsers + - strings + - strings-extra + - stringutils + - tailrec + - these + - transformers + - tuples + - type-equality + - typelevel-prelude + - unfoldable + - unicode + - unsafe-coerce + - unsafe-reference + - variant + - versions + - web-dom + - web-events + - web-file + - web-html + - web-storage + - web-xhr spago-bin: path: bin - core: - dependencies: - - aff - - arrays - - avar - - codec-json - - control - - foldable-traversable - - lists - - maybe - - node-path - - node-process - - now - - optparse - - ordered-collections - - prelude - - record - - registry-lib - - spago - - spago-core - - strings - - transformers - - unsafe-coerce - build_plan: - - aff - - aff-promise - - affjax - - affjax-node - - ansi - - argonaut-core - - arraybuffer-types - - arrays - - assert - - avar - - bifunctors - - catenable-lists - - codec - - codec-json - - console - - const - - contravariant - - control - - datetime - - distributive - - docs-search-common - - docs-search-index - - dodo-printer - - effect - - either - - enums - - exceptions - - exists - - exitcodes - - filterable - - fixed-points - - foldable-traversable - - foreign - - foreign-object - - form-urlencoded - - formatters - - free - - functions - - functors - - gen - - graphs - - http-methods - - identity - - integers - - invariant - - js-date - - js-timers - - js-uri - - json - - json-codecs - - language-cst-parser - - language-purescript - - lazy - - lcg - - lists - - maybe - - media-types - - newtype - - node-buffer - - node-child-process - - node-event-emitter - - node-execa - - node-fs - - node-human-signals - - node-os - - node-path - - node-process - - node-streams - - nonempty - - now - - nullable - - numbers - - open-memoize - - optparse - - ordered-collections - - orders - - parallel - - parsing - - partial - - posix-types - - prelude - - profunctor - - profunctor-lenses - - psci-support - - quickcheck - - quickcheck-laws - - random - - record - - refs - - registry-lib - - routing-duplex - - safe-coerce - - search-trie - - spago - - spago-core - - st - - string-parsers - - strings - - strings-extra - - stringutils - - tailrec - - these - - transformers - - tuples - - type-equality - - typelevel-prelude - - unfoldable - - unicode - - unsafe-coerce - - unsafe-reference - - variant - - versions - - web-dom - - web-events - - web-file - - web-html - - web-storage - - web-xhr - test: - dependencies: [] - build_plan: [] + dependencies: + - aff + - arrays + - avar + - codec-json + - control + - foldable-traversable + - lists + - maybe + - node-path + - node-process + - now + - optparse + - ordered-collections + - prelude + - record + - registry-lib + - spago + - spago-core + - strings + - transformers + - unsafe-coerce + test_dependencies: [] + build_plan: + - aff + - aff-promise + - affjax + - affjax-node + - ansi + - argonaut-codecs + - argonaut-core + - arraybuffer-types + - arrays + - assert + - avar + - bifunctors + - catenable-lists + - codec + - codec-json + - console + - const + - contravariant + - control + - datetime + - distributive + - docs-search-common + - docs-search-index + - dodo-printer + - effect + - either + - enums + - exceptions + - exists + - exitcodes + - filterable + - fixed-points + - foldable-traversable + - foreign + - foreign-object + - fork + - form-urlencoded + - formatters + - free + - functions + - functors + - gen + - graphs + - http-methods + - identity + - integers + - invariant + - js-date + - js-timers + - js-uri + - json + - json-codecs + - language-cst-parser + - language-purescript + - lazy + - lcg + - lists + - maybe + - media-types + - mmorph + - newtype + - node-buffer + - node-child-process + - node-event-emitter + - node-execa + - node-fs + - node-human-signals + - node-os + - node-path + - node-process + - node-streams + - nonempty + - now + - nullable + - numbers + - open-memoize + - optparse + - ordered-collections + - orders + - parallel + - parsing + - partial + - pipes + - posix-types + - prelude + - profunctor + - profunctor-lenses + - psci-support + - quickcheck + - quickcheck-laws + - random + - record + - refs + - registry-lib + - routing-duplex + - safe-coerce + - search-trie + - spago + - spago-core + - spec + - spec-node + - st + - string-parsers + - strings + - strings-extra + - stringutils + - tailrec + - these + - transformers + - tuples + - type-equality + - typelevel-prelude + - unfoldable + - unicode + - unsafe-coerce + - unsafe-reference + - variant + - versions + - web-dom + - web-events + - web-file + - web-html + - web-storage + - web-xhr spago-core: path: core - core: - dependencies: - - aff - - arrays - - bifunctors - - codec - - codec-json - - console - - control - - datetime - - dodo-printer - - effect - - either - - exceptions - - filterable - - foldable-traversable - - functions - - identity - - integers - - json - - lists - - maybe - - newtype - - node-buffer - - node-fs - - node-path - - node-process - - now - - ordered-collections - - partial - - prelude - - profunctor - - refs - - registry-lib - - strings - - stringutils - - transformers - - tuples - build_plan: - - aff - - ansi - - arraybuffer-types - - arrays - - assert - - avar - - bifunctors - - catenable-lists - - codec - - codec-json - - console - - const - - contravariant - - control - - datetime - - distributive - - dodo-printer - - effect - - either - - enums - - exceptions - - exists - - filterable - - fixed-points - - foldable-traversable - - foreign - - foreign-object - - formatters - - free - - functions - - functors - - gen - - graphs - - identity - - integers - - invariant - - js-date - - js-uri - - json - - language-cst-parser - - lazy - - lcg - - lists - - maybe - - newtype - - node-buffer - - node-event-emitter - - node-fs - - node-path - - node-process - - node-streams - - nonempty - - now - - nullable - - numbers - - ordered-collections - - orders - - parallel - - parsing - - partial - - posix-types - - prelude - - profunctor - - profunctor-lenses - - quickcheck - - random - - record - - refs - - registry-lib - - routing-duplex - - safe-coerce - - st - - strings - - stringutils - - tailrec - - transformers - - tuples - - type-equality - - typelevel-prelude - - unfoldable - - unicode - - unsafe-coerce - - variant - test: - dependencies: [] - build_plan: [] + dependencies: + - aff + - arrays + - bifunctors + - codec + - codec-json + - console + - control + - datetime + - dodo-printer + - effect + - either + - exceptions + - filterable + - foldable-traversable + - functions + - identity + - integers + - json + - lists + - maybe + - newtype + - node-buffer + - node-fs + - node-path + - node-process + - now + - ordered-collections + - partial + - prelude + - profunctor + - refs + - registry-lib + - strings + - stringutils + - transformers + - tuples + test_dependencies: [] + build_plan: + - aff + - ansi + - arraybuffer-types + - arrays + - assert + - avar + - bifunctors + - catenable-lists + - codec + - codec-json + - console + - const + - contravariant + - control + - datetime + - distributive + - dodo-printer + - effect + - either + - enums + - exceptions + - exists + - filterable + - fixed-points + - foldable-traversable + - foreign + - foreign-object + - formatters + - free + - functions + - functors + - gen + - graphs + - identity + - integers + - invariant + - js-date + - js-uri + - json + - language-cst-parser + - lazy + - lcg + - lists + - maybe + - newtype + - node-buffer + - node-event-emitter + - node-fs + - node-path + - node-process + - node-streams + - nonempty + - now + - nullable + - numbers + - ordered-collections + - orders + - parallel + - parsing + - partial + - posix-types + - prelude + - profunctor + - profunctor-lenses + - quickcheck + - random + - record + - refs + - registry-lib + - routing-duplex + - safe-coerce + - st + - strings + - stringutils + - tailrec + - transformers + - tuples + - type-equality + - typelevel-prelude + - unfoldable + - unicode + - unsafe-coerce + - variant package_set: address: registry: 56.4.0 diff --git a/src/Spago/Config.purs b/src/Spago/Config.purs index 38bce11c0..29ae4e4ee 100644 --- a/src/Spago/Config.purs +++ b/src/Spago/Config.purs @@ -38,6 +38,7 @@ import Data.Enum as Enum import Data.Graph as Graph import Data.HTTP.Method as Method import Data.Int as Int +import Data.List (List(..)) import Data.Map as Map import Data.Nullable (Nullable) import Data.Nullable as Nullable @@ -164,6 +165,17 @@ type ReadWorkspaceOptions = , migrateConfig :: Boolean } +type PrelimWorkspace = + { backend :: Maybe Core.BackendConfig + , buildOpts :: Maybe + { censorLibraryWarnings :: Maybe Core.CensorBuildWarnings + , output :: Maybe String + , statVerbosity :: Maybe Core.StatVerbosity + } + , extraPackages :: Maybe (Map PackageName Core.ExtraPackage) + , packageSet :: Maybe Core.SetAddress + } + -- | Reads all the configurations in the tree and builds up the Map of local -- | packages to be integrated in the package set readWorkspace :: ∀ a. ReadWorkspaceOptions -> Spago (Registry.RegistryEnv a) Workspace @@ -180,6 +192,36 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do false, true -> logWarn $ "Your " <> path <> " is using an outdated format. Run Spago with the --migrate flag to update it to the latest version." _, false -> pure unit + logInfo "Gathering all the spago configs higher in the tree..." + let + higherPaths :: List FilePath + higherPaths = Array.toUnfoldable $ Paths.toGitSearchPath Paths.cwd + + checkForWorkspace :: forall b. FilePath + -> Spago (LogEnv b) (Maybe PrelimWorkspace) + checkForWorkspace config = do + result <- readConfig config + case result of + Left _ -> pure Nothing + Right { yaml: { workspace: Nothing } } -> pure Nothing + Right { yaml: { workspace: Just ws } } -> pure (Just ws) + + searchHigherPaths :: forall b. List FilePath -> Spago (LogEnv b) (Maybe PrelimWorkspace) + searchHigherPaths Nil = pure Nothing + searchHigherPaths (path : otherPaths) = do + mYaml :: Maybe String <- map Array.head $ liftAff $ Glob.gitignoringGlob path [ "./spago.yaml" ] + case mYaml of + Nothing -> searchHigherPaths otherPaths + Just foundSpagoYaml -> do + mWorkspace :: Maybe PrelimWorkspace <- checkForWorkspace foundSpagoYaml + case mWorkspace of + Nothing -> searchHigherPaths otherPaths + workspace -> pure workspace + + mHigherConfigPath <- searchHigherPaths higherPaths + for_ mHigherConfigPath $ \_ -> do + logDebug $ [ toDoc "Found workspace at higher path: " ] + -- First try to read the config in the root. It _has_ to contain a workspace -- configuration, or we fail early. { workspace, package: maybePackage, workspaceDoc } <- readConfig "spago.yaml" >>= case _ of @@ -199,10 +241,10 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do doMigrateConfig "spago.yaml" config pure { workspace, package, workspaceDoc: doc } - logDebug "Gathering all the spago configs in the tree..." - otherConfigPaths <- liftAff $ Glob.gitignoringGlob Paths.cwd [ "**/spago.yaml" ] - unless (Array.null otherConfigPaths) do - logDebug $ [ toDoc "Found packages at these paths:", Log.indent $ Log.lines (map toDoc otherConfigPaths) ] + logDebug "Gathering all the spago configs lower in the tree..." + otherLowerConfigPaths <- liftAff $ Glob.gitignoringGlob Paths.cwd [ "**/spago.yaml" ] + unless (Array.null otherLowerConfigPaths) do + logDebug $ [ toDoc "Found packages at these lower paths:", Log.indent $ Log.lines (map toDoc otherLowerConfigPaths) ] -- We read all of them in, and only read the package section, if any. let @@ -220,7 +262,7 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do Right config -> do Right { config, hasTests, configPath: path, packagePath: Path.dirname path } - { right: otherPackages, left: failedPackages } <- partitionMap identity <$> traverse readWorkspaceConfig otherConfigPaths + { right: otherPackages, left: failedPackages } <- partitionMap identity <$> traverse readWorkspaceConfig otherLowerConfigPaths unless (Array.null failedPackages) do logWarn $ [ toDoc "Failed to read some configs:" ] <> failedPackages diff --git a/src/Spago/Paths.purs b/src/Spago/Paths.purs index e2b3ccc8a..cdb4ba0a4 100644 --- a/src/Spago/Paths.purs +++ b/src/Spago/Paths.purs @@ -6,6 +6,8 @@ import Effect.Unsafe (unsafePerformEffect) import Node.Path (FilePath) import Node.Path as Path import Node.Process as Process +import Data.Array (cons, replicate, reverse) +import Data.String (joinWith) type NodePaths = { config :: FilePath @@ -44,6 +46,17 @@ toLocalCachePackagesPath rootDir = Path.concat [ toLocalCachePath rootDir, "p" ] toLocalCacheGitPath :: FilePath -> FilePath toLocalCacheGitPath rootDir = Path.concat [ toLocalCachePath rootDir, "g" ] +-- search maximum 4 levels up the tree to find the Git project, if it exists +toGitSearchPath :: FilePath -> Array FilePath +toGitSearchPath rootDir = reverse $ makeSearchPaths rootDir 2 where + makeSearchPath :: FilePath -> Int -> FilePath + makeSearchPath wd i = joinWith "" $ cons wd $ cons "/" $ replicate i "../" + + makeSearchPaths :: FilePath -> Int -> Array FilePath + makeSearchPaths wd 0 = pure wd + makeSearchPaths wd i | i > 0 = cons (makeSearchPath wd i) (makeSearchPaths wd (i - 1)) + makeSearchPaths _ _ = mempty + registryPath ∷ FilePath registryPath = Path.concat [ globalCachePath, "registry" ] diff --git a/test/Spago/Paths.purs b/test/Spago/Paths.purs new file mode 100644 index 000000000..fa4c5bf9f --- /dev/null +++ b/test/Spago/Paths.purs @@ -0,0 +1,21 @@ +module Test.Spago.Paths where + +import Test.Prelude + +import Test.Spec (Spec) +import Test.Spec as Spec +import Test.Spec.Assertions as Assert + +import Spago.Paths (toGitSearchPath) + +spec :: Spec Unit +spec = Spec.around withTempDir do + Spec.describe "paths" do + Spec.it "generate four paths to parent directories of working directory, plus working directory" \ _ -> do + toGitSearchPath "~/a/b/c/d/e" `Assert.shouldEqual` + [ "~/a/b/c/d/e" + , "~/a/b/c/d/e/../" + , "~/a/b/c/d/e/../../" + , "~/a/b/c/d/e/../../../" + , "~/a/b/c/d/e/../../../../" + ] From 4e3b19b1a05bacc381686cbf7c69fd7bca43c35c Mon Sep 17 00:00:00 2001 From: Peter Becich Date: Sun, 21 Jul 2024 00:04:42 -0700 Subject: [PATCH 2/8] successfully finds and uses workspace in parent directory --- src/Spago/Config.purs | 35 ++++++++++++++++++++++------------- src/Spago/Paths.purs | 4 ++-- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/Spago/Config.purs b/src/Spago/Config.purs index 29ae4e4ee..cf604d707 100644 --- a/src/Spago/Config.purs +++ b/src/Spago/Config.purs @@ -200,27 +200,30 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do checkForWorkspace :: forall b. FilePath -> Spago (LogEnv b) (Maybe PrelimWorkspace) checkForWorkspace config = do - result <- readConfig config + logInfo $ "Checking for workspace: " <> config + result <- map (map (\y -> y.yaml)) $ readConfig config case result of Left _ -> pure Nothing - Right { yaml: { workspace: Nothing } } -> pure Nothing - Right { yaml: { workspace: Just ws } } -> pure (Just ws) + Right { workspace: Nothing } -> pure Nothing + Right { workspace: Just ws } -> pure (Just ws) - searchHigherPaths :: forall b. List FilePath -> Spago (LogEnv b) (Maybe PrelimWorkspace) + searchHigherPaths :: forall b. List FilePath -> Spago (LogEnv b) (Maybe (Tuple FilePath PrelimWorkspace)) searchHigherPaths Nil = pure Nothing searchHigherPaths (path : otherPaths) = do - mYaml :: Maybe String <- map Array.head $ liftAff $ Glob.gitignoringGlob path [ "./spago.yaml" ] + -- TODO stop searching if .git is found, this is the root + logInfo $ "Searching " <> path + mYaml :: Maybe String <- map (map (\yml -> path <> yml)) $ map Array.head $ liftAff $ Glob.gitignoringGlob path [ "./spago.yaml" ] case mYaml of Nothing -> searchHigherPaths otherPaths Just foundSpagoYaml -> do mWorkspace :: Maybe PrelimWorkspace <- checkForWorkspace foundSpagoYaml case mWorkspace of Nothing -> searchHigherPaths otherPaths - workspace -> pure workspace + Just ws -> pure (pure (Tuple foundSpagoYaml ws)) - mHigherConfigPath <- searchHigherPaths higherPaths - for_ mHigherConfigPath $ \_ -> do - logDebug $ [ toDoc "Found workspace at higher path: " ] + mHigherWorkspace <- searchHigherPaths higherPaths + for_ mHigherWorkspace $ \(Tuple filepath _) -> + logInfo $ "Found workspace definition in " <> filepath -- First try to read the config in the root. It _has_ to contain a workspace -- configuration, or we fail early. @@ -233,10 +236,16 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do , Log.break , toDoc "The configuration file help can be found here https://github.com/purescript/spago#the-configuration-file" ] - Right { yaml: { workspace: Nothing } } -> die - [ "Your spago.yaml doesn't contain a workspace section." - , "See the relevant documentation here: https://github.com/purescript/spago#the-workspace" - ] + Right config@{ yaml: { workspace: Nothing, package }, doc } -> case mHigherWorkspace of + Nothing -> + die + [ "No workspace definition found in this spago.yaml or any spago.yaml in parent directory." + , "See the relevant documentation here: https://github.com/purescript/spago#the-workspace" + ] + Just (Tuple _ higherWorkspace) -> do + -- TODO migrate workspace at higher directory? + doMigrateConfig "spago.yaml" config + pure { workspace: higherWorkspace, package, workspaceDoc: doc } Right config@{ yaml: { workspace: Just workspace, package }, doc } -> do doMigrateConfig "spago.yaml" config pure { workspace, package, workspaceDoc: doc } diff --git a/src/Spago/Paths.purs b/src/Spago/Paths.purs index cdb4ba0a4..d1e621ef4 100644 --- a/src/Spago/Paths.purs +++ b/src/Spago/Paths.purs @@ -48,12 +48,12 @@ toLocalCacheGitPath rootDir = Path.concat [ toLocalCachePath rootDir, "g" ] -- search maximum 4 levels up the tree to find the Git project, if it exists toGitSearchPath :: FilePath -> Array FilePath -toGitSearchPath rootDir = reverse $ makeSearchPaths rootDir 2 where +toGitSearchPath rootDir = reverse $ makeSearchPaths rootDir 4 where makeSearchPath :: FilePath -> Int -> FilePath makeSearchPath wd i = joinWith "" $ cons wd $ cons "/" $ replicate i "../" makeSearchPaths :: FilePath -> Int -> Array FilePath - makeSearchPaths wd 0 = pure wd + makeSearchPaths wd 0 = pure (wd <> "/") makeSearchPaths wd i | i > 0 = cons (makeSearchPath wd i) (makeSearchPaths wd (i - 1)) makeSearchPaths _ _ = mempty From 5857155d7e7f636b6e9ff6044886d1e80a6ae534 Mon Sep 17 00:00:00 2001 From: Peter Becich Date: Sun, 21 Jul 2024 00:13:39 -0700 Subject: [PATCH 3/8] look for workspace in parent directories only after not found in working directory --- src/Spago/Config.purs | 55 ++++++++++++++++++++++++++----------------- src/Spago/Paths.purs | 2 +- test/Spago/Paths.purs | 5 ++-- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/Spago/Config.purs b/src/Spago/Config.purs index cf604d707..a04eafbd7 100644 --- a/src/Spago/Config.purs +++ b/src/Spago/Config.purs @@ -192,7 +192,6 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do false, true -> logWarn $ "Your " <> path <> " is using an outdated format. Run Spago with the --migrate flag to update it to the latest version." _, false -> pure unit - logInfo "Gathering all the spago configs higher in the tree..." let higherPaths :: List FilePath higherPaths = Array.toUnfoldable $ Paths.toGitSearchPath Paths.cwd @@ -210,23 +209,31 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do searchHigherPaths :: forall b. List FilePath -> Spago (LogEnv b) (Maybe (Tuple FilePath PrelimWorkspace)) searchHigherPaths Nil = pure Nothing searchHigherPaths (path : otherPaths) = do - -- TODO stop searching if .git is found, this is the root - logInfo $ "Searching " <> path + mGitRoot :: Maybe String <- map Array.head $ liftAff $ Glob.gitignoringGlob path [ "./.git" ] mYaml :: Maybe String <- map (map (\yml -> path <> yml)) $ map Array.head $ liftAff $ Glob.gitignoringGlob path [ "./spago.yaml" ] case mYaml of - Nothing -> searchHigherPaths otherPaths + Nothing -> case mGitRoot of + Nothing -> searchHigherPaths otherPaths + Just gitRoot -> do + -- directory containing .git assumed to be the root of the project; + -- do not search up the file tree further than this + logInfo $ "No Spago workspace found in any directory up to root of project: " <> gitRoot + pure Nothing Just foundSpagoYaml -> do mWorkspace :: Maybe PrelimWorkspace <- checkForWorkspace foundSpagoYaml case mWorkspace of - Nothing -> searchHigherPaths otherPaths + Nothing -> case mGitRoot of + Nothing -> searchHigherPaths otherPaths + Just gitRoot -> do + -- directory containing .git assumed to be the root of the project; + -- do not search up the file tree further than this + logInfo $ "No Spago workspace found in any directory up to root of project: " <> gitRoot + pure Nothing Just ws -> pure (pure (Tuple foundSpagoYaml ws)) - mHigherWorkspace <- searchHigherPaths higherPaths - for_ mHigherWorkspace $ \(Tuple filepath _) -> - logInfo $ "Found workspace definition in " <> filepath - - -- First try to read the config in the root. It _has_ to contain a workspace - -- configuration, or we fail early. + -- First try to read the config in the root. + -- Else, look for a workspace in parent directories. + -- Else fail. { workspace, package: maybePackage, workspaceDoc } <- readConfig "spago.yaml" >>= case _ of Left errLines -> die @@ -236,16 +243,22 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do , Log.break , toDoc "The configuration file help can be found here https://github.com/purescript/spago#the-configuration-file" ] - Right config@{ yaml: { workspace: Nothing, package }, doc } -> case mHigherWorkspace of - Nothing -> - die - [ "No workspace definition found in this spago.yaml or any spago.yaml in parent directory." - , "See the relevant documentation here: https://github.com/purescript/spago#the-workspace" - ] - Just (Tuple _ higherWorkspace) -> do - -- TODO migrate workspace at higher directory? - doMigrateConfig "spago.yaml" config - pure { workspace: higherWorkspace, package, workspaceDoc: doc } + Right config@{ yaml: { workspace: Nothing, package }, doc } -> do + logInfo "Looking for Spago workspace configuration higher in the filesystem, up to project root (.git)..." + mHigherWorkspace <- searchHigherPaths higherPaths + case mHigherWorkspace of + Nothing -> + die + [ "No workspace definition found in this directory" + , "or in any directory up to root of project." + , "Root determined by '.git' file." + , "See the relevant documentation here: https://github.com/purescript/spago#the-workspace" + ] + Just (Tuple higherWorkspacePath higherWorkspace) -> do + logInfo $ "Found workspace definition in " <> higherWorkspacePath + -- TODO migrate workspace at higher directory? + doMigrateConfig "spago.yaml" config + pure { workspace: higherWorkspace, package, workspaceDoc: doc } Right config@{ yaml: { workspace: Just workspace, package }, doc } -> do doMigrateConfig "spago.yaml" config pure { workspace, package, workspaceDoc: doc } diff --git a/src/Spago/Paths.purs b/src/Spago/Paths.purs index d1e621ef4..442cbd84e 100644 --- a/src/Spago/Paths.purs +++ b/src/Spago/Paths.purs @@ -53,7 +53,7 @@ toGitSearchPath rootDir = reverse $ makeSearchPaths rootDir 4 where makeSearchPath wd i = joinWith "" $ cons wd $ cons "/" $ replicate i "../" makeSearchPaths :: FilePath -> Int -> Array FilePath - makeSearchPaths wd 0 = pure (wd <> "/") + makeSearchPaths wd 0 = mempty makeSearchPaths wd i | i > 0 = cons (makeSearchPath wd i) (makeSearchPaths wd (i - 1)) makeSearchPaths _ _ = mempty diff --git a/test/Spago/Paths.purs b/test/Spago/Paths.purs index fa4c5bf9f..b31d820a1 100644 --- a/test/Spago/Paths.purs +++ b/test/Spago/Paths.purs @@ -11,10 +11,9 @@ import Spago.Paths (toGitSearchPath) spec :: Spec Unit spec = Spec.around withTempDir do Spec.describe "paths" do - Spec.it "generate four paths to parent directories of working directory, plus working directory" \ _ -> do + Spec.it "generate four paths to parent directories of working directory" \ _ -> do toGitSearchPath "~/a/b/c/d/e" `Assert.shouldEqual` - [ "~/a/b/c/d/e" - , "~/a/b/c/d/e/../" + [ "~/a/b/c/d/e/../" , "~/a/b/c/d/e/../../" , "~/a/b/c/d/e/../../../" , "~/a/b/c/d/e/../../../../" From 79210d1bf29256e2e63d37398ff133478bff1551 Mon Sep 17 00:00:00 2001 From: Peter Becich Date: Sun, 21 Jul 2024 00:45:10 -0700 Subject: [PATCH 4/8] fix warning --- src/Spago/Paths.purs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Spago/Paths.purs b/src/Spago/Paths.purs index 442cbd84e..1eab31d0c 100644 --- a/src/Spago/Paths.purs +++ b/src/Spago/Paths.purs @@ -53,7 +53,7 @@ toGitSearchPath rootDir = reverse $ makeSearchPaths rootDir 4 where makeSearchPath wd i = joinWith "" $ cons wd $ cons "/" $ replicate i "../" makeSearchPaths :: FilePath -> Int -> Array FilePath - makeSearchPaths wd 0 = mempty + makeSearchPaths _ 0 = mempty makeSearchPaths wd i | i > 0 = cons (makeSearchPath wd i) (makeSearchPaths wd (i - 1)) makeSearchPaths _ _ = mempty From 66bf114d8526e805cef8e6e454cd03cb95cc2247 Mon Sep 17 00:00:00 2001 From: Peter Becich Date: Sun, 21 Jul 2024 00:49:20 -0700 Subject: [PATCH 5/8] clarify comment --- src/Spago/Paths.purs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Spago/Paths.purs b/src/Spago/Paths.purs index 1eab31d0c..aaedb378d 100644 --- a/src/Spago/Paths.purs +++ b/src/Spago/Paths.purs @@ -46,7 +46,7 @@ toLocalCachePackagesPath rootDir = Path.concat [ toLocalCachePath rootDir, "p" ] toLocalCacheGitPath :: FilePath -> FilePath toLocalCacheGitPath rootDir = Path.concat [ toLocalCachePath rootDir, "g" ] --- search maximum 4 levels up the tree to find the Git project, if it exists +-- search maximum 4 levels up the tree to find all other `spago.yaml`, which may contain workspace definition toGitSearchPath :: FilePath -> Array FilePath toGitSearchPath rootDir = reverse $ makeSearchPaths rootDir 4 where makeSearchPath :: FilePath -> Int -> FilePath From f8160d38610058cd4153b5341def23f9ce6f21bc Mon Sep 17 00:00:00 2001 From: Peter Becich Date: Sun, 25 Aug 2024 17:03:22 -0700 Subject: [PATCH 6/8] filesystem search stops at `.git` successfully --- src/Spago/Config.purs | 62 ++++++++++++++++++++++++++----------------- src/Spago/Glob.purs | 6 ++++- src/Spago/Paths.purs | 4 ++- 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/Spago/Config.purs b/src/Spago/Config.purs index a04eafbd7..17e0bddc6 100644 --- a/src/Spago/Config.purs +++ b/src/Spago/Config.purs @@ -180,7 +180,7 @@ type PrelimWorkspace = -- | packages to be integrated in the package set readWorkspace :: ∀ a. ReadWorkspaceOptions -> Spago (Registry.RegistryEnv a) Workspace readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do - logInfo "Reading Spago workspace configuration..." + logInfo "Reading spago.yaml..." let doMigrateConfig :: FilePath -> _ -> Spago (Registry.RegistryEnv _) Unit @@ -199,7 +199,7 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do checkForWorkspace :: forall b. FilePath -> Spago (LogEnv b) (Maybe PrelimWorkspace) checkForWorkspace config = do - logInfo $ "Checking for workspace: " <> config + logDebug $ "Checking for workspace: " <> config result <- map (map (\y -> y.yaml)) $ readConfig config case result of Left _ -> pure Nothing @@ -209,27 +209,37 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do searchHigherPaths :: forall b. List FilePath -> Spago (LogEnv b) (Maybe (Tuple FilePath PrelimWorkspace)) searchHigherPaths Nil = pure Nothing searchHigherPaths (path : otherPaths) = do - mGitRoot :: Maybe String <- map Array.head $ liftAff $ Glob.gitignoringGlob path [ "./.git" ] - mYaml :: Maybe String <- map (map (\yml -> path <> yml)) $ map Array.head $ liftAff $ Glob.gitignoringGlob path [ "./spago.yaml" ] - case mYaml of - Nothing -> case mGitRoot of - Nothing -> searchHigherPaths otherPaths - Just gitRoot -> do - -- directory containing .git assumed to be the root of the project; - -- do not search up the file tree further than this - logInfo $ "No Spago workspace found in any directory up to root of project: " <> gitRoot - pure Nothing - Just foundSpagoYaml -> do - mWorkspace :: Maybe PrelimWorkspace <- checkForWorkspace foundSpagoYaml + mGitRoot :: Maybe String <- map Array.head $ liftAff $ Glob.findGitGlob path + case mGitRoot of + Nothing -> do + logDebug "No project root (.git) found at: " + logDebug path + Just gitRoot -> do + logInfo "Project root (.git) found at: " + logInfo $ path <> gitRoot + mSpagoYaml :: Maybe String <- map (map (\yml -> path <> yml)) $ map Array.head $ liftAff $ Glob.gitignoringGlob path [ "./spago.yaml" ] + + case Tuple mSpagoYaml mGitRoot of + Tuple Nothing Nothing -> searchHigherPaths otherPaths + Tuple Nothing (Just gitRoot) -> do + -- directory containing .git assumed to be the root of the project; + -- do not search up the file tree further than this + logInfo $ "No Spago workspace found in any directory up to project root: " <> path <> gitRoot + pure Nothing + Tuple (Just spagoYaml) (Just gitRoot) -> do + mWorkspace :: Maybe PrelimWorkspace <- checkForWorkspace spagoYaml case mWorkspace of - Nothing -> case mGitRoot of - Nothing -> searchHigherPaths otherPaths - Just gitRoot -> do - -- directory containing .git assumed to be the root of the project; - -- do not search up the file tree further than this - logInfo $ "No Spago workspace found in any directory up to root of project: " <> gitRoot - pure Nothing - Just ws -> pure (pure (Tuple foundSpagoYaml ws)) + Nothing -> do + -- directory containing .git assumed to be the root of the project; + -- do not search up the file tree further than this + logInfo $ "No Spago workspace found in any directory up to project root: " <> path <> gitRoot + pure Nothing + Just ws -> pure (pure (Tuple spagoYaml ws)) + Tuple (Just spagoYaml) Nothing -> do + mWorkspace :: Maybe PrelimWorkspace <- checkForWorkspace spagoYaml + case mWorkspace of + Nothing -> searchHigherPaths otherPaths + Just ws -> pure (pure (Tuple spagoYaml ws)) -- First try to read the config in the root. -- Else, look for a workspace in parent directories. @@ -244,7 +254,8 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do , toDoc "The configuration file help can be found here https://github.com/purescript/spago#the-configuration-file" ] Right config@{ yaml: { workspace: Nothing, package }, doc } -> do - logInfo "Looking for Spago workspace configuration higher in the filesystem, up to project root (.git)..." + logInfo "Looking for Spago workspace configuration higher in the filesystem." + logInfo $ "Search limited to " <> show Paths.gitSearchDepth <> " levels, or project root (.git)..." mHigherWorkspace <- searchHigherPaths higherPaths case mHigherWorkspace of Nothing -> @@ -255,7 +266,8 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do , "See the relevant documentation here: https://github.com/purescript/spago#the-workspace" ] Just (Tuple higherWorkspacePath higherWorkspace) -> do - logInfo $ "Found workspace definition in " <> higherWorkspacePath + logInfo "Found workspace definition in: " + logInfo higherWorkspacePath -- TODO migrate workspace at higher directory? doMigrateConfig "spago.yaml" config pure { workspace: higherWorkspace, package, workspaceDoc: doc } @@ -263,7 +275,7 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do doMigrateConfig "spago.yaml" config pure { workspace, package, workspaceDoc: doc } - logDebug "Gathering all the spago configs lower in the tree..." + logDebug "Gathering all the spago configs lower in the filesystem..." otherLowerConfigPaths <- liftAff $ Glob.gitignoringGlob Paths.cwd [ "**/spago.yaml" ] unless (Array.null otherLowerConfigPaths) do logDebug $ [ toDoc "Found packages at these lower paths:", Log.indent $ Log.lines (map toDoc otherLowerConfigPaths) ] diff --git a/src/Spago/Glob.purs b/src/Spago/Glob.purs index 29838fcea..3cdd2e3f7 100644 --- a/src/Spago/Glob.purs +++ b/src/Spago/Glob.purs @@ -3,7 +3,7 @@ -- | All of this code (and the FFI file) is a series of attempts to make globbing -- | reasonably performant while still supporting all of our usecases, like ignoring -- | files based on `.gitignore` files. -module Spago.Glob (gitignoringGlob) where +module Spago.Glob (gitignoringGlob, findGitGlob) where import Spago.Prelude @@ -207,3 +207,7 @@ fsWalk cwd ignorePatterns includePatterns = Aff.makeAff \cb -> do gitignoringGlob :: String -> Array String -> Aff (Array String) gitignoringGlob dir patterns = map (withForwardSlashes <<< Path.relative dir <<< _.path) <$> fsWalk dir [ ".git" ] patterns + +findGitGlob :: String -> Aff (Array String) +findGitGlob dir = map (withForwardSlashes <<< Path.relative dir <<< _.path) + <$> fsWalk dir mempty [ "./.git" ] diff --git a/src/Spago/Paths.purs b/src/Spago/Paths.purs index aaedb378d..a548d3022 100644 --- a/src/Spago/Paths.purs +++ b/src/Spago/Paths.purs @@ -47,8 +47,10 @@ toLocalCacheGitPath :: FilePath -> FilePath toLocalCacheGitPath rootDir = Path.concat [ toLocalCachePath rootDir, "g" ] -- search maximum 4 levels up the tree to find all other `spago.yaml`, which may contain workspace definition +gitSearchDepth :: Int +gitSearchDepth = 4 toGitSearchPath :: FilePath -> Array FilePath -toGitSearchPath rootDir = reverse $ makeSearchPaths rootDir 4 where +toGitSearchPath rootDir = reverse $ makeSearchPaths rootDir gitSearchDepth where makeSearchPath :: FilePath -> Int -> FilePath makeSearchPath wd i = joinWith "" $ cons wd $ cons "/" $ replicate i "../" From 70b22821e76ecbb71d45e2503000013456a0b79e Mon Sep 17 00:00:00 2001 From: Peter Becich Date: Sat, 31 Aug 2024 14:00:58 -0700 Subject: [PATCH 7/8] Spago.Paths.chdir --- src/Spago/Paths.purs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Spago/Paths.purs b/src/Spago/Paths.purs index a548d3022..aa6abc06b 100644 --- a/src/Spago/Paths.purs +++ b/src/Spago/Paths.purs @@ -2,12 +2,13 @@ module Spago.Paths where import Prelude +import Data.Array (cons, replicate, reverse) +import Data.String (joinWith) +import Effect.Class (class MonadEffect, liftEffect) import Effect.Unsafe (unsafePerformEffect) import Node.Path (FilePath) import Node.Path as Path import Node.Process as Process -import Data.Array (cons, replicate, reverse) -import Data.String (joinWith) type NodePaths = { config :: FilePath @@ -22,6 +23,9 @@ foreign import paths :: NodePaths cwd :: FilePath cwd = unsafePerformEffect (Process.cwd) +chdir :: forall m. MonadEffect m => FilePath -> m Unit +chdir dir = liftEffect $ Process.chdir dir + mkRelative :: FilePath -> FilePath mkRelative = Path.relative cwd From 232b417518bb7fdfff5069928ba4b520a8557d32 Mon Sep 17 00:00:00 2001 From: Peter Becich Date: Sat, 31 Aug 2024 14:09:01 -0700 Subject: [PATCH 8/8] find root spago.yaml filepath, not file --- src/Spago/Config.purs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Spago/Config.purs b/src/Spago/Config.purs index 17e0bddc6..bdd16ae03 100644 --- a/src/Spago/Config.purs +++ b/src/Spago/Config.purs @@ -179,6 +179,7 @@ type PrelimWorkspace = -- | Reads all the configurations in the tree and builds up the Map of local -- | packages to be integrated in the package set readWorkspace :: ∀ a. ReadWorkspaceOptions -> Spago (Registry.RegistryEnv a) Workspace +-- readWorkspace readWorkspaceOptions@{ maybeSelectedPackage, pureBuild, migrateConfig } = do readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do logInfo "Reading spago.yaml..." @@ -234,12 +235,16 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do -- do not search up the file tree further than this logInfo $ "No Spago workspace found in any directory up to project root: " <> path <> gitRoot pure Nothing - Just ws -> pure (pure (Tuple spagoYaml ws)) + Just ws -> do + logInfo spagoYaml + pure (map (\p -> (Tuple p ws)) (String.stripSuffix (Pattern "spago.yaml") spagoYaml)) Tuple (Just spagoYaml) Nothing -> do mWorkspace :: Maybe PrelimWorkspace <- checkForWorkspace spagoYaml case mWorkspace of Nothing -> searchHigherPaths otherPaths - Just ws -> pure (pure (Tuple spagoYaml ws)) + Just ws -> do + logInfo spagoYaml + pure (map (\p -> (Tuple p ws)) (String.stripSuffix (Pattern "spago.yaml") spagoYaml)) -- First try to read the config in the root. -- Else, look for a workspace in parent directories.