포스트

코드 project 내에서 코드 트리구조를 text, json, markdown로 생성하기(dart 코드)

이전 파이썬 코드 버전을 보실 분들은..

[20241212] 코드 project 내에서 코드를 트리구조로 한 파일에 생성하기(python 코드) (2) 지난 게시글에서는 코드 프로젝트의 각 파일의 경로를 모두 모아서 텍스트 파일로 모아서 보는 코드를 작성… 지난 게시글에서는 코드 프로젝트의 각 파일의 경로를 모두 모아서 텍스트 파일로 모아서 보는 코드를 작성…

dart 코드로 재작성한 코드는 다음과 같습니다.

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
/// collect_tree.dart
import 'package:args/args.dart';
import 'dart:io';

void writeFileTreeWithTopFolder(
    String rootFolder, String outputFile, String type) async {
  // 최상위 폴더 이름 가져오기
  final normalizedRoot = rootFolder.replaceAll(r'\', '/').replaceAll(RegExp(r'/$'), '');
  final rootFolderName = normalizedRoot.split('/').last;

  // 출력 파일 열기
  final output = File(outputFile);
  final sink = output.openWrite();

  try {
    // 디렉토리 순회
    final directory = Directory(rootFolder);
    if (!await directory.exists()) {
      print('Error: Root folder does not exist: $rootFolder');
      return;
    }

    await for (final entity
        in directory.list(recursive: true, followLinks: false)) {
      if (entity is File && entity.path.endsWith('.$type')) {
        // 상대 경로 계산
        final relativePath = entity.parent.path
            .replaceFirst(rootFolder, '')
            .replaceAll(r'\', '/')
            .replaceFirst(RegExp(r'^/'), ''); // 선행 슬래시 제거

        // 최상위 폴더 이름 포함 경로
        final formattedPath =
            '$rootFolderName/${relativePath.isEmpty ? '' : relativePath}';

        // 파일 이름 추출
        final fileName = entity.uri.pathSegments.last;

        // 출력 내용 작성
        sink.writeln('$formattedPath: $fileName');
      }
    }
    print('$outputFile 파일이 생성되었습니다.');
  } catch (e) {
    print('Error: $e');
  } finally {
    await sink.close();
  }
}

// 메인 함수
void main(List arguments) {
  // 기본 경로 및 옵션
  const defaultPath =
      r'C:\Users\devra\StudioProjects\폴더';
  const defaultOutput = '_dev/dart_file_tree.txt';
  const defaultType = 'dart';

  // 명령줄 인자 파싱
  final parser = ArgParser()
    ..addOption('path',
        abbr: 'p',
        defaultsTo: defaultPath,
        help: 'The root folder to scan.')
    ..addOption('output',
        abbr: 'o',
        defaultsTo: defaultOutput,
        help: 'The output file to write the tree.')
    ..addOption('type',
        abbr: 't', defaultsTo: defaultType, help: 'The file type to scan.');

  final args = parser.parse(arguments);

  final rootFolder = args['path'];
  final outputFile = args['output'];
  final type = args['type'];

  writeFileTreeWithTopFolder(rootFolder, outputFile, type);
}

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
/// convert_file_tree.dart
import 'dart:io';
import 'dart:convert';

/// 트리 구조를 빌드하는 함수
Map buildTree(List filePaths) {
  final Map tree = {};

  for (final path in filePaths) {
    final parts = path.split(r'\');
    Map current = tree;

    for (int i = 0; i  {});
    }

    current[parts.last] = null; // 파일은 null 값으로 추가
  }

  return tree;
}

/// 트리를 JSON 파일로 저장
void saveTreeAsJson(Map tree, String filePath) {
  final jsonContent = JsonEncoder.withIndent('    ').convert(tree);
  final file = File(filePath);
  file.writeAsStringSync(jsonContent, encoding: utf8);
}

/// 트리를 Markdown 형식으로 저장
void saveTreeAsMarkdown(Map tree, String filePath) {
  final file = File(filePath);
  final sink = file.openWrite();

  sink.writeln('```'); // Markdown 코드 블록 시작
  _writeMarkdown(tree, sink);
  sink.writeln('```'); // Markdown 코드 블록 끝

  sink.close();
}

/// Markdown 형식으로 트리를 출력
void _writeMarkdown(Map tree, IOSink sink, {String prefix = '', bool isRoot = true}) {
  final entries = tree.entries.toList();
  for (int i = 0; i  ? '/' : ''; // 디렉토리는 /로 끝냄

    // 현재 항목 출력
    sink.writeln('$prefix$connector${entries[i].key}$suffix');

    // 하위 디렉토리 순회
    if (entries[i].value is Map) {
      final newPrefix = isRoot ? "" : prefix + (isLast ? '    ' : '│   '); // 들여쓰기 계산
      _writeMarkdown(entries[i].value as Map, sink, prefix: newPrefix, isRoot: false);
    }
  }
}

/// 트리를 콘솔에 출력
void printTree(Map tree, [String prefix = '', bool isRoot = true]) {
  final entries = tree.entries.toList();
  for (int i = 0; i ) {
      final extension = i == entries.length - 1 ? '    ' : '│   ';
      printTree(entries[i].value as Map, '$prefix$extension', false);
    }
  }
}

void main() async {
  // `dart_file_tree.txt`에서 파일 경로 읽기
  final filePaths = [];
  final inputFile = File('_dev/dart_file_tree.txt');

  if (!await inputFile.exists()) {
    print('Error: Input file not found.');
    return;
  }

  final lines = await inputFile.readAsLines(encoding: utf8);
  for (final line in lines) {
    final trimmedLine = line.trim();
    if (trimmedLine.contains(': ')) {
      final parts = trimmedLine.split(': ');
      final base = parts[0].replaceAll('/', r'\'); // 경로 형식 통일
      final fileName = parts[1];
      filePaths.add('$base\\$fileName');
    }
  }

  // 트리 생성
  final tree = buildTree(filePaths);

  // 트리 출력
  printTree(tree);

  // JSON 저장
  saveTreeAsJson(tree, '_dev/dart_file_tree.json');
  print('JSON 파일로 저장되었습니다.');

  // Markdown 저장
  saveTreeAsMarkdown(tree, '_dev/dart_file_tree.md');
  print('Markdown 파일로 저장되었습니다.');
}

pubspec.yaml

1
2
dependencies:
  args: ^2.6.0

sticker

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.