ProjectManager icon indicating copy to clipboard operation
ProjectManager copied to clipboard

Can it detect the projects in some folders automatically?

Open xgfone opened this issue 8 years ago • 9 comments

The plugin of Visual Studio Code, Project Manager, can detect the git or svn projects when i indicate a list of folders. I think it is very intelligent, and this plugin maybe add this feature.

xgfone avatar Mar 14 '17 03:03 xgfone

See if I understand you correctly: right now Project Manager only use the first folder from the sidebar to name the project, you are requesting the feature that using the folder which containing .git or .svn directories if there are multiple folders.

randy3k avatar Mar 14 '17 04:03 randy3k

Yes, but detect the sub-directories of the folders we indicate.

For instance, there are two options, git-folders and svn-folders, in the configuration file as follow.

{
    "git-folders": [
        "/path/to/folder1",
        "/path/to/folder2"
    ],
    "svn-folders": [
        "/path/to/folder3",
        "/path/to/folder4",
    ]
}

In the folder /path/to/folder1, there are two git projects and one plain directory, such as git-11 and git-12 and plain1. Accordingly, /path/to/folder2 has git-21, git-22, git-23 and plain2.

The algorithm is as follows.

  1. Travel the value of git-folders, that's, each given folder in the config.
  2. For each folder, travel all the sub-direcotres, and decide whether it is a git project or not.
  3. If true(yes), convert it to the ST project. Or pass.
  4. Finally, we all get five ST projects, that's,
    • git-11 -> /path/to/folder1/git-11
    • git-12 -> /path/to/folder1/git-12
    • git-21 -> /path/to/folder2/git-21
    • git-22 -> /path/to/folder2/git-22
    • git-23 -> /path/to/folder2/git-23

For SVN, the algorithm is the same as above.

The plugin maybe have a command, which will execute the algorithm above automatically when we trigger it. So we will get all that we want.

xgfone avatar Mar 14 '17 05:03 xgfone

Sublime Text only understands project via .sublime-project files, it means every time we will need to either create those files or check if those files exist in the User/Projects directory. The total amount of overhead time may be an issue (or maybe not if it is an SSD drive) .

randy3k avatar Mar 14 '17 06:03 randy3k

I know. But it may not be executed frequently, only when to trigger it. Once having detected, it's ok. What's more, it's not necessary to detected them frequently or each time when ST starts.

In general, moreover, we don't have thousands of git/svn projects, just tens or dozens. so it won't cost amounts of overhead time, and maybe finish quickly. For example, I have forty git projects, and Project Manager in VS Code costs about two or three seconds to detect them. So I think that it won't cost too much time in ST.

When found some git/svn projects, if it hasn't existed in ST projects, just create a ST project; or just update the ST project path when the git/svn path is not the same as the project path in .sublime-project. For other case, pass it.

xgfone avatar Mar 14 '17 07:03 xgfone

Actually I quite like your idea, but there are a few things that I need to think about. For example, how happen if one of the folders containing git repos is removed? As the corresponding ST project files were created, shall we just leave them in the Projects directory?

I am leaning to the idea of Batch import Git Repos. I.e, prompting a panel asking the name of a directory in which the git repos are located. Then all repos are imported one by one (with confirmation dialog?)

randy3k avatar Mar 14 '17 07:03 randy3k

About the 1st issue, we can solve it by an option in configuration file. If true, remove it; or leave.

The idea of Batch import Git Repos is nice. For the confirmation dialog, what about to use the configuration option to decide?

xgfone avatar Mar 14 '17 07:03 xgfone

Batch import Git Repos maybe consider the case that the repos are removed, too.

xgfone avatar Mar 14 '17 07:03 xgfone

I just run this script when I want to generate the project folders:

import glob
import json
import socket
import sys
import os

def print_usage():
  print('Usage: [PATH_OF_GIT_PROJECTS]')

def create_new_project(sublime_projects_path, folder_path):
  project_name = os.path.basename(folder_path)
  data = {
    "folders": [
      {
        "binary_file_patterns": [],
        "file_exclude_patterns": [],
        "folder_exclude_patterns": [],
        "name": project_name,
        "path": folder_path,
      }
    ]
  }
  
  print('Creating new sublime project for: {}'.format(project_name))
  project_path = os.path.join(sublime_projects_path, '{}.sublime-project'.format(project_name))
  with open(project_path, 'w') as file:
    json.dump(data, file, indent=2)

def get_current_projects(sublime_projects_path):
  os.chdir(sublime_projects_path)
  projects = []
  for file in glob.iglob('*.sublime-project'):
    try:
      file_path = os.path.join(sublime_projects_path, file)
      data = json.load(open(file_path))
      if 'folders' in data:
        data['__project_path'] = file_path
        projects.append(data)
    except Exception as e:
      print('Error while getting current projects: {}'.format(e))
      sys.exit(1)

  return projects

def detect_new_git_folders(path_to_check):
  folders = set()
  for file in os.listdir(path_to_check):
    try:
      file_path = os.path.join(path_to_check, file)
      if '.git' in os.listdir(file_path):
        folders.add(os.path.expanduser(file_path))
    except:
      pass

  return folders

def main():
  if len(sys.argv) < 2:
    print_usage()
    sys.exit(1)

  path_to_check = sys.argv[1]
  sublime_projects_path = os.path.expanduser('~/.config/sublime-text-3/Packages/User/Projects - {}/'.format(socket.gethostname()))

  current_folders = { folder['path'] for project in get_current_projects(sublime_projects_path) for folder in project['folders'] }
  detected_folders = detect_new_git_folders(path_to_check)

  for folder_path in sorted(detected_folders - current_folders):
    create_new_project(sublime_projects_path, folder_path)

if __name__ == "__main__":
  main()

I also have another script which "prunes" the projects: it checks all the .sublime-project files and checks if each folder in each project still exists. If it doesn't, it removes it from the project file, and if all folders are missing from a project it removes the project file.

I think this kind of functionality would be nice to have in this package. @randy3k would you be open to a Pull Request to add this functionality in? :thinking:

acheronfail avatar Oct 27 '20 12:10 acheronfail

I actually just wrote a similar script today as @acheronfail before finding this enhancement request. I too would love this functionality in Project Manager. It could be baked into the "Refresh Projects" action and look in a list of defined repository root directories defined in settings.

pkkid avatar Apr 03 '22 04:04 pkkid