All files / lib/analyzers cloud-analyzer.js

80% Statements 56/70
65.9% Branches 29/44
40% Functions 2/5
83.33% Lines 55/66

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122          8x               8x 8x 1x 1x     8x 8x 1x 1x     8x 8x         8x 8x 8x 1x       8x 8x 2x 2x 2x 2x 2x           8x 8x 1x 1x       8x 8x 8x 1x 1x       8x 8x 1x 1x 1x   1x 1x 1x   1x     1x             8x 8x 1x 1x 1x     1x 1x           8x 8x                           8x 8x 8x 8x   8x    
import fs from 'fs-extra';
import path from 'path';
import { recursiveGlob } from './utils.js';
 
export async function analyzeCloud(projectPath) {
  const detected = {
    providers: [],
    services: [],
    configFiles: [],
    orchestration: []
  };
 
  // Docker
  const dockerfilePath = path.join(projectPath, 'Dockerfile');
  if (await fs.pathExists(dockerfilePath)) {
    detected.configFiles.push('Dockerfile');
    detected.providers.push('docker');
  }
 
  const composePath = path.join(projectPath, 'docker-compose.yml');
  if (await fs.pathExists(composePath)) {
    detected.configFiles.push('docker-compose.yml');
    detected.providers.push('docker');
  }
 
  const dockerignorePath = path.join(projectPath, '.dockerignore');
  Iif (await fs.pathExists(dockerignorePath)) {
    detected.configFiles.push('.dockerignore');
  }
 
  // Kubernetes
  const k8sDir = path.join(projectPath, 'k8s');
  const helmDir = path.join(projectPath, 'helm');
  if (await fs.pathExists(k8sDir) || await fs.pathExists(helmDir)) {
    detected.orchestration.push('kubernetes');
  }
 
  // Check YAML files for apiVersion
  const yamlFiles = await recursiveGlob(projectPath, '**/*.yaml');
  for (const file of yamlFiles.slice(0, 10)) { // Limit to avoid performance issues
    try {
      const content = await fs.readFile(file, 'utf8');
      Eif (content.includes('apiVersion:')) {
        detected.orchestration.push('kubernetes');
        break;
      }
    } catch (e) {}
  }
 
  // Terraform
  const tfFiles = await recursiveGlob(projectPath, '**/*.tf');
  if (tfFiles.length > 0) {
    detected.configFiles.push(...tfFiles.slice(0, 5)); // limit to 5
    detected.providers.push('terraform');
  }
 
  // Serverless Framework
  const serverlessYml = path.join(projectPath, 'serverless.yml');
  const serverlessYaml = path.join(projectPath, 'serverless.yaml');
  if (await fs.pathExists(serverlessYml) || await fs.pathExists(serverlessYaml)) {
    detected.configFiles.push('serverless.yml');
    detected.providers.push('serverless');
  }
 
  // Package.json → cloud SDKs
  const pkgPath = path.join(projectPath, 'package.json');
  if (await fs.pathExists(pkgPath)) {
    try {
      const pkg = await fs.readJson(pkgPath);
      const deps = { ...pkg.dependencies, ...pkg.devDependencies };
 
      Eif (deps['aws-sdk'] || Object.keys(deps).some(k => k.startsWith('@aws-sdk/'))) {
        detected.providers.push('aws');
        detected.services.push('s3', 'lambda', 'ec2', 'dynamodb');
      }
      Iif (deps['@google-cloud/*'] || deps.firebase) {
        detected.providers.push('gcp');
      }
      Iif (Object.keys(deps).some(k => k.startsWith('@azure/'))) {
        detected.providers.push('azure');
      }
    } catch (e) {}
  }
 
  // Go modules
  const goModPath = path.join(projectPath, 'go.mod');
  if (await fs.pathExists(goModPath)) {
    try {
      const content = await fs.readFile(goModPath, 'utf8');
      Iif (content.includes('github.com/aws/aws-sdk-go')) {
        detected.providers.push('aws');
      }
      Eif (content.includes('cloud.google.com/go')) {
        detected.providers.push('gcp');
      }
    } catch (e) {}
  }
 
  // Python requirements
  const reqPath = path.join(projectPath, 'requirements.txt');
  Iif (await fs.pathExists(reqPath)) {
    try {
      const content = await fs.readFile(reqPath, 'utf8');
      const lines = content.toLowerCase().split('\n');
      if (lines.some(l => l.includes('boto3') || l.includes('aws-'))) {
        detected.providers.push('aws');
      }
      if (lines.some(l => l.includes('google-cloud'))) {
        detected.providers.push('gcp');
      }
    } catch (e) {}
  }
 
  // Deduplicate
  detected.providers = [...new Set(detected.providers)];
  detected.services = [...new Set(detected.services)];
  detected.configFiles = [...new Set(detected.configFiles)];
  detected.orchestration = [...new Set(detected.orchestration)];
 
  return detected;
}