amalgomate/astfuncs.go
func removeEmptyDirs(rootDir string) (removed bool, rErr error) {
	dirContent, err := ioutil.ReadDir(rootDir)
	if err != nil {
		return false, errors.Wrapf(err, "failed to read directory")
	}

	removeCurrentDir := true
	for _, fi := range dirContent {
		if !fi.IsDir() {
			// if directory contains non-directory, it will not be removed
			removeCurrentDir = false
			continue
		}
		currChildRemoved, err := removeEmptyDirs(path.Join(rootDir, fi.Name()))
		if err != nil {
			return false, err
		}
		if !currChildRemoved {
			// if a child directory was not removed, it means it was non-empty, so this directory is non-empty
			removeCurrentDir = false
			continue
		}
	}

	if !removeCurrentDir {
		return false, nil
	}
	if err := os.Remove(rootDir); err != nil {
		return false, errors.Wrapf(err, "failed to remove directory")
	}
	return true, nil
}
func removeEmptyDirs(rootDir string) (removed bool, rErr error) {
	dirContent, err := ioutil.ReadDir(rootDir)
	if err != nil {
		return false, errors.Wrapf(err, "failed to read directory")
	}

	removeCurrentDir := true
	for _, fi := range dirContent {
		if !fi.IsDir() {
			// if directory contains non-directory, it will not be removed
			removeCurrentDir = false
			continue
		}
		currChildRemoved, err := removeEmptyDirs(path.Join(rootDir, fi.Name()))
		if err != nil {
			return false, err
		}
		if !currChildRemoved {
			// if a child directory was not removed, it means it was non-empty, so this directory is non-empty
			removeCurrentDir = false
			continue
		}
	}

	if !removeCurrentDir {
		return false, nil
	}
	if err := os.Remove(rootDir); err != nil {
		return false, errors.Wrapf(err, "failed to remove directory")
	}
	return true, nil
}
// removeEmptyDirs removes all directories in rootDir (including the root directory itself) that are empty or contain
// only empty directories.