def test_strip_directory_failure(self): """If a path is not inside a directory, ValueError should be raised.""" with self.assertRaises(ValueError): strip_directory("path/to/file", "another/directory") with self.assertRaises(ValueError): strip_directory("path/to/file", "/path/to/f")
def get_source(user: User, project: Project, path: str) -> typing.Union[Source, DiskSource]: """ Locate a `Source` that contains the file at `path`. Iterate up through the directory tree of the path until Source(s) mapped to that path are found. Then check if that file exists in the source. Fall back to DiskSource if no file is found in any linked Sources. """ # the paths won't match if the incoming path has a trailing slash as the paths on the source doesn't (shouldn't) path = path.rstrip("/") original_path = path gh_facade: typing.Optional[GitHubFacade] = None while True: sources = Source.objects.filter(path=path, project=project) if sources: if path == original_path: # This source should be one without sub files return sources[0] else: # These may be Github, etc, sources mapped into the same directory. Find one that has a file at the path for source in sources: if isinstance(source, GithubSource): source = typing.cast(GithubSource, source) if gh_facade is None: gh_token = user_github_token(user) gh_facade = GitHubFacade(source.repo, gh_token) relative_path = utf8_path_join( source.subpath, strip_directory(original_path, source.path)) if gh_facade.path_exists(relative_path): return source # this source has the file so it must be this one? # if not, continue on, keep going up the tree to find the root source else: raise RuntimeError( "Don't know how to examine the contents of {}". format(type(source))) if path == ".": break path = utf8_dirname(path) if path == "/" or path == "": path = "." # Fall Back to DiskSource return DiskSource()
def refresh(self) -> None: # build a list of all the files we know about (dict map file name to DirectoryListEntry) source_files = { entry.path: entry for entry in recursive_directory_list(self.project, None, self.authentication) } # generate the storage directory on disk for files in this project project_dir = generate_project_storage_directory( self.target_directory, self.project) for root, dirs, files in os.walk(to_utf8(project_dir)): for f in files: # iterate every file in the project storage directory full_disk_file_path = utf8_path_join(root, f) relative_disk_file_path = strip_directory( full_disk_file_path, project_dir) if relative_disk_file_path in source_files: # if we already have a reference to this file somehow in DB (either FileSource or linked) if (source_files[relative_disk_file_path].type == DirectoryEntryType.FILE): # if it is a file if isinstance( source_files[relative_disk_file_path].source, FileSource): # only update contents if it is a FileSource, not if it came from GitHub etc self.update_existing_file_sources( full_disk_file_path, relative_disk_file_path) else: # just in case the sources listing missed it or something messed up, just try to update sources with # path source_exists = self.update_existing_file_sources( full_disk_file_path, relative_disk_file_path) if not source_exists: # Create a new FileSource as reference to this disk file and pull in the contents with open(to_utf8(full_disk_file_path), "rb") as disk_file: FileSource.objects.create( project=self.project, path=relative_disk_file_path, file=File(disk_file), )
def get_github_repository_path(self) -> str: source = typing.cast(GithubSource, self.source) return utf8_path_join(source.subpath, strip_directory(self.file_path, source.path))
def test_strip_directory_normal(self): """Test the normal behaviour of using `strip_directory` with a number of scenarios.""" self.assertEqual("file", strip_directory("path/to/thing/file", "path/to/thing")) self.assertEqual( "file", strip_directory("path/to/thing/file", "path/to/thing/") )
def get_github_repository_path(source, file_path): repo_path = utf8_path_join(source.subpath, strip_directory(file_path, source.path)) return repo_path