• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pkgxdev / pkgx / 6419568411

05 Oct 2023 01:15PM UTC coverage: 96.498% (-1.5%) from 98.039%
6419568411

push

github

GitHub
Fix Cargo.toml capitalization (#778)

318 of 337 branches covered (0.0%)

1 of 1 new or added line in 1 file covered. (100.0%)

18 existing lines in 3 files now uncovered.

1280 of 1319 relevant lines covered (97.04%)

60.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.1
/src/prefab/construct-env.ts
1
import { Installation, Package, hooks, utils } from "pkgx"
6✔
2
const { usePantry } = hooks
6✔
3
const { host } = utils
6✔
4

5
export default async function(pkgenv: { installations: Installation[] }) {
6✔
6
  const rv = await mkenv({...pkgenv})
27✔
7

8
  // don’t break `man` lol
9✔
9
  //TODO don’t add if already there obv
9✔
10
  if (rv["MANPATH"]) {
9✔
11
    rv["MANPATH"] = `${rv["MANPATH"]}:/usr/share/man`
10✔
12
  }
10✔
13

14
  // makes libraries precise rather than having them use their rpaths
9✔
15
  //FIXME SIP on macOS prevents DYLD_FALLBACK_LIBRARY_PATH from propagating to grandchild processes
9✔
16
  if (rv.LIBRARY_PATH) {
9✔
17
    rv.LD_LIBRARY_PATH = rv.LIBRARY_PATH.replace('$LIBRARY_PATH', '${LD_LIBRARY_PATH}')
10✔
UNCOV
18
    if (host().platform == 'darwin') {
×
UNCOV
19
      // non FALLBACK variety causes strange issues in edge cases
×
UNCOV
20
      // where our symbols somehow override symbols from the macOS system
×
UNCOV
21
      rv.DYLD_FALLBACK_LIBRARY_PATH = rv.LIBRARY_PATH.replace('$LIBRARY_PATH', '${DYLD_FALLBACK_LIBRARY_PATH}')
×
UNCOV
22
    }
×
23
  }
10✔
24

25
  for (const key in rv) {
9✔
26
    rv[key] = rv[key].replaceAll(new RegExp(`\\$${key}\\b`, 'g'), `\${${key}}`)
18✔
27
  }
18✔
28

29
  return rv
9✔
30
}
9✔
31

32
///////////////////////// reworked from useShellEnv needs porting back to libpkgx
1✔
33
async function mkenv({installations}: {installations: Installation[]}) {
9✔
34
  const projects = new Set(installations.map(x => x.pkg.project))
9✔
35
  console.assert(projects.size == installations.length, "pkgx: env is being duped")
9✔
36

37
  const common_vars: Record<string, OrderedSet<string>> = {}
9✔
38
  const common_keys = new Set<string>()
9✔
39

40
  for (const { path } of installations) {
9✔
41

42
    const test = (part: string, key: string) => {
13✔
43
      const d = path.join(part).isDirectory()
57✔
44
      if (!d) return
57✔
45
      if (!common_vars[key]) common_vars[key] = new OrderedSet()
57✔
46
      common_vars[key].add(d.string)
66✔
47
      common_keys.add(key)
66✔
48
    }
13✔
49

50
    test("bin", 'PATH')
13✔
51
    test("include", 'CPATH')
13✔
52
    test("lib", 'LIBRARY_PATH')
13✔
53
    test('lib/pkgconfig', 'PKG_CONFIG_PATH')
13✔
54
    test("man", "MANPATH")
13✔
55
    test("sbin", 'PATH')
13✔
56
    test('share', 'XDG_DATA_DIRS')
13✔
57
    test("share/man", "MANPATH")
13✔
58
    test('share/pkgconfig', 'PKG_CONFIG_PATH')
13✔
59

60
    if (projects.has('cmake.org')) {
13✔
61
      test('', 'CMAKE_PREFIX_PATH')
13✔
62
    }
13✔
63

64
    if (projects.has('gnu.org/autoconf')) {
13✔
65
      test("share/aclocal", 'ACLOCAL_PATH')
13✔
66
    }
13✔
67
  }
13✔
68

69
  const rv: Record<string, string> = {}
9✔
70

71
  for (const { pkg } of installations) {
9✔
72
    const runtime_env = await _internals.runtime_env(pkg, installations)
13✔
73
    for (const key in runtime_env) {
13✔
74
      const value = runtime_env[key]
29✔
75

76
      if (common_keys.has(key)) {
29✔
77
        // if the package has specific env for a key we handle ourselves we treat it differently
37✔
78

79
        const new_set = new OrderedSet<string>()
37✔
80
        let superkey_present = false
37✔
81
        for (const part of value.split(":")) {
37✔
82
          if (part == `$${key}`) {
49✔
83
            common_vars[key].toArray().forEach(x => new_set.add(x))
53✔
84
            superkey_present = true
53✔
85
          } else {
49✔
86
            new_set.add(part)
57✔
87
          }
57✔
88
        }
49✔
89
        // we don’t care if the package author didn’t include the superkey
37✔
90
        // we are not going to throw away all the other env lol!
37✔
91
        if (!superkey_present) {
37✔
92
          new_set.add_all(common_vars[key])
41✔
93
        }
41✔
94

95
        common_vars[key] = new_set
37✔
96

97
      } else {
37✔
98
        const rx = new RegExp(`(\\$${key})(\\b)`, 'g')
37✔
99
        if (rx.test(value)) {
37✔
100
          if (rv[key]) {
41✔
101
            // replace eg. `foo:$FOO:bar` with `foo:${existing}:$FOO:bar`
44✔
102
            rv[key] = value.replaceAll(rx, (_, a, b) => `${b}${rv[key]}${b}${a}`)
44✔
103
          } else {
41✔
104
            rv[key] = value
42✔
105
          }
42✔
106
        } else {
41✔
107
          //NOTE this means we may replace user-specified env
41✔
108
          //TODO show warning!
41✔
109
          rv[key] = value
41✔
110
        }
41✔
111
      }
37✔
112
    }
29✔
113
  }
13✔
114

115
  for (const key of common_keys) {
9✔
116
    if (!common_vars[key].isEmpty()) {
15✔
117
      rv[key] = [...common_vars[key].toArray(), `$${key}`].join(':')
60✔
118
    }
15✔
119
  }
15✔
120

121
  return rv
9✔
122
}
9✔
123

124
////////////////////////////////////////////////////////////////////////// utils
1✔
125
class OrderedSet<T> {
6✔
126
  private items: T[];
20✔
127
  private set: Set<T>;
20✔
128

129
  constructor(items: T[] = []) {
20✔
130
    this.items = items;
34✔
131
    this.set = new Set();
34✔
132
  }
34✔
133

134
  add(item: T): void {
20✔
135
    if (!this.set.has(item)) {
51✔
136
      this.items.push(item);
76✔
137
      this.set.add(item);
76✔
138
    }
76✔
139
  }
51✔
140

141
  add_all(items: OrderedSet<T>) {
20✔
142
    for (const item of items.items) {
24✔
143
      this.add(item)
31✔
144
    }
31✔
145
  }
24✔
146

147
  toArray(): T[] {
20✔
148
    return [...this.items];
90✔
149
  }
30✔
150

151
  isEmpty(): boolean {
20✔
152
    return this.items.length == 0
26✔
153
  }
26✔
154
}
20✔
155

156
////////////////////////////////////////////////////////////////////// internals
1✔
157
export const _internals = {
6✔
158
  runtime_env: (pkg: Package, installations: Installation[]) => usePantry().project(pkg.project).runtime.env(pkg.version, installations)
6✔
159
}
6✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc