1

I'm using the Github API and Python to attempt to generate a file structure in a repository, but the directories aren't forming correctly. To authenticate and create the repository, I'm using the Github library, and the create_file_structure function to construct the file structure, which is passed as a string. This function is designed to parse the string, and using the create_file function, create the files and directories in the repository. Unfortunately, the code is interpreting all the lines in the file structure incorrectly, instead of creating the accurate appropriate directories.

I'm not sure what's causing the issue, but it looks like the create_file_structure function is not correctly identifying the directories in the file structure. I'd appreciate any help in understanding what's going wrong and how I can fix it.

I tried running the create_file_structure function and passing it a file structure string, as well as a repo object representing the repository where I want to create the file structure. I expected the function to correctly parse the file structure string and create the appropriate files and directories in the repository.

However, the function is treating all the lines in the file structure string as files, rather than creating the appropriate directories. This is causing the file structure to be created incorrectly, with all the lines being treated as files rather than the correct mix of files and directories.

Here is an example of the file structure I'm trying to create:

dir1/
├── dir2/
│   ├── file1
│   └── file2
└── dir3/
    ├── file3
    ├── file4
    └── dir4/
        └── file5

And here is the output I'm getting:

Successfully created file: dir1
Successfully created file: dir2/dir2
Successfully created file: dir2/file1
Successfully created file: dir2/file2
Successfully created file: dir2/dir3/dir3
Successfully created file: dir2/dir3/file3/file3
Successfully created file: dir2/dir3/file3/file4/file4
Successfully created file: dir2/dir3/file3/file4/dir4/dir4
Successfully created file: dir2/dir3/file3/file4/dir4/file5/file5
Successfully created file structure

Here is the full main.py I'm using:


from github import Github


def create_repository(username, token, repository_name):
  g = Github(username, token)
  repo = g.get_user().create_repo(repository_name)
  print(f"Successfully created repository: {repository_name}")
  return repo


def create_file_structure(repo, file_structure):
  file_structure = file_structure.replace('├──', '|--').replace('└──', '`--')
  lines = file_structure.strip().split('\n')
  current_dir = []
  for line in lines:
    line = line.strip()
    if line.startswith('|--') or line.startswith('`--'):
      if line.endswith('/'): current_dir.append(line[3:].strip())
      else: current_dir.append(line[3:].strip())
    create_file(repo, current_dir, line)
  print('Successfully created file structure')


import re


def create_file(repo, current_dir, filename):
  filename = filename.strip()
  filename = re.sub('[^a-zA-Z0-9.]', '', filename)
  current_dir = [d.rstrip('/') for d in current_dir]
  filename = filename.rstrip('/')
  if current_dir: path = '/'.join(current_dir + [filename])
  else: path = filename
  try:
    repo.create_file(path, 'Initial commit', '')
    print(f"Successfully created file: {path}")
  except Exception as e:
    print(f"Error creating file {path}: {e}")


def main():
  username = input('Enter your GitHub username: ')
  token = input('Enter your GitHub personal access token: ')
  repository_name = input('Enter the repository name: ')
  repo = create_repository(username, token, repository_name)
  lines = []
  while True:
    line = input()
    if line: lines.append(line)
    else: break
  file_structure = '\n'.join(lines)
  create_file_structure(repo, file_structure)


if __name__ == '__main__': main()

1 Answers1

0

To answer your immediate question, in your create_file_structure function, you have the lines:

    if line.startswith('|--') or line.startswith('`--'):
      if line.endswith('/'): current_dir.append(line[3:].strip())
      else: current_dir.append(line[3:].strip())
    create_file(repo, current_dir, line)

In the inner if statement, you check to see if the line ends with '/' which symbolizes a directory and if so, then you add a section of the line variable to the current_dir variable. If not, then you do the same thing (!). So regardless of whether the line symbolizes a directory, you add a section of the line variable to the current_dir variable. Next, you call create_file outside of the if statement, so regardless of whether the line symbolizes a directory, you will create a file from the line variable.

I think what you want to say is, if the line does NOT symbolize a directory, then create a file, for example:

    if not line.endswith('/'): 
        create_file(repo, current_dir, line)

Note that this alone will not make your code generate a file structure in a repository from the input. I think you are using the GitHub API correctly, but your string manipulation code will not work the way you want it to work. Try commenting out the GitHub parts and focus first on debugging your string manipulation code using the Python debugger or more print statements.

You'll have to make at least a few more changes for the string manipulation to work. For example, note that:

  • if line.startswith('|--') or line.startswith('`--') does not capture all lines that are files. The lines for file1 and file2 do not start with these symbols.
  • Your functions will create a file with path dir2/dir3/file3/file3 which is incorrect. Using the characters of line after the first three characters will not work when you have nested directories. Try using recursion and call create_file_structure within create_file_structure but on a substring of the line variable.
Ryan Ly
  • 41
  • 2