} dev 가 null 이면 판정 불가 * (파일 부재 · JSON 오류 · Composer 1 형식) */ public static function inspect(string $vendorPath): array { $unknown = ['dev' => null, 'packages' => []]; $path = rtrim($vendorPath, '/\\').'/'.self::INSTALLED_JSON; if (! is_file($path)) { return $unknown; } $raw = @file_get_contents($path); if ($raw === false || $raw === '') { return $unknown; } $decoded = json_decode($raw, true); // Composer 1 은 최상위가 패키지 배열이라 dev 정보 자체가 없다 — 판정 불가로 둔다. if (! is_array($decoded) || ! array_key_exists('packages', $decoded)) { return $unknown; } $names = []; if (isset($decoded['dev-package-names']) && is_array($decoded['dev-package-names'])) { foreach ($decoded['dev-package-names'] as $name) { if (is_string($name) && trim($name) !== '') { $names[] = $name; } } } $devFlag = $decoded['dev'] ?? null; return [ 'dev' => $devFlag === true || $names !== [], 'packages' => $names, ]; } /** * vendor 가 개발용 설치인지 반환합니다. * * @param string $vendorPath vendor 디렉토리 절대 경로 * @return bool|null 판정 불가 시 null */ public static function isDevInstall(string $vendorPath): ?bool { return self::inspect($vendorPath)['dev']; } /** * vendor 에 설치된 개발용(require-dev) 패키지 이름 목록을 반환합니다. * * @param string $vendorPath vendor 디렉토리 절대 경로 * @return array 개발용 패키지가 없거나 판정 불가면 빈 배열 */ public static function devPackageNames(string $vendorPath): array { return self::inspect($vendorPath)['packages']; } }