Skip to content

Instantly share code, notes, and snippets.

@taverasmisael
Created November 12, 2022 14:09
Show Gist options
  • Save taverasmisael/e790fbd833f076e14200261f98593488 to your computer and use it in GitHub Desktop.
Save taverasmisael/e790fbd833f076e14200261f98593488 to your computer and use it in GitHub Desktop.
Simple and non-recursive way to rename index files on a directory to have the same name as the directory it is in
import path from 'path'
import fs from 'fs'
const cwd = path.resolve('[YOUR DIR]')
const dirs = fs.readdirSync(cwd)
const isFile = (baseDir: string) => (dir: string) =>
fs.lstatSync(path.join(baseDir, dir)).isFile()
const and =
<T>(...args: ((v: T) => boolean)[]) =>
(v: T): boolean =>
args.reduce((a, b) => a && b(v), true)
const files = dirs.reduce((acc, dir) => {
const currentPath = path.join(cwd, dir)
const stats = fs.lstatSync(currentPath)
if (stats.isDirectory()) {
// we just want the first level
const indexFile = fs
.readdirSync(currentPath)
.find(
and(
isFile(currentPath),
(name: string) => name.split('.')[0] === 'index'
)
)
if (!indexFile) {
// skip directories without index files.
return acc
}
return { ...acc, [dir]: indexFile }
}
return acc
}, {} as Record<string, string>) //?
const entries = Object.entries(files) //? $.length
const rename = (entries: [string, string][]) =>
entries.forEach(([dir, name]) => {
const oldName = path.join(cwd, dir, name)
const newName = path.join(cwd, dir, `${dir}${path.extname(name)}`)
fs.renameSync(oldName, newName)
})
// rename(entries) // Uncomment this and see the magic happen
@taverasmisael
Copy link
Author

This snippet assumes an astro content collection type of thing.

const fs = require('fs')
const path = require('path')

function moveMDFiles(root: string, newDir: string) {
  const dirs = fs.readdirSync(root).filter((d) => !['media', 'es', 'config.ts'].includes(d)) 
  const res = dirs.reduce((acc, dir) => {
    const currentPath = path.join(root, dir)

    if (fs.lstatSync(currentPath).isDirectory()) {
      const files = fs.readdirSync(currentPath)
      const mediaFiles = getMediaFiles(path.join(currentPath, 'media'))
      const post = path.join(
        currentPath,
        files.find((f) => ['.md', '.mdx'].includes(path.extname(f)))
      )
      return [
        ...acc,
        {
          post,
          mediaFiles,
        },
      ]
    }

    return acc
  }, [])

  function getMediaFiles(dir: string) {
    const mediaFiles = fs.readdirSync(dir)
    return mediaFiles.map((f) => path.join(dir, f))
  }


  res.forEach((entry) => {
    const { post, mediaFiles } = entry
    const postPath = path.basename(post) //?
    fs.renameSync(post, path.resolve(newDir, postPath))
    mediaFiles.forEach((mediaFile) => {
      const parsedMediaPath = path.parse(mediaFile)
      const mediaFileName = parsedMediaPath.name === 'banner' ? `banner-${path.parse(postPath).name}` : parsedMediaPath.name
      const mediaPath = `${mediaFileName}${parsedMediaPath.ext}`
      fs.renameSync(mediaFile, path.resolve(root, 'media', mediaPath)) // media will ignore newDir. I did this because I was adding i18n, and wanted the media to be global instead of per language. The future will tell if this was good or bad
    })
  })
}

const oldDir = path.resolve(__dirname, 'YOUR_DIR')
const newDir = path.resolve(__dirname, 'YOUR_NEW_DIR')

moveMDFiles(oldDir, newDir)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment