|  | 
|  | 1 | +import * as fs from 'node:fs' | 
|  | 2 | +import * as path from 'node:path' | 
|  | 3 | +import * as prettier from 'prettier' | 
|  | 4 | + | 
|  | 5 | +/** Pairs of package labels and their corresponding paths */ | 
|  | 6 | +type LabelerPair = [string, string] | 
|  | 7 | + | 
|  | 8 | +function readPairsFromFs(): Array<LabelerPair> { | 
|  | 9 | +  const ignored = new Set(['.DS_Store']) | 
|  | 10 | + | 
|  | 11 | +  const pairs: Array<LabelerPair> = [] | 
|  | 12 | + | 
|  | 13 | +  // Add subfolders in the packages folder, i.e. packages/** | 
|  | 14 | +  fs.readdirSync(path.resolve('packages')) | 
|  | 15 | +    .filter((folder) => !ignored.has(folder)) | 
|  | 16 | +    .forEach((folder) => { | 
|  | 17 | +      // Check if package.json exists for the folder before adding it | 
|  | 18 | +      if ( | 
|  | 19 | +        fs.existsSync( | 
|  | 20 | +          path.resolve(path.join('packages', folder, 'package.json')), | 
|  | 21 | +        ) | 
|  | 22 | +      ) { | 
|  | 23 | +        pairs.push([`package: ${folder}`, `packages/${folder}/**/*`]) | 
|  | 24 | +      } else { | 
|  | 25 | +        console.info( | 
|  | 26 | +          `Skipping \`${folder}\` as it does not have a \`package.json\` file.`, | 
|  | 27 | +        ) | 
|  | 28 | +      } | 
|  | 29 | +    }) | 
|  | 30 | + | 
|  | 31 | +  // Sort by package name in alphabetical order | 
|  | 32 | +  pairs.sort((a, b) => a[0].localeCompare(b[0])) | 
|  | 33 | + | 
|  | 34 | +  return pairs | 
|  | 35 | +} | 
|  | 36 | + | 
|  | 37 | +async function generateLabelerYaml(pairs: Array<LabelerPair>): Promise<string> { | 
|  | 38 | +  function s(n = 1) { | 
|  | 39 | +    return ' '.repeat(n) | 
|  | 40 | +  } | 
|  | 41 | + | 
|  | 42 | +  // Convert the pairs into valid yaml | 
|  | 43 | +  const formattedPairs = pairs | 
|  | 44 | +    .map(([packageLabel, packagePath]) => { | 
|  | 45 | +      const result = [ | 
|  | 46 | +        `'${packageLabel}':`, | 
|  | 47 | +        `${s(2)}-${s(1)}changed-files:`, | 
|  | 48 | +        `${s(4)}-${s(1)}any-glob-to-any-file:${s(1)}'${packagePath}'`, | 
|  | 49 | +      ].join('\n') | 
|  | 50 | + | 
|  | 51 | +      return result | 
|  | 52 | +    }) | 
|  | 53 | +    .join('\n') | 
|  | 54 | + | 
|  | 55 | +  // Get the location of the Prettier config file | 
|  | 56 | +  const prettierConfigPath = await prettier.resolveConfigFile() | 
|  | 57 | +  if (!prettierConfigPath) { | 
|  | 58 | +    throw new Error( | 
|  | 59 | +      'No Prettier config file found. Please ensure you have a Prettier config file in your project.', | 
|  | 60 | +    ) | 
|  | 61 | +  } | 
|  | 62 | +  console.info('using prettier config file at:', prettierConfigPath) | 
|  | 63 | + | 
|  | 64 | +  // Resolve the Prettier config | 
|  | 65 | +  const prettierConfig = await prettier.resolveConfig(prettierConfigPath) | 
|  | 66 | +  console.info('using resolved prettier config:', prettierConfig) | 
|  | 67 | + | 
|  | 68 | +  // Format the YAML string using Prettier | 
|  | 69 | +  const formattedStr = await prettier.format(formattedPairs, { | 
|  | 70 | +    parser: 'yaml', | 
|  | 71 | +    ...prettierConfig, | 
|  | 72 | +  }) | 
|  | 73 | + | 
|  | 74 | +  return formattedStr | 
|  | 75 | +} | 
|  | 76 | + | 
|  | 77 | +async function run() { | 
|  | 78 | +  console.info('Generating labeler config...') | 
|  | 79 | + | 
|  | 80 | +  // Generate the pairs of package labels and their corresponding paths | 
|  | 81 | +  const pairs = readPairsFromFs() | 
|  | 82 | + | 
|  | 83 | +  // Always add the docs folder | 
|  | 84 | +  pairs.push(['documentation', 'docs/**/*']) | 
|  | 85 | + | 
|  | 86 | +  // Convert the pairs into valid yaml | 
|  | 87 | +  const yamlStr = await generateLabelerYaml(pairs) | 
|  | 88 | + | 
|  | 89 | +  // Write to 'labeler-config.yml' | 
|  | 90 | +  const configPath = path.resolve('labeler-config.yml') | 
|  | 91 | +  fs.writeFileSync(configPath, yamlStr, { | 
|  | 92 | +    encoding: 'utf-8', | 
|  | 93 | +  }) | 
|  | 94 | + | 
|  | 95 | +  console.info(`Generated labeler config at \`${configPath}\`!`) | 
|  | 96 | +  return | 
|  | 97 | +} | 
|  | 98 | + | 
|  | 99 | +try { | 
|  | 100 | +  run().then(() => { | 
|  | 101 | +    process.exit(0) | 
|  | 102 | +  }) | 
|  | 103 | +} catch (error) { | 
|  | 104 | +  console.error('Error generating labeler config:', error) | 
|  | 105 | +  process.exit(1) | 
|  | 106 | +} | 
0 commit comments