mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-04 15:25:41 +08:00
Add deps-map component and related command
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -53,6 +53,7 @@ packlib_files.txt
|
||||
/docs/.vitepress/dist/
|
||||
/docs/.vitepress/cache/
|
||||
/docs/.vitepress/ext-data.json
|
||||
/docs/.vitepress/deps-data.json
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
|
||||
|
||||
589
docs/.vitepress/components/DepsMap.vue
Normal file
589
docs/.vitepress/components/DepsMap.vue
Normal file
@@ -0,0 +1,589 @@
|
||||
<template>
|
||||
<div class="deps-map">
|
||||
<!-- Warning if data missing -->
|
||||
<div v-if="missing" class="warning custom-block" style="margin-bottom: 16px">
|
||||
<p class="custom-block-title">WARNING</p>
|
||||
<p>Dependency data not generated yet. Run <code>bin/spc dev:gen-deps-data</code> to generate it.</p>
|
||||
</div>
|
||||
|
||||
<template v-else>
|
||||
<!-- Toolbar -->
|
||||
<div class="deps-toolbar">
|
||||
<input
|
||||
class="deps-search"
|
||||
v-model="searchText"
|
||||
:placeholder="i18n.searchPlaceholder"
|
||||
@input="selectedPkg = null"
|
||||
/>
|
||||
<div class="deps-filters">
|
||||
<div class="filter-group">
|
||||
<button
|
||||
v-for="t in typeOptions"
|
||||
:key="t.value"
|
||||
:class="['filter-btn', { active: selectedType === t.value }]"
|
||||
@click="selectedType = t.value; selectedPkg = null"
|
||||
>{{ t.label }}</button>
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<button
|
||||
v-for="p in platformOptions"
|
||||
:key="p.value"
|
||||
:class="['filter-btn', { active: selectedPlatform === p.value }]"
|
||||
@click="selectedPlatform = p.value"
|
||||
>{{ p.label }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="deps-layout">
|
||||
<!-- Package list -->
|
||||
<div class="deps-list">
|
||||
<div v-if="filteredPackages.length === 0" class="no-results">{{ i18n.noResults }}</div>
|
||||
<div
|
||||
v-for="pkg in filteredPackages"
|
||||
:key="pkg.name"
|
||||
:class="['pkg-item', { selected: selectedPkg === pkg.name }]"
|
||||
@click="selectPkg(pkg.name)"
|
||||
>
|
||||
<span class="pkg-name">{{ pkg.name }}</span>
|
||||
<span :class="['pkg-badge', pkg.type === 'php-extension' ? 'badge-ext' : 'badge-lib']">
|
||||
{{ typeLabel(pkg.type) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Detail panel -->
|
||||
<div class="deps-detail" v-if="selectedPkg && selectedPkgData">
|
||||
<h3 class="detail-title">{{ selectedPkg }}</h3>
|
||||
<span :class="['detail-type-badge', selectedPkgData.type === 'php-extension' ? 'badge-ext' : 'badge-lib']">
|
||||
{{ typeLabel(selectedPkgData.type) }}
|
||||
</span>
|
||||
|
||||
<!-- OS support for extensions -->
|
||||
<div v-if="selectedPkgData.type === 'php-extension' && selectedPkgData.os" class="detail-section">
|
||||
<div class="detail-label">{{ i18n.supportedPlatforms }}</div>
|
||||
<div class="detail-chips">
|
||||
<span v-for="os in selectedPkgData.os" :key="os" class="chip chip-os">{{ os }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Required deps -->
|
||||
<div class="detail-section">
|
||||
<div class="detail-label">{{ i18n.requiredDeps }}</div>
|
||||
<div class="detail-chips" v-if="currentDepends.length > 0">
|
||||
<span
|
||||
v-for="dep in currentDepends"
|
||||
:key="dep"
|
||||
:class="['chip', 'chip-required', { clickable: packages[dep] }]"
|
||||
@click="packages[dep] && selectPkg(dep)"
|
||||
>{{ dep }}</span>
|
||||
</div>
|
||||
<div v-else class="no-deps">{{ i18n.none }}</div>
|
||||
</div>
|
||||
|
||||
<!-- Suggested deps -->
|
||||
<div class="detail-section">
|
||||
<div class="detail-label">{{ i18n.suggestedDeps }}</div>
|
||||
<div class="detail-chips" v-if="currentSuggests.length > 0">
|
||||
<span
|
||||
v-for="dep in currentSuggests"
|
||||
:key="dep"
|
||||
:class="['chip', 'chip-suggested', { clickable: packages[dep] }]"
|
||||
@click="packages[dep] && selectPkg(dep)"
|
||||
>{{ dep }}</span>
|
||||
</div>
|
||||
<div v-else class="no-deps">{{ i18n.none }}</div>
|
||||
</div>
|
||||
|
||||
<!-- Required by -->
|
||||
<div class="detail-section">
|
||||
<div class="detail-label">{{ i18n.requiredBy }}</div>
|
||||
<div class="detail-chips" v-if="requiredBy.length > 0">
|
||||
<span
|
||||
v-for="dep in requiredBy"
|
||||
:key="dep"
|
||||
class="chip chip-rev clickable"
|
||||
@click="selectPkg(dep)"
|
||||
>{{ dep }}</span>
|
||||
</div>
|
||||
<div v-else class="no-deps">{{ i18n.none }}</div>
|
||||
</div>
|
||||
|
||||
<!-- Suggested by -->
|
||||
<div class="detail-section">
|
||||
<div class="detail-label">{{ i18n.suggestedBy }}</div>
|
||||
<div class="detail-chips" v-if="suggestedBy.length > 0">
|
||||
<span
|
||||
v-for="dep in suggestedBy"
|
||||
:key="dep"
|
||||
class="chip chip-rev-sug clickable"
|
||||
@click="selectPkg(dep)"
|
||||
>{{ dep }}</span>
|
||||
</div>
|
||||
<div v-else class="no-deps">{{ i18n.none }}</div>
|
||||
</div>
|
||||
|
||||
<!-- Mermaid graph -->
|
||||
<div class="detail-section" v-if="hasMermaid">
|
||||
<div class="detail-label">{{ i18n.depGraph }}</div>
|
||||
<div ref="mermaidEl" class="mermaid-wrap"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Empty state -->
|
||||
<div class="deps-detail deps-detail-empty" v-else>
|
||||
<p>{{ i18n.selectHint }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch, onMounted, nextTick } from 'vue'
|
||||
import { useData } from 'vitepress'
|
||||
import { data as depsData } from '../deps-map.data.js'
|
||||
|
||||
const { lang, isDark } = useData()
|
||||
|
||||
const missing = depsData.missing
|
||||
const packages = depsData.packages ?? {}
|
||||
|
||||
// --- i18n ---
|
||||
const I18N = {
|
||||
zh: {
|
||||
searchPlaceholder: '搜索包名...',
|
||||
noResults: '未找到包。',
|
||||
selectHint: '← 选择一个包以查看其依赖关系。',
|
||||
supportedPlatforms: '支持的平台',
|
||||
requiredDeps: '必需依赖',
|
||||
suggestedDeps: '可选依赖',
|
||||
requiredBy: '被哪些包依赖',
|
||||
suggestedBy: '被哪些包建议',
|
||||
depGraph: '依赖关系图',
|
||||
none: '无',
|
||||
},
|
||||
en: {
|
||||
searchPlaceholder: 'Search package...',
|
||||
noResults: 'No packages found.',
|
||||
selectHint: '← Select a package to view its dependency details.',
|
||||
supportedPlatforms: 'Supported Platforms',
|
||||
requiredDeps: 'Required Dependencies',
|
||||
suggestedDeps: 'Suggested Dependencies',
|
||||
requiredBy: 'Required By',
|
||||
suggestedBy: 'Suggested By',
|
||||
depGraph: 'Dependency Graph',
|
||||
none: 'None',
|
||||
},
|
||||
}
|
||||
const i18n = computed(() => I18N[lang.value] ?? I18N.en)
|
||||
|
||||
// --- State ---
|
||||
const searchText = ref('')
|
||||
const selectedType = ref('all')
|
||||
const selectedPlatform = ref('linux')
|
||||
const selectedPkg = ref(null)
|
||||
const mermaidEl = ref(null)
|
||||
|
||||
// --- Options ---
|
||||
const typeOptions = computed(() => [
|
||||
{ value: 'all', label: lang.value === 'zh' ? '全部' : 'All' },
|
||||
{ value: 'php-extension', label: lang.value === 'zh' ? '扩展' : 'Extensions' },
|
||||
{ value: 'library', label: lang.value === 'zh' ? '库' : 'Libraries' },
|
||||
])
|
||||
const platformOptions = [
|
||||
{ value: 'linux', label: 'Linux' },
|
||||
{ value: 'macos', label: 'macOS' },
|
||||
{ value: 'windows', label: 'Windows' },
|
||||
]
|
||||
|
||||
function typeLabel(type) {
|
||||
if (type === 'php-extension') return 'ext'
|
||||
if (type === 'library') return 'lib'
|
||||
return type
|
||||
}
|
||||
|
||||
// --- Package list ---
|
||||
const allPackages = computed(() =>
|
||||
Object.entries(packages).map(([name, data]) => ({ name, ...data }))
|
||||
)
|
||||
|
||||
const filteredPackages = computed(() => {
|
||||
let list = allPackages.value
|
||||
if (selectedType.value !== 'all') {
|
||||
list = list.filter(p => p.type === selectedType.value)
|
||||
}
|
||||
if (searchText.value.trim()) {
|
||||
const q = searchText.value.trim().toLowerCase()
|
||||
list = list.filter(p => p.name.toLowerCase().includes(q))
|
||||
}
|
||||
return list
|
||||
})
|
||||
|
||||
// --- Selected package ---
|
||||
const selectedPkgData = computed(() =>
|
||||
selectedPkg.value ? (packages[selectedPkg.value] ?? null) : null
|
||||
)
|
||||
|
||||
const currentDepends = computed(() =>
|
||||
selectedPkgData.value?.platforms?.[selectedPlatform.value]?.depends ?? []
|
||||
)
|
||||
const currentSuggests = computed(() =>
|
||||
selectedPkgData.value?.platforms?.[selectedPlatform.value]?.suggests ?? []
|
||||
)
|
||||
|
||||
const requiredBy = computed(() => {
|
||||
if (!selectedPkg.value) return []
|
||||
const name = selectedPkg.value
|
||||
const plat = selectedPlatform.value
|
||||
return Object.entries(packages)
|
||||
.filter(([, d]) => (d.platforms?.[plat]?.depends ?? []).includes(name))
|
||||
.map(([n]) => n)
|
||||
})
|
||||
|
||||
const suggestedBy = computed(() => {
|
||||
if (!selectedPkg.value) return []
|
||||
const name = selectedPkg.value
|
||||
const plat = selectedPlatform.value
|
||||
return Object.entries(packages)
|
||||
.filter(([, d]) => (d.platforms?.[plat]?.suggests ?? []).includes(name))
|
||||
.map(([n]) => n)
|
||||
})
|
||||
|
||||
// --- Mermaid ---
|
||||
const hasMermaid = computed(
|
||||
() => currentDepends.value.length > 0 || currentSuggests.value.length > 0
|
||||
)
|
||||
|
||||
function buildMermaidCode() {
|
||||
const deps = currentDepends.value
|
||||
const sugs = currentSuggests.value
|
||||
if (deps.length === 0 && sugs.length === 0) return ''
|
||||
|
||||
const safe = s => s.replace(/[^a-zA-Z0-9_]/g, '_')
|
||||
const root = safe(selectedPkg.value)
|
||||
const lines = ['graph LR', ` ${root}["${selectedPkg.value}"]`]
|
||||
|
||||
const MAX_DEPTH = 6 // max hops from root
|
||||
const MAX_CHILDREN = 6 // per-node child limit for levels 2+
|
||||
|
||||
const visitedNodes = new Set([selectedPkg.value])
|
||||
const visitedEdges = new Set()
|
||||
const queue = []
|
||||
|
||||
// Level 1: direct required deps — solid arrows, no child limit
|
||||
for (const dep of deps) {
|
||||
const ek = `${selectedPkg.value}\0${dep}`
|
||||
if (!visitedEdges.has(ek)) {
|
||||
visitedEdges.add(ek)
|
||||
lines.push(` ${root} --> ${safe(dep)}["${dep}"]`)
|
||||
}
|
||||
if (!visitedNodes.has(dep)) {
|
||||
visitedNodes.add(dep)
|
||||
queue.push({ name: dep, depth: 1 })
|
||||
}
|
||||
}
|
||||
|
||||
// BFS: levels 2–MAX_DEPTH — dotted arrows, capped children per node
|
||||
while (queue.length > 0) {
|
||||
const { name, depth } = queue.shift()
|
||||
if (depth >= MAX_DEPTH) continue
|
||||
const children = packages[name]?.platforms?.[selectedPlatform.value]?.depends ?? []
|
||||
for (const child of children.slice(0, MAX_CHILDREN)) {
|
||||
const ek = `${name}\0${child}`
|
||||
if (!visitedEdges.has(ek)) {
|
||||
visitedEdges.add(ek)
|
||||
lines.push(` ${safe(name)} -.-> ${safe(child)}["${child}"]`)
|
||||
}
|
||||
if (!visitedNodes.has(child)) {
|
||||
visitedNodes.add(child)
|
||||
queue.push({ name: child, depth: depth + 1 })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Suggested deps from root (single level, optional dotted)
|
||||
for (const sug of sugs) {
|
||||
lines.push(` ${root} -. optional .-> ${safe(sug)}["${sug}"]`)
|
||||
}
|
||||
|
||||
return lines.join('\n')
|
||||
}
|
||||
|
||||
let mermaidLib = null
|
||||
|
||||
async function renderMermaid() {
|
||||
if (!mermaidEl.value || !hasMermaid.value) return
|
||||
const code = buildMermaidCode()
|
||||
if (!code) return
|
||||
|
||||
try {
|
||||
if (!mermaidLib) {
|
||||
const m = await import('mermaid')
|
||||
mermaidLib = m.default
|
||||
}
|
||||
mermaidLib.initialize({
|
||||
startOnLoad: false,
|
||||
theme: isDark.value ? 'dark' : 'default',
|
||||
securityLevel: 'loose',
|
||||
})
|
||||
const id = 'deps-graph-' + Date.now()
|
||||
const { svg } = await mermaidLib.render(id, code)
|
||||
if (mermaidEl.value) {
|
||||
mermaidEl.value.innerHTML = svg
|
||||
}
|
||||
} catch {
|
||||
if (mermaidEl.value) {
|
||||
mermaidEl.value.innerHTML = `<pre class="mermaid-fallback">${code}</pre>`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function selectPkg(name) {
|
||||
selectedPkg.value = name
|
||||
}
|
||||
|
||||
watch([selectedPkg, selectedPlatform, isDark], async () => {
|
||||
await nextTick()
|
||||
await renderMermaid()
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
await nextTick()
|
||||
await renderMermaid()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.deps-map {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Toolbar */
|
||||
.deps-toolbar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.deps-search {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
background: var(--vp-c-bg);
|
||||
color: var(--vp-c-text-1);
|
||||
outline: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.deps-search:focus {
|
||||
border-color: var(--vp-c-brand);
|
||||
}
|
||||
|
||||
.deps-filters {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.filter-group {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.filter-btn {
|
||||
padding: 4px 12px;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
border-radius: 20px;
|
||||
background: var(--vp-c-bg);
|
||||
color: var(--vp-c-text-2);
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.filter-btn:hover {
|
||||
border-color: var(--vp-c-brand);
|
||||
color: var(--vp-c-brand);
|
||||
}
|
||||
.filter-btn.active {
|
||||
background: var(--vp-c-brand);
|
||||
border-color: var(--vp-c-brand);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Layout */
|
||||
.deps-layout {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
/* Package list */
|
||||
.deps-list {
|
||||
width: 260px;
|
||||
flex-shrink: 0;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
border-radius: 8px;
|
||||
overflow-y: auto;
|
||||
max-height: 600px;
|
||||
}
|
||||
|
||||
.no-results {
|
||||
padding: 16px;
|
||||
color: var(--vp-c-text-3);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pkg-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 8px 12px;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid var(--vp-c-divider);
|
||||
transition: background 0.1s;
|
||||
}
|
||||
.pkg-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.pkg-item:hover {
|
||||
background: var(--vp-c-bg-soft);
|
||||
}
|
||||
.pkg-item.selected {
|
||||
background: var(--vp-c-brand-soft);
|
||||
}
|
||||
|
||||
.pkg-name {
|
||||
font-family: var(--vp-font-family-mono);
|
||||
font-size: 13px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.pkg-badge {
|
||||
font-size: 11px;
|
||||
padding: 1px 6px;
|
||||
border-radius: 10px;
|
||||
flex-shrink: 0;
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
/* Detail panel */
|
||||
.deps-detail {
|
||||
flex: 1;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
max-height: 600px;
|
||||
}
|
||||
|
||||
.deps-detail-empty {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--vp-c-text-3);
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 16px;
|
||||
font-family: var(--vp-font-family-mono);
|
||||
}
|
||||
|
||||
.detail-type-badge {
|
||||
font-size: 12px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
display: inline-block;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.detail-section {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: var(--vp-c-text-2);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.detail-chips {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.no-deps {
|
||||
color: var(--vp-c-text-3);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* Chips */
|
||||
.chip {
|
||||
font-family: var(--vp-font-family-mono);
|
||||
font-size: 12px;
|
||||
padding: 3px 10px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid transparent;
|
||||
display: inline-block;
|
||||
}
|
||||
.chip.clickable {
|
||||
cursor: pointer;
|
||||
transition: opacity 0.15s;
|
||||
}
|
||||
.chip.clickable:hover {
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.chip-required {
|
||||
background: var(--vp-c-danger-soft);
|
||||
border-color: var(--vp-c-danger-1);
|
||||
color: var(--vp-c-danger-1);
|
||||
}
|
||||
.chip-suggested {
|
||||
background: var(--vp-c-warning-soft);
|
||||
border-color: var(--vp-c-warning-1);
|
||||
color: var(--vp-c-warning-1);
|
||||
}
|
||||
.chip-rev {
|
||||
background: var(--vp-c-brand-soft);
|
||||
border-color: var(--vp-c-brand-1);
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
.chip-rev-sug {
|
||||
background: var(--vp-c-bg-soft);
|
||||
border-color: var(--vp-c-divider);
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
.chip-os {
|
||||
background: var(--vp-c-bg-soft);
|
||||
border-color: var(--vp-c-divider);
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
|
||||
/* Badges */
|
||||
.badge-ext {
|
||||
background: var(--vp-c-brand-soft);
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
.badge-lib {
|
||||
background: var(--vp-c-tip-soft);
|
||||
color: var(--vp-c-tip-1);
|
||||
}
|
||||
|
||||
/* Mermaid */
|
||||
.mermaid-wrap {
|
||||
overflow-x: auto;
|
||||
padding: 8px 0;
|
||||
}
|
||||
.mermaid-fallback {
|
||||
font-size: 12px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
</style>
|
||||
23
docs/.vitepress/deps-map.data.js
Normal file
23
docs/.vitepress/deps-map.data.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import { readFileSync, existsSync } from 'node:fs'
|
||||
import { resolve, dirname } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
const DATA_PATH = resolve(__dirname, 'deps-data.json')
|
||||
|
||||
export default {
|
||||
watch: [DATA_PATH],
|
||||
|
||||
load() {
|
||||
if (!existsSync(DATA_PATH)) {
|
||||
console.warn(
|
||||
'[deps-map.data.js] deps-data.json not found. ' +
|
||||
'Run `bin/spc dev:gen-deps-data` to generate it.'
|
||||
)
|
||||
return { packages: {}, missing: true }
|
||||
}
|
||||
|
||||
const raw = JSON.parse(readFileSync(DATA_PATH, 'utf-8'))
|
||||
return { packages: raw.packages ?? {}, missing: false }
|
||||
},
|
||||
}
|
||||
@@ -3,9 +3,13 @@ import DefaultTheme from 'vitepress/theme'
|
||||
import {inBrowser, useData} from "vitepress";
|
||||
import {watchEffect} from "vue";
|
||||
import './style.css';
|
||||
import DepsMap from '../components/DepsMap.vue';
|
||||
|
||||
export default {
|
||||
...DefaultTheme,
|
||||
enhanceApp({ app }) {
|
||||
app.component('DepsMap', DepsMap)
|
||||
},
|
||||
setup() {
|
||||
const { lang } = useData()
|
||||
watchEffect(() => {
|
||||
|
||||
@@ -22,26 +22,26 @@ spc download [artifacts] [options]
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Short | Description |
|
||||
|---|---|---|
|
||||
| `--for-extensions=<list>` | `-e` | Download artifacts needed by the given extensions |
|
||||
| `--for-libs=<list>` | `-l` | Download artifacts needed by the given libraries |
|
||||
| `--for-packages=<list>` | | Download artifacts needed by the given packages |
|
||||
| `--without-suggests` | | Skip suggested packages when using `--for-extensions` |
|
||||
| `--clean` | | Delete existing download cache before fetching |
|
||||
| `--with-php=<ver>` | | PHP version in `major.minor` format (default: `8.4`) |
|
||||
| `--prefer-binary` | `-p` | Prefer pre-built binaries over source archives |
|
||||
| `--prefer-source` | | Prefer source archives over pre-built binaries |
|
||||
| `--source-only` | | Only download source artifacts |
|
||||
| `--binary-only` | | Only download binary artifacts |
|
||||
| `--parallel=<n>` | `-P` | Number of parallel downloads (default: `1`) |
|
||||
| `--retry=<n>` | `-R` | Number of retries on failure (default: `0`) |
|
||||
| `--ignore-cache=<list>` | | Force re-download the specified artifacts |
|
||||
| `--no-alt` | | Do not use alternative mirror URLs |
|
||||
| `--no-shallow-clone` | | Do not clone git repositories shallowly |
|
||||
| `--custom-url=<src:url>` | `-U` | Override the download URL for a source |
|
||||
| `--custom-git=<src:branch:url>` | `-G` | Override with a custom git repository |
|
||||
| `--custom-local=<src:path>` | `-L` | Use a local path as a source override |
|
||||
| Option | Short | Description |
|
||||
|---------------------------------|-------|-------------------------------------------------------|
|
||||
| `--for-extensions=<list>` | `-e` | Download artifacts needed by the given extensions |
|
||||
| `--for-libs=<list>` | `-l` | Download artifacts needed by the given libraries |
|
||||
| `--for-packages=<list>` | | Download artifacts needed by the given packages |
|
||||
| `--without-suggests` | | Skip suggested packages when using `--for-extensions` |
|
||||
| `--clean` | | Delete existing download cache before fetching |
|
||||
| `--with-php=<ver>` | | PHP version in `major.minor` format (default: `8.4`) |
|
||||
| `--prefer-binary` | `-p` | Prefer pre-built binaries over source archives |
|
||||
| `--prefer-source` | | Prefer source archives over pre-built binaries |
|
||||
| `--source-only` | | Only download source artifacts |
|
||||
| `--binary-only` | | Only download binary artifacts |
|
||||
| `--parallel=<n>` | `-P` | Number of parallel downloads (default: `1`) |
|
||||
| `--retry=<n>` | `-R` | Number of retries on failure (default: `0`) |
|
||||
| `--ignore-cache=<list>` | | Force re-download the specified artifacts |
|
||||
| `--no-alt` | | Do not use alternative mirror URLs |
|
||||
| `--no-shallow-clone` | | Do not clone git repositories shallowly |
|
||||
| `--custom-url=<src:url>` | `-U` | Override the download URL for a source |
|
||||
| `--custom-git=<src:branch:url>` | `-G` | Override with a custom git repository |
|
||||
| `--custom-local=<src:path>` | `-L` | Use a local path as a source override |
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -81,67 +81,73 @@ All `download` options are also available on `build:php` with the `--dl-` prefix
|
||||
|
||||
These flags apply only to the combined `build:php` target. To build a specific SAPI in isolation, use its dedicated command (e.g. `spc build:php-cli`).
|
||||
|
||||
| Option | Description |
|
||||
|---|---|
|
||||
| `--build-cli` | Build the `cli` SAPI (`php` / `php.exe`) |
|
||||
| `--build-fpm` | Build `php-fpm` (Linux and macOS only) |
|
||||
| `--build-cgi` | Build `php-cgi` |
|
||||
| `--build-micro` | Build `micro.sfx` |
|
||||
| `--build-embed` | Build the embed static library (`libphp.a` / `php8embed.lib`) |
|
||||
| `--build-frankenphp` | Build the FrankenPHP binary |
|
||||
| Option | Description |
|
||||
|----------------------|---------------------------------------------------------------|
|
||||
| `--build-cli` | Build the `cli` SAPI (`php` / `php.exe`) |
|
||||
| `--build-fpm` | Build `php-fpm` (Linux and macOS only) |
|
||||
| `--build-cgi` | Build `php-cgi` |
|
||||
| `--build-micro` | Build `micro.sfx` |
|
||||
| `--build-embed` | Build the embed static library (`libphp.a` / `php8embed.lib`) |
|
||||
| `--build-frankenphp` | Build the FrankenPHP binary |
|
||||
|
||||
### Common Build Options {#common-build-options}
|
||||
|
||||
| Option | Short | Description |
|
||||
|---|---|---|
|
||||
| `--no-strip` | | Keep debug symbols; do not strip the binary |
|
||||
| `--with-upx-pack` | | Compress the output binary with UPX (install first with `spc install-pkg upx`; Linux and Windows only) |
|
||||
| `--disable-opcache-jit` | | Disable OPcache JIT |
|
||||
| `--with-config-file-path=<path>` | | Directory where PHP looks for `php.ini` (default: `/usr/local/etc/php`) |
|
||||
| `--with-config-file-scan-dir=<path>` | | Directory PHP scans for additional `.ini` files (default: `/usr/local/etc/php/conf.d`) |
|
||||
| `--with-hardcoded-ini=<k=v>` | `-I` | Bake an INI setting into the binary at compile time (repeatable) |
|
||||
| `--enable-zts` | | Enable thread-safe (ZTS) mode |
|
||||
| `--no-smoke-test` | | Skip the post-build smoke tests |
|
||||
| `--with-suggests` | `-L` / `-E` | Also resolve and install suggested packages |
|
||||
| `--with-packages=<list>` | | Additional packages to install alongside the build |
|
||||
| `--no-download` | | Skip the download step (use existing cached files) |
|
||||
| `--with-added-patch=<file>` | `-P` | Inject an external PHP patch script (repeatable) |
|
||||
| `--build-shared=<list>` | `-D` | Extensions to compile as shared `.so` / `.dll` instead of static |
|
||||
| Option | Short | Description |
|
||||
|--------------------------------------|-------|--------------------------------------------------------------------------------------------------------|
|
||||
| `--no-strip` | | Keep debug symbols; do not strip the binary |
|
||||
| `--with-upx-pack` | | Compress the output binary with UPX (install first with `spc install-pkg upx`; Linux and Windows only) |
|
||||
| `--disable-opcache-jit` | | Disable OPcache JIT |
|
||||
| `--with-config-file-path=<path>` | | Directory where PHP looks for `php.ini` (default: `/usr/local/etc/php`) |
|
||||
| `--with-config-file-scan-dir=<path>` | | Directory PHP scans for additional `.ini` files (default: `/usr/local/etc/php/conf.d`) |
|
||||
| `--with-hardcoded-ini=<k=v>` | `-I` | Bake an INI setting into the binary at compile time (repeatable) |
|
||||
| `--enable-zts` | | Enable thread-safe (ZTS) mode |
|
||||
| `--no-smoke-test` | | Skip the post-build smoke tests |
|
||||
| `--with-suggests` | | Also resolve and install suggested packages |
|
||||
| `--with-packages=<list>` | | Additional packages to install alongside the build |
|
||||
| `--no-download` | | Skip the download step (use existing cached files) |
|
||||
| `--build-shared=<list>` | `-D` | Extensions to compile as shared `.so` / `.dll` instead of static |
|
||||
|
||||
### micro Options {#micro-options}
|
||||
|
||||
| Option | Description |
|
||||
|---|---|
|
||||
| `--with-micro-fake-cli` | Make `micro`'s `PHP_SAPI` report `cli` instead of `micro` |
|
||||
| `--without-micro-ext-test` | Disable the post-build extension test for `micro.sfx` |
|
||||
| `--with-micro-logo=<path>` | Embed a custom `.ico` icon into `micro.sfx` (Windows only) |
|
||||
| `--enable-micro-win32` | Build `micro.sfx` as a Win32 GUI application instead of a console app (Windows only) |
|
||||
| Option | Description |
|
||||
|----------------------------|--------------------------------------------------------------------------------------|
|
||||
| `--with-micro-fake-cli` | Make `micro`'s `PHP_SAPI` report `cli` instead of `micro` |
|
||||
| `--without-micro-ext-test` | Disable the post-build extension test for `micro.sfx` |
|
||||
| `--with-micro-logo=<path>` | Embed a custom `.ico` icon into `micro.sfx` (Windows only) |
|
||||
| `--enable-micro-win32` | Build `micro.sfx` as a Win32 GUI application instead of a console app (Windows only) |
|
||||
|
||||
### frankenphp Options {#frankenphp-options}
|
||||
|
||||
| Option | Description |
|
||||
|---|---|
|
||||
| `--enable-zts` | Required for FrankenPHP; enables thread-safe mode |
|
||||
| `--with-frankenphp-app=<path>` | Embed a directory into the FrankenPHP binary |
|
||||
| Option | Description |
|
||||
|--------------------------------|---------------------------------------------------|
|
||||
| `--enable-zts` | Required for FrankenPHP; enables thread-safe mode |
|
||||
| `--with-frankenphp-app=<path>` | Embed a directory into the FrankenPHP binary |
|
||||
|
||||
### embed Options {#embed-options}
|
||||
|
||||
| Option | Description |
|
||||
|---|---|
|
||||
| Option | Description |
|
||||
|-------------------------|-----------------------------------------------------------------------|
|
||||
| `--build-shared=<list>` | Compile specific extensions as shared libraries (requires embed SAPI) |
|
||||
|
||||
### Download Pass-through Options {#download-options}
|
||||
|
||||
All downloader options are available with the `--dl-` prefix:
|
||||
|
||||
| Option | Description |
|
||||
|---|---|
|
||||
| `--dl-with-php=<ver>` | PHP version to download (default: `8.4`) |
|
||||
| `--dl-prefer-binary` | Prefer pre-built binaries for dependencies |
|
||||
| `--dl-parallel=<n>` | Number of parallel downloads |
|
||||
| `--dl-retry=<n>` | Number of retries on failure |
|
||||
| `--dl-custom-url=<src:url>` | Override a source download URL |
|
||||
| `--dl-custom-git=<src:branch:url>` | Override with a custom git repository |
|
||||
| Option | Description |
|
||||
|------------------------------------|--------------------------------------------|
|
||||
| `--dl-with-php=<ver>` | PHP version to download (default: `8.4`) |
|
||||
| `--dl-prefer-binary` | Prefer pre-built binaries for dependencies |
|
||||
| `--dl-parallel=<n>` | Number of parallel downloads |
|
||||
| `--dl-retry=<n>` | Number of retries on failure |
|
||||
| `--dl-custom-url=<src:url>` | Override a source download URL |
|
||||
| `--dl-custom-git=<src:branch:url>` | Override with a custom git repository |
|
||||
|
||||
Downloader options passed to `build:php` are used by the automatic downloader that runs before the build.
|
||||
This allows you to control the download behavior without needing a separate `spc download` command.
|
||||
|
||||
```bash
|
||||
spc build:php "bcmath,openssl,curl" --build-cli --dl-with-php=8.3 --dl-prefer-binary --dl-parallel=4
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -177,6 +183,42 @@ spc build:php-embed "bcmath,openssl"
|
||||
spc build:frankenphp "bcmath,openssl,curl" --enable-zts
|
||||
```
|
||||
|
||||
## build:libs
|
||||
|
||||
Build one or more library packages from source.
|
||||
|
||||
```bash
|
||||
spc build:libs <libraries> [options]
|
||||
```
|
||||
|
||||
`libraries` (required): Comma-separated list of library package names to build (e.g. `"openssl,curl,zlib"`).
|
||||
|
||||
All `download` options are available with the `--dl-` prefix.
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Short | Description |
|
||||
|---|---|---|
|
||||
| `--with-suggests` | `-L`, `-E` | Also resolve and install suggested packages |
|
||||
| `--with-packages=<list>` | | Additional packages to install alongside the build, comma-separated |
|
||||
| `--no-download` | | Skip downloading artifacts (use existing cached files) |
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Build a single library
|
||||
spc build:libs openssl
|
||||
|
||||
# Build multiple libraries
|
||||
spc build:libs "openssl,curl,zlib"
|
||||
|
||||
# Build with suggested packages included
|
||||
spc build:libs openssl --with-suggests
|
||||
|
||||
# Skip the download step
|
||||
spc build:libs openssl --no-download
|
||||
```
|
||||
|
||||
## craft
|
||||
|
||||
Read a `craft.yml` and run the full build pipeline automatically.
|
||||
@@ -195,10 +237,10 @@ Diagnose whether the current environment can compile PHP normally.
|
||||
spc doctor [--auto-fix[=never]]
|
||||
```
|
||||
|
||||
| Option | Description |
|
||||
|---|---|
|
||||
| `--auto-fix` | Automatically fix detected issues using the system package manager |
|
||||
| `--auto-fix=never` | Report issues but never attempt automatic fixes |
|
||||
| Option | Description |
|
||||
|--------------------|--------------------------------------------------------------------|
|
||||
| `--auto-fix` | Automatically fix detected issues using the system package manager |
|
||||
| `--auto-fix=never` | Report issues but never attempt automatic fixes |
|
||||
|
||||
## dev:shell
|
||||
|
||||
@@ -209,3 +251,275 @@ spc dev:shell
|
||||
```
|
||||
|
||||
Useful for compiling small programs against `libphp.a` (embed SAPI) or inspecting the build environment manually.
|
||||
|
||||
## check-update
|
||||
|
||||
Check whether newer versions are available for downloaded artifacts.
|
||||
|
||||
```bash
|
||||
spc check-update [artifact] [options]
|
||||
```
|
||||
|
||||
`artifact` (optional): Artifact names to check, comma-separated. Defaults to all currently downloaded artifacts.
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Short | Description |
|
||||
|---|---|---|
|
||||
| `--json` | | Output results in JSON format |
|
||||
| `--bare` | | Check without requiring the artifact to be downloaded first (old version will be `null`) |
|
||||
| `--parallel=<n>` | `-p` | Number of parallel update checks (default: `10`) |
|
||||
| `--with-php=<ver>` | | PHP version context in `major.minor` format (default: `8.4`) |
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Check all downloaded artifacts
|
||||
spc check-update
|
||||
|
||||
# Check specific artifacts
|
||||
spc check-update "openssl,curl"
|
||||
|
||||
# Output as JSON
|
||||
spc check-update --json
|
||||
|
||||
# Check without requiring a prior download
|
||||
spc check-update "openssl" --bare
|
||||
```
|
||||
|
||||
## dump-extensions
|
||||
|
||||
Analyse a Composer project and output the list of PHP extensions it requires.
|
||||
|
||||
```bash
|
||||
spc dump-extensions [path] [options]
|
||||
```
|
||||
|
||||
`path` (optional): Path to the project root (default: `.`).
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Short | Description |
|
||||
|---|---|---|
|
||||
| `--format=<fmt>` | `-F` | Output format (default: `default`) |
|
||||
| `--no-ext-output=<list>` | `-N` | When no extensions are found, output this default comma-separated list instead of exiting with failure |
|
||||
| `--no-dev` | | Exclude dev dependencies |
|
||||
| `--no-spc-filter` | `-S` | Do not apply the SPC filter when determining required extensions |
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Analyse the current directory
|
||||
spc dump-extensions
|
||||
|
||||
# Analyse a specific directory
|
||||
spc dump-extensions /path/to/project
|
||||
|
||||
# Exclude dev dependencies
|
||||
spc dump-extensions --no-dev
|
||||
|
||||
# Fall back to a default list when no extensions are found
|
||||
spc dump-extensions --no-ext-output="bcmath,openssl"
|
||||
```
|
||||
|
||||
## dump-license
|
||||
|
||||
Export open-source license files for artifacts.
|
||||
|
||||
```bash
|
||||
spc dump-license [artifacts] [options]
|
||||
```
|
||||
|
||||
`artifacts` (optional): Specific artifacts whose licenses should be dumped, comma-separated (e.g. `"php-src,openssl,curl"`).
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Short | Description |
|
||||
|---|---|---|
|
||||
| `--for-extensions=<list>` | `-e` | Dump by extension names (automatically includes `php-src`), e.g. `"openssl,mbstring"` |
|
||||
| `--for-libs=<list>` | `-l` | Dump by library names, e.g. `"openssl,zlib"` |
|
||||
| `--for-packages=<list>` | `-p` | Dump by package names, e.g. `"php,libssl"` |
|
||||
| `--dump-dir=<path>` | `-d` | Directory to write license files (default: `buildroot/license`) |
|
||||
| `--without-suggests` | | Do not include licenses for suggested packages |
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Dump licenses for the extensions you compiled
|
||||
spc dump-license --for-extensions="bcmath,openssl,curl"
|
||||
|
||||
# Dump licenses for specific artifacts
|
||||
spc dump-license "php-src,openssl"
|
||||
|
||||
# Write licenses to a custom directory
|
||||
spc dump-license --for-extensions="bcmath,openssl" --dump-dir=/tmp/licenses
|
||||
```
|
||||
|
||||
## extract
|
||||
|
||||
Extract downloaded artifacts to their target locations in the source tree.
|
||||
|
||||
```bash
|
||||
spc extract [artifacts] [options]
|
||||
```
|
||||
|
||||
`artifacts` (optional): Specific artifacts to extract, comma-separated (e.g. `"php-src,openssl,curl"`).
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Short | Description |
|
||||
|---|---|---|
|
||||
| `--for-extensions=<list>` | `-e` | Extract artifacts needed by the given extensions, e.g. `"openssl,mbstring"` |
|
||||
| `--for-libs=<list>` | `-l` | Extract artifacts needed by the given libraries, e.g. `"libcares,openssl"` |
|
||||
| `--for-packages=<list>` | | Extract artifacts needed by the given packages, e.g. `"php,libssl,libcurl"` |
|
||||
| `--without-suggests` | | Skip suggested packages when using `--for-extensions` |
|
||||
| `--source-only` | | Force extraction from source even if a pre-built binary is available |
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Extract artifacts for a set of extensions
|
||||
spc extract --for-extensions="bcmath,openssl,curl"
|
||||
|
||||
# Extract specific artifacts
|
||||
spc extract "php-src,openssl"
|
||||
|
||||
# Force source extraction
|
||||
spc extract --for-extensions="bcmath,openssl" --source-only
|
||||
```
|
||||
|
||||
## install-pkg
|
||||
|
||||
Install additional helper packages (e.g. UPX, toolchains). Aliases: `i`, `install-package`.
|
||||
|
||||
```bash
|
||||
spc install-pkg <package> [options]
|
||||
```
|
||||
|
||||
`package` (required): The name of the package to install.
|
||||
|
||||
All `download` options are available with the `--dl-` prefix.
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Install the UPX compressor
|
||||
spc install-pkg upx
|
||||
```
|
||||
|
||||
## micro:combine
|
||||
|
||||
Merge `micro.sfx` with a PHP or PHAR file to produce a standalone executable.
|
||||
|
||||
```bash
|
||||
spc micro:combine <file> [options]
|
||||
```
|
||||
|
||||
`file` (required): Path to the PHP or PHAR file to combine.
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Short | Description |
|
||||
|---|---|---|
|
||||
| `--with-micro=<path>` | `-M` | Path to a custom `micro.sfx` (default: `buildroot/bin/micro.sfx`) |
|
||||
| `--with-ini-set=<k=v>` | `-I` | Inject an INI setting into the binary (repeatable) |
|
||||
| `--with-ini-file=<path>` | `-N` | Inject INI settings from a file |
|
||||
| `--output=<name>` | `-O` | Output file name (default: `my-app`) |
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Combine a PHP script
|
||||
spc micro:combine app.php
|
||||
|
||||
# Combine a PHAR with a custom output name
|
||||
spc micro:combine app.phar --output my-app
|
||||
|
||||
# Inject INI settings
|
||||
spc micro:combine app.php -I "memory_limit=512M" -I "disable_functions=system"
|
||||
|
||||
# Inject from an INI file
|
||||
spc micro:combine app.php --with-ini-file=custom.ini
|
||||
|
||||
# Use a custom micro.sfx
|
||||
spc micro:combine app.php --with-micro=/path/to/micro.sfx
|
||||
```
|
||||
|
||||
## reset
|
||||
|
||||
Clean build directories and reset the build environment.
|
||||
|
||||
```bash
|
||||
spc reset [options]
|
||||
```
|
||||
|
||||
By default, removes `buildroot/` and `source/`.
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Short | Description |
|
||||
|---|---|---|
|
||||
| `--with-pkgroot` | | Also remove the `pkgroot/` directory |
|
||||
| `--with-download` | | Also remove the `downloads/` directory |
|
||||
| `--yes` | `-y` | Skip the confirmation prompt |
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Clean build directories (will prompt for confirmation)
|
||||
spc reset
|
||||
|
||||
# Also clear the download cache
|
||||
spc reset --with-download
|
||||
|
||||
# Full clean without prompting
|
||||
spc reset --with-pkgroot --with-download --yes
|
||||
```
|
||||
|
||||
## spc-config
|
||||
|
||||
Output compiler and linker flags needed to link your own program against the PHP embed static library.
|
||||
|
||||
```bash
|
||||
spc spc-config [extensions] [options]
|
||||
```
|
||||
|
||||
`extensions` (optional): Comma-separated list of extensions to include.
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Short | Description |
|
||||
|---|---|---|
|
||||
| `--with-libs=<list>` | | Additional libraries to include, comma-separated |
|
||||
| `--with-packages=<list>` | `-p` | Additional packages to include, comma-separated |
|
||||
| `--with-suggested-libs` | `-L` | Include suggested libraries |
|
||||
| `--with-suggests` | | Include all suggested packages |
|
||||
| `--with-suggested-exts` | `-E` | Include suggested extensions |
|
||||
| `--includes` | | Output only `-I` include paths (`CFLAGS`) |
|
||||
| `--libs` | | Output only `-L` and `-l` linker flags (`LDFLAGS` + `LIBS`) |
|
||||
| `--libs-only-deps` | | Output only `-l` dependency flags |
|
||||
| `--absolute-libs` | | Use absolute paths for library files |
|
||||
| `--no-php` | | Do not link against the PHP library |
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Output full compiler + linker flags
|
||||
spc spc-config "bcmath,openssl,curl"
|
||||
|
||||
# Output include paths only
|
||||
spc spc-config "bcmath,openssl" --includes
|
||||
|
||||
# Output linker flags only
|
||||
spc spc-config "bcmath,openssl" --libs
|
||||
|
||||
# Use absolute library paths
|
||||
spc spc-config "bcmath,openssl" --libs --absolute-libs
|
||||
```
|
||||
Enter an interactive shell with StaticPHP's build environment pre-loaded (compiler wrappers, `buildroot/`, `pkgroot/` paths, etc. on `PATH`).
|
||||
|
||||
```bash
|
||||
spc dev:shell
|
||||
```
|
||||
|
||||
Useful for compiling small programs against `libphp.a` (embed SAPI) or inspecting the build environment manually.
|
||||
|
||||
@@ -1,4 +1,19 @@
|
||||
# Dependency Table
|
||||
---
|
||||
aside: false
|
||||
---
|
||||
|
||||
<!-- TODO: Auto-generated by `bin/spc dev:gen-ext-dep-docs` and `dev:gen-lib-dep-docs`.
|
||||
Placeholder until commands are implemented in v3. -->
|
||||
# Dependency Map
|
||||
|
||||
This page lists all supported packages (extensions and libraries) together with their dependency relationships.
|
||||
|
||||
- **Required Dependencies**: packages that are always built alongside the selected package.
|
||||
- **Suggested Dependencies**: packages that are not built by default; enable them with `--with-suggests` or by specifying them manually.
|
||||
- **Required By / Suggested By**: which other packages need or suggest this package.
|
||||
|
||||
Run the following command to generate the dependency data (source mode required):
|
||||
|
||||
```bash
|
||||
bin/spc dev:gen-deps-data
|
||||
```
|
||||
|
||||
<DepsMap />
|
||||
|
||||
@@ -92,30 +92,29 @@ spc build:php <extensions> [options]
|
||||
|
||||
### 通用构建选项 {#common-build-options}
|
||||
|
||||
| 选项 | 缩写 | 说明 |
|
||||
|---|---|---|
|
||||
| `--no-strip` | | 保留调试符号,不精简二进制 |
|
||||
| `--with-upx-pack` | | 用 UPX 压缩产物(需先 `spc install-pkg upx`;仅 Linux 和 Windows)|
|
||||
| `--disable-opcache-jit` | | 禁用 OPcache JIT |
|
||||
| `--with-config-file-path=<path>` | | PHP 查找 `php.ini` 的目录(默认:`/usr/local/etc/php`)|
|
||||
| `--with-config-file-scan-dir=<path>` | | PHP 扫描追加 `.ini` 文件的目录(默认:`/usr/local/etc/php/conf.d`)|
|
||||
| `--with-hardcoded-ini=<k=v>` | `-I` | 编译时将 INI 配置硬编码进二进制(可重复使用)|
|
||||
| `--enable-zts` | | 启用线程安全(ZTS)模式 |
|
||||
| `--no-smoke-test` | | 跳过构建后的冒烟测试 |
|
||||
| `--with-suggests` | `-L` / `-E` | 同时解析并安装建议包 |
|
||||
| `--with-packages=<list>` | | 额外安装的包 |
|
||||
| `--no-download` | | 跳过下载步骤(使用已有缓存)|
|
||||
| `--with-added-patch=<file>` | `-P` | 注入外部 PHP 补丁脚本(可重复使用)|
|
||||
| `--build-shared=<list>` | `-D` | 指定编译为共享 `.so` / `.dll` 的扩展 |
|
||||
| 选项 | 缩写 | 说明 |
|
||||
|--------------------------------------|------|--------------------------------------------------------|
|
||||
| `--no-strip` | | 保留调试符号,不精简二进制 |
|
||||
| `--with-upx-pack` | | 用 UPX 压缩产物(需先 `spc install-pkg upx`;仅 Linux 和 Windows) |
|
||||
| `--disable-opcache-jit` | | 禁用 OPcache JIT |
|
||||
| `--with-config-file-path=<path>` | | PHP 查找 `php.ini` 的目录(默认:`/usr/local/etc/php`) |
|
||||
| `--with-config-file-scan-dir=<path>` | | PHP 扫描追加 `.ini` 文件的目录(默认:`/usr/local/etc/php/conf.d`) |
|
||||
| `--with-hardcoded-ini=<k=v>` | `-I` | 编译时将 INI 配置硬编码进二进制(可重复使用) |
|
||||
| `--enable-zts` | | 启用线程安全(ZTS)模式 |
|
||||
| `--no-smoke-test` | | 跳过构建后的冒烟测试 |
|
||||
| `--with-suggests` | | 同时解析并安装建议包 |
|
||||
| `--with-packages=<list>` | | 额外安装的包 |
|
||||
| `--no-download` | | 跳过下载步骤(使用已有缓存) |
|
||||
| `--build-shared=<list>` | `-D` | 指定编译为共享 `.so` / `.dll` 的扩展 |
|
||||
|
||||
### micro 专用选项 {#micro-options}
|
||||
|
||||
| 选项 | 说明 |
|
||||
|---|---|
|
||||
| `--with-micro-fake-cli` | 让 `micro` 的 `PHP_SAPI` 报告为 `cli` 而非 `micro` |
|
||||
| `--without-micro-ext-test` | 跳过构建后的 `micro.sfx` 扩展测试 |
|
||||
| `--with-micro-logo=<path>` | 为 `micro.sfx` 嵌入自定义 `.ico` 图标(仅 Windows)|
|
||||
| `--enable-micro-win32` | 将 `micro.sfx` 构建为 Win32 GUI 程序而非控制台程序(仅 Windows)|
|
||||
| 选项 | 说明 |
|
||||
|----------------------------|--------------------------------------------------|
|
||||
| `--with-micro-fake-cli` | 让 `micro` 的 `PHP_SAPI` 报告为 `cli` 而非 `micro` |
|
||||
| `--without-micro-ext-test` | 跳过构建后的 `micro.sfx` 扩展测试 |
|
||||
| `--with-micro-logo=<path>` | 为 `micro.sfx` 嵌入自定义 `.ico` 图标(仅 Windows) |
|
||||
| `--enable-micro-win32` | 将 `micro.sfx` 构建为 Win32 GUI 程序而非控制台程序(仅 Windows) |
|
||||
|
||||
### frankenphp 专用选项 {#frankenphp-options}
|
||||
|
||||
@@ -143,6 +142,13 @@ spc build:php <extensions> [options]
|
||||
| `--dl-custom-url=<src:url>` | 覆盖指定源的下载地址 |
|
||||
| `--dl-custom-git=<src:branch:url>` | 覆盖为自定义 git 仓库 |
|
||||
|
||||
Downloader 选项传递给 `build:php` 命令时,会被自动下载器在构建前使用。
|
||||
这样你就可以直接通过构建命令控制下载行为,无需单独执行 `spc download` 命令。
|
||||
|
||||
```bash
|
||||
spc build:php "bcmath,openssl,curl" --build-cli --dl-with-php=8.3 --dl-prefer-binary --dl-parallel=4
|
||||
```
|
||||
|
||||
### 示例
|
||||
|
||||
```bash
|
||||
@@ -177,6 +183,42 @@ spc build:php-embed "bcmath,openssl"
|
||||
spc build:frankenphp "bcmath,openssl,curl" --enable-zts
|
||||
```
|
||||
|
||||
## build:libs
|
||||
|
||||
从源码构建一个或多个库包。
|
||||
|
||||
```bash
|
||||
spc build:libs <libraries> [options]
|
||||
```
|
||||
|
||||
`libraries`(必填):要构建的库包名称列表,逗号分隔(如 `"openssl,curl,zlib"`)。
|
||||
|
||||
支持所有 `download` 命令的选项,加 `--dl-` 前缀传递。
|
||||
|
||||
### 选项
|
||||
|
||||
| 选项 | 缩写 | 说明 |
|
||||
|---|---|---|
|
||||
| `--with-suggests` | `-L`、`-E` | 同时解析并安装建议包 |
|
||||
| `--with-packages=<list>` | | 额外安装的包,逗号分隔 |
|
||||
| `--no-download` | | 跳过下载步骤(使用已有缓存) |
|
||||
|
||||
### 示例
|
||||
|
||||
```bash
|
||||
# 构建单个库
|
||||
spc build:libs openssl
|
||||
|
||||
# 构建多个库
|
||||
spc build:libs "openssl,curl,zlib"
|
||||
|
||||
# 构建时包含建议包
|
||||
spc build:libs openssl --with-suggests
|
||||
|
||||
# 跳过下载步骤
|
||||
spc build:libs openssl --no-download
|
||||
```
|
||||
|
||||
## craft
|
||||
|
||||
读取 `craft.yml` 并自动完成全流程构建。
|
||||
@@ -195,10 +237,10 @@ spc craft [path/to/craft.yml]
|
||||
spc doctor [--auto-fix[=never]]
|
||||
```
|
||||
|
||||
| 选项 | 说明 |
|
||||
|---|---|
|
||||
| `--auto-fix` | 自动修复检测到的问题(使用系统包管理器)|
|
||||
| `--auto-fix=never` | 仅报告问题,不尝试自动修复 |
|
||||
| 选项 | 说明 |
|
||||
|--------------------|----------------------|
|
||||
| `--auto-fix` | 自动修复检测到的问题(使用系统包管理器) |
|
||||
| `--auto-fix=never` | 仅报告问题,不尝试自动修复 |
|
||||
|
||||
## dev:shell
|
||||
|
||||
@@ -210,3 +252,271 @@ spc dev:shell
|
||||
|
||||
可用于在 embed SAPI 的 `libphp.a` 上编译小型 C 程序,或手动检查构建环境。
|
||||
|
||||
## check-update
|
||||
|
||||
检查指定制品是否有可用更新。
|
||||
|
||||
```bash
|
||||
spc check-update [artifact] [options]
|
||||
```
|
||||
|
||||
`artifact`(可选):要检查更新的制品名称,逗号分隔。默认检查所有已下载的制品。
|
||||
|
||||
### 选项
|
||||
|
||||
| 选项 | 缩写 | 说明 |
|
||||
|---|---|---|
|
||||
| `--json` | | 以 JSON 格式输出结果 |
|
||||
| `--bare` | | 检查时不要求制品已下载(旧版本显示为 null)|
|
||||
| `--parallel=<n>` | `-p` | 并行检查数(默认 `10`)|
|
||||
| `--with-php=<ver>` | | PHP 版本上下文,格式为 `major.minor`(默认 `8.4`)|
|
||||
|
||||
### 示例
|
||||
|
||||
```bash
|
||||
# 检查所有已下载制品
|
||||
spc check-update
|
||||
|
||||
# 检查指定制品
|
||||
spc check-update "openssl,curl"
|
||||
|
||||
# 以 JSON 格式输出
|
||||
spc check-update --json
|
||||
|
||||
# 无需先下载即可检查
|
||||
spc check-update "openssl" --bare
|
||||
```
|
||||
|
||||
## dump-extensions
|
||||
|
||||
从 Composer 项目中分析所需的 PHP 扩展列表。
|
||||
|
||||
```bash
|
||||
spc dump-extensions [path] [options]
|
||||
```
|
||||
|
||||
`path`(可选):项目根目录路径,默认为当前目录(`.`)。
|
||||
|
||||
### 选项
|
||||
|
||||
| 选项 | 缩写 | 说明 |
|
||||
|---|---|---|
|
||||
| `--format=<fmt>` | `-F` | 输出格式(默认 `default`)|
|
||||
| `--no-ext-output=<list>` | `-N` | 未找到扩展时输出的默认组合(逗号分隔),而不是以失败退出 |
|
||||
| `--no-dev` | | 不包含 dev 依赖 |
|
||||
| `--no-spc-filter` | `-S` | 不使用 SPC 过滤器筛选扩展 |
|
||||
|
||||
### 示例
|
||||
|
||||
```bash
|
||||
# 分析当前目录的 Composer 项目
|
||||
spc dump-extensions
|
||||
|
||||
# 分析指定目录
|
||||
spc dump-extensions /path/to/project
|
||||
|
||||
# 不包含 dev 依赖
|
||||
spc dump-extensions --no-dev
|
||||
|
||||
# 未找到扩展时输出默认组合
|
||||
spc dump-extensions --no-ext-output="bcmath,openssl"
|
||||
```
|
||||
|
||||
## dump-license
|
||||
|
||||
导出制品的开源许可证文件。
|
||||
|
||||
```bash
|
||||
spc dump-license [artifacts] [options]
|
||||
```
|
||||
|
||||
`artifacts`(可选):要导出许可证的制品名称,逗号分隔(如 `"php-src,openssl,curl"`)。
|
||||
|
||||
### 选项
|
||||
|
||||
| 选项 | 缩写 | 说明 |
|
||||
|---|---|---|
|
||||
| `--for-extensions=<list>` | `-e` | 按扩展名导出(自动包含 php-src),如 `"openssl,mbstring"` |
|
||||
| `--for-libs=<list>` | `-l` | 按库名导出,如 `"openssl,zlib"` |
|
||||
| `--for-packages=<list>` | `-p` | 按包名导出,如 `"php,libssl"` |
|
||||
| `--dump-dir=<path>` | `-d` | 许可证输出目录(默认 `buildroot/license`)|
|
||||
| `--without-suggests` | | 不包含建议包的许可证 |
|
||||
|
||||
### 示例
|
||||
|
||||
```bash
|
||||
# 按扩展名导出许可证
|
||||
spc dump-license --for-extensions="bcmath,openssl,curl"
|
||||
|
||||
# 导出指定制品的许可证
|
||||
spc dump-license "php-src,openssl"
|
||||
|
||||
# 指定输出目录
|
||||
spc dump-license --for-extensions="bcmath,openssl" --dump-dir=/tmp/licenses
|
||||
```
|
||||
|
||||
## extract
|
||||
|
||||
将已下载的制品解压到对应的目标位置。
|
||||
|
||||
```bash
|
||||
spc extract [artifacts] [options]
|
||||
```
|
||||
|
||||
`artifacts`(可选):要解压的制品名称,逗号分隔(如 `"php-src,openssl,curl"`)。
|
||||
|
||||
### 选项
|
||||
|
||||
| 选项 | 缩写 | 说明 |
|
||||
|---|---|---|
|
||||
| `--for-extensions=<list>` | `-e` | 按扩展名解压所需制品,如 `"openssl,mbstring"` |
|
||||
| `--for-libs=<list>` | `-l` | 按库名解压所需制品,如 `"libcares,openssl"` |
|
||||
| `--for-packages=<list>` | | 按包名解压所需制品,如 `"php,libssl,libcurl"` |
|
||||
| `--without-suggests` | | 使用 `--for-extensions` 时跳过建议包 |
|
||||
| `--source-only` | | 强制解压源码,即使已有预编译二进制 |
|
||||
|
||||
### 示例
|
||||
|
||||
```bash
|
||||
# 按扩展名解压
|
||||
spc extract --for-extensions="bcmath,openssl,curl"
|
||||
|
||||
# 解压指定制品
|
||||
spc extract "php-src,openssl"
|
||||
|
||||
# 强制解压源码
|
||||
spc extract --for-extensions="bcmath,openssl" --source-only
|
||||
```
|
||||
|
||||
## install-pkg
|
||||
|
||||
安装额外的辅助包(如 UPX、工具链等)。别名:`i`、`install-package`。
|
||||
|
||||
```bash
|
||||
spc install-pkg <package> [options]
|
||||
```
|
||||
|
||||
`package`(必填):要安装的包名称。
|
||||
|
||||
支持所有 `download` 命令的选项,加 `--dl-` 前缀传递。
|
||||
|
||||
### 示例
|
||||
|
||||
```bash
|
||||
# 安装 UPX 压缩工具
|
||||
spc install-pkg upx
|
||||
|
||||
# 安装时优先使用预编译二进制(默认行为)
|
||||
spc install-pkg upx
|
||||
```
|
||||
|
||||
## micro:combine
|
||||
|
||||
将 `micro.sfx` 与 PHP/PHAR 文件合并为独立可执行文件。
|
||||
|
||||
```bash
|
||||
spc micro:combine <file> [options]
|
||||
```
|
||||
|
||||
`file`(必填):要合并的 PHP 或 PHAR 文件路径。
|
||||
|
||||
### 选项
|
||||
|
||||
| 选项 | 缩写 | 说明 |
|
||||
|---|---|---|
|
||||
| `--with-micro=<path>` | `-M` | 指定自定义 `micro.sfx` 文件路径(默认使用 `buildroot/bin/micro.sfx`)|
|
||||
| `--with-ini-set=<k=v>` | `-I` | 合并时注入 INI 配置(可重复使用)|
|
||||
| `--with-ini-file=<path>` | `-N` | 合并时注入 INI 文件 |
|
||||
| `--output=<name>` | `-O` | 自定义输出文件名(默认 `my-app`)|
|
||||
|
||||
### 示例
|
||||
|
||||
```bash
|
||||
# 合并 PHP 文件
|
||||
spc micro:combine app.php
|
||||
|
||||
# 合并 PHAR 文件并指定输出名
|
||||
spc micro:combine app.phar --output my-app
|
||||
|
||||
# 注入 INI 配置
|
||||
spc micro:combine app.php -I "memory_limit=512M" -I "disable_functions=system"
|
||||
|
||||
# 注入 INI 文件
|
||||
spc micro:combine app.php --with-ini-file=custom.ini
|
||||
|
||||
# 使用自定义 micro.sfx
|
||||
spc micro:combine app.php --with-micro=/path/to/micro.sfx
|
||||
```
|
||||
|
||||
## reset
|
||||
|
||||
清理构建目录,重置构建环境。
|
||||
|
||||
```bash
|
||||
spc reset [options]
|
||||
```
|
||||
|
||||
默认清理 `buildroot/` 和 `source/` 目录。
|
||||
|
||||
### 选项
|
||||
|
||||
| 选项 | 缩写 | 说明 |
|
||||
|---|---|---|
|
||||
| `--with-pkgroot` | | 同时删除 `pkgroot/` 目录 |
|
||||
| `--with-download` | | 同时删除 `downloads/` 目录 |
|
||||
| `--yes` | `-y` | 跳过确认提示 |
|
||||
|
||||
### 示例
|
||||
|
||||
```bash
|
||||
# 清理构建目录(会提示确认)
|
||||
spc reset
|
||||
|
||||
# 同时清理下载缓存
|
||||
spc reset --with-download
|
||||
|
||||
# 完全清理(不提示)
|
||||
spc reset --with-pkgroot --with-download --yes
|
||||
```
|
||||
|
||||
## spc-config
|
||||
|
||||
输出静态编译所需的编译器和链接器标志,适用于将 PHP embed 库链接到自定义程序。
|
||||
|
||||
```bash
|
||||
spc spc-config [extensions] [options]
|
||||
```
|
||||
|
||||
`extensions`(可选):要包含的扩展名列表,逗号分隔。
|
||||
|
||||
### 选项
|
||||
|
||||
| 选项 | 缩写 | 说明 |
|
||||
|---|---|---|
|
||||
| `--with-libs=<list>` | | 额外包含的库,逗号分隔 |
|
||||
| `--with-packages=<list>` | `-p` | 额外包含的包,逗号分隔 |
|
||||
| `--with-suggested-libs` | `-L` | 包含建议库 |
|
||||
| `--with-suggests` | | 包含所有建议包 |
|
||||
| `--with-suggested-exts` | `-E` | 包含建议扩展 |
|
||||
| `--includes` | | 仅输出 `-I` 头文件路径(`CFLAGS`)|
|
||||
| `--libs` | | 仅输出 `-L` 和 `-l` 链接标志(`LDFLAGS + LIBS`)|
|
||||
| `--libs-only-deps` | | 仅输出依赖库的 `-l` 标志 |
|
||||
| `--absolute-libs` | | 使用库文件的绝对路径输出 |
|
||||
| `--no-php` | | 不链接 PHP 库 |
|
||||
|
||||
### 示例
|
||||
|
||||
```bash
|
||||
# 输出完整编译标志
|
||||
spc spc-config "bcmath,openssl,curl"
|
||||
|
||||
# 仅输出头文件路径
|
||||
spc spc-config "bcmath,openssl" --includes
|
||||
|
||||
# 仅输出链接标志
|
||||
spc spc-config "bcmath,openssl" --libs
|
||||
|
||||
# 使用绝对路径
|
||||
spc spc-config "bcmath,openssl" --libs --absolute-libs
|
||||
```
|
||||
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
---
|
||||
aside: false
|
||||
---
|
||||
|
||||
# 依赖关系图
|
||||
|
||||
<!-- TODO: 由 `bin/spc dev:gen-ext-dep-docs` 和 `dev:gen-lib-dep-docs` 自动生成。v3 命令实现后填充。 -->
|
||||
这里列出了所有支持的包(扩展、库)及其依赖关系。
|
||||
|
||||
- **必需依赖**:构建该包时会强制一同构建的包。
|
||||
- **可选依赖**:默认不构建,使用 `--with-suggests` 参数可启用,或在构建命令中手动指定。
|
||||
- **被依赖**:其他哪些包需要当前包。
|
||||
|
||||
运行以下命令生成依赖数据(需要在源码模式下):
|
||||
|
||||
```bash
|
||||
bin/spc dev:gen-deps-data
|
||||
```
|
||||
|
||||
<DepsMap />
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"docs:preview": "vitepress preview docs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mermaid": "^11.0.0",
|
||||
"vitepress": "^2.0.0-alpha.5",
|
||||
"vue": "^3.2.47"
|
||||
}
|
||||
|
||||
95
src/StaticPHP/Command/Dev/GenDepsDataCommand.php
Normal file
95
src/StaticPHP/Command/Dev/GenDepsDataCommand.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace StaticPHP\Command\Dev;
|
||||
|
||||
use StaticPHP\Command\BaseCommand;
|
||||
use StaticPHP\Config\PackageConfig;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
|
||||
#[AsCommand('dev:gen-deps-data', 'Generate package dependency data JSON for documentation', [], true)]
|
||||
class GenDepsDataCommand extends BaseCommand
|
||||
{
|
||||
private const PLATFORMS = ['linux', 'macos', 'windows'];
|
||||
|
||||
protected bool $no_motd = true;
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
if (!spc_mode(SPC_MODE_SOURCE)) {
|
||||
$this->output->writeln('<error>This command is only available in source mode.</error>');
|
||||
return static::USER_ERROR;
|
||||
}
|
||||
|
||||
$all = PackageConfig::getAll();
|
||||
$packages = [];
|
||||
|
||||
foreach ($all as $pkg_name => $config) {
|
||||
$type = $config['type'] ?? 'unknown';
|
||||
|
||||
// Build platform-specific dep/suggest data
|
||||
$platforms = [];
|
||||
foreach (self::PLATFORMS as $platform) {
|
||||
$platforms[$platform] = [
|
||||
'depends' => $this->resolvePlatformList($config, 'depends', $platform),
|
||||
'suggests' => $this->resolvePlatformList($config, 'suggests', $platform),
|
||||
];
|
||||
}
|
||||
|
||||
$entry = [
|
||||
'type' => $type,
|
||||
'platforms' => $platforms,
|
||||
];
|
||||
|
||||
// For php-extension, add OS support info
|
||||
if ($type === 'php-extension') {
|
||||
$os_list = $config['php-extension']['os'] ?? null;
|
||||
if ($os_list !== null) {
|
||||
$entry['os'] = $os_list;
|
||||
}
|
||||
}
|
||||
|
||||
$packages[$pkg_name] = $entry;
|
||||
}
|
||||
|
||||
// Sort by type then name for readability
|
||||
uksort($packages, function ($a, $b) use ($packages) {
|
||||
$ta = $packages[$a]['type'];
|
||||
$tb = $packages[$b]['type'];
|
||||
if ($ta !== $tb) {
|
||||
return strcmp($ta, $tb);
|
||||
}
|
||||
return strcmp($a, $b);
|
||||
});
|
||||
|
||||
$output_data = [
|
||||
'generated_at' => date('c'),
|
||||
'packages' => $packages,
|
||||
];
|
||||
|
||||
$output_path = ROOT_DIR . '/docs/.vitepress/deps-data.json';
|
||||
file_put_contents($output_path, json_encode($output_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL);
|
||||
|
||||
$this->output->writeln('<info>Generated ' . $output_path . ' with ' . count($packages) . ' packages.</info>');
|
||||
return static::SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the value of a platform-specific array field, applying the suffix fallback chain.
|
||||
*
|
||||
* Fallback rules (same as PackageConfig::get):
|
||||
* linux : @linux → @unix → (base)
|
||||
* macos : @macos → @unix → (base)
|
||||
* windows : @windows → (base)
|
||||
*/
|
||||
private function resolvePlatformList(array $config, string $field, string $platform): array
|
||||
{
|
||||
return match ($platform) {
|
||||
'linux' => $config["{$field}@linux"] ?? $config["{$field}@unix"] ?? $config[$field] ?? [],
|
||||
'macos' => $config["{$field}@macos"] ?? $config["{$field}@unix"] ?? $config[$field] ?? [],
|
||||
'windows' => $config["{$field}@windows"] ?? $config[$field] ?? [],
|
||||
default => $config[$field] ?? [],
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ use StaticPHP\Command\CraftCommand;
|
||||
use StaticPHP\Command\Dev\DumpCapabilitiesCommand;
|
||||
use StaticPHP\Command\Dev\DumpStagesCommand;
|
||||
use StaticPHP\Command\Dev\EnvCommand;
|
||||
use StaticPHP\Command\Dev\GenDepsDataCommand;
|
||||
use StaticPHP\Command\Dev\GenExtDocsCommand;
|
||||
use StaticPHP\Command\Dev\IsInstalledCommand;
|
||||
use StaticPHP\Command\Dev\LintConfigCommand;
|
||||
@@ -83,6 +84,7 @@ class ConsoleApplication extends Application
|
||||
new DumpCapabilitiesCommand(),
|
||||
new PackageInfoCommand(),
|
||||
new GenExtDocsCommand(),
|
||||
new GenDepsDataCommand(),
|
||||
]);
|
||||
|
||||
// add additional commands from registries
|
||||
|
||||
Reference in New Issue
Block a user