Skip to content

Commit 73056c5

Browse files
Merge pull request #80 from swift-developer-tools/feature/path-advanced
Add Path (Advanced) bindings
2 parents 727b685 + f953709 commit 73056c5

4 files changed

Lines changed: 274 additions & 0 deletions

File tree

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the swift-libgit2 open source project.
4+
//
5+
// Copyright (c) Margins Technologies LLC.
6+
// Licensed under the Apache License, Version 2.0.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
import CLibgit2
11+
12+
13+
14+
/// The types of Git-specific files.
15+
///
16+
/// ## C Equivalent
17+
///
18+
/// [`git_path_gitfile`](https://libgit2.org/docs/reference/main/sys/path/git_path_gitfile.html)
19+
public enum GitPathGitFile: UInt32, CEnum
20+
{
21+
/// Check for the `.gitignore` file.
22+
case gitPathGitFileGitignore = 0
23+
24+
/// Check for the `.gitmodules` file.
25+
case gitPathGitFileGitmodules = 1
26+
27+
/// Check for the `.gitattributes` file.
28+
case gitPathGitFileGitattributes = 2
29+
30+
31+
32+
/// Initializes a ``GitPathGitFile`` instance from the given
33+
/// `git_path_gitfile` instance.
34+
/// - Parameter pathGitFile: The `git_path_gitfile` instance to use.
35+
internal init?(
36+
cValue pathGitFile: git_path_gitfile
37+
)
38+
{
39+
switch pathGitFile
40+
{
41+
case GIT_PATH_GITFILE_GITIGNORE : self = .gitPathGitFileGitignore
42+
case GIT_PATH_GITFILE_GITMODULES : self = .gitPathGitFileGitmodules
43+
case GIT_PATH_GITFILE_GITATTRIBUTES : self = .gitPathGitFileGitattributes
44+
default : return nil
45+
}
46+
}
47+
48+
49+
50+
/// Converts the ``GitPathGitFile`` instance into a `git_path_gitfile`
51+
/// instance.
52+
/// - Returns: The `git_path_gitfile` instance.
53+
internal func cValue() -> git_path_gitfile
54+
{
55+
switch self
56+
{
57+
case .gitPathGitFileGitignore : return GIT_PATH_GITFILE_GITIGNORE
58+
case .gitPathGitFileGitmodules : return GIT_PATH_GITFILE_GITMODULES
59+
case .gitPathGitFileGitattributes : return GIT_PATH_GITFILE_GITATTRIBUTES
60+
}
61+
}
62+
}
63+
64+
65+
66+
/// The types of file system checks to perform.
67+
///
68+
/// ## C Equivalent
69+
///
70+
/// [`git_path_fs`](https://libgit2.org/docs/reference/main/sys/path/git_path_fs.html)
71+
public enum GitPathFS: UInt32, CEnum
72+
{
73+
/// Perform both NTFS-specific and HFS-specific checks.
74+
case gitPathFSGeneric = 0
75+
76+
/// Perform only NTFS-specific checks.
77+
case gitPathFSNTFS = 1
78+
79+
/// Perform only HFS-specific checks.
80+
case gitPathFSHFS = 2
81+
82+
83+
84+
/// Initializes a ``GitPathFS`` instance from the given `git_path_fs`
85+
/// instance.
86+
/// - Parameter pathFS: The `git_path_fs` instance to use.
87+
internal init?(
88+
cValue pathFS: git_path_fs
89+
)
90+
{
91+
switch pathFS
92+
{
93+
case GIT_PATH_FS_GENERIC : self = .gitPathFSGeneric
94+
case GIT_PATH_FS_NTFS : self = .gitPathFSNTFS
95+
case GIT_PATH_FS_HFS : self = .gitPathFSHFS
96+
default : return nil
97+
}
98+
}
99+
100+
101+
102+
/// Converts the ``GitPathFS`` instance into a `git_path_fs` instance.
103+
/// - Returns: The `git_path_fs` instance.
104+
internal func cValue() -> git_path_fs
105+
{
106+
switch self
107+
{
108+
case .gitPathFSGeneric : return GIT_PATH_FS_GENERIC
109+
case .gitPathFSNTFS : return GIT_PATH_FS_NTFS
110+
case .gitPathFSHFS : return GIT_PATH_FS_HFS
111+
}
112+
}
113+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the swift-libgit2 open source project.
4+
//
5+
// Copyright (c) Margins Technologies LLC.
6+
// Licensed under the Apache License, Version 2.0.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
import CLibgit2
11+
12+
13+
14+
/// Checks whether the given path component corresponds to a `.git$SUFFIX` file.
15+
/// - Parameters:
16+
/// - path: The path component to check.
17+
/// - pathLen: The length `path`.
18+
/// - gitFile: The Git-specific file type.
19+
/// - fs: The type of file system check to perform.
20+
/// - Returns: Whether the given path component corresponds to a `.git$SUFFIX`
21+
/// file, or `nil` if there was an error.
22+
///
23+
/// ## Discussion
24+
///
25+
/// Since some file systems have special behavior when writing files to the
26+
/// disk, a plain string comparison is not always possible to verify whether
27+
/// a file name matches an expected path. This function performs a more
28+
/// in-depth check to verify the given path component.
29+
///
30+
/// ## C Equivalent
31+
///
32+
/// [`git_path_is_gitfile()`](https://libgit2.org/docs/reference/main/sys/path/git_path_is_gitfile.html)
33+
public func gitPathIsGitFile(
34+
path : String,
35+
pathLen : Int,
36+
gitFile : GitPathGitFile,
37+
fs : GitPathFS
38+
) -> Bool?
39+
{
40+
let isPathGitFile: Int32 = git_path_is_gitfile(
41+
path,
42+
path.count,
43+
gitFile.cValue(),
44+
fs.cValue()
45+
)
46+
47+
if
48+
isPathGitFile != 0,
49+
isPathGitFile != 1
50+
{
51+
return nil
52+
}
53+
54+
return Bool(isPathGitFile)
55+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Path (Advanced)
2+
3+
Path validation.
4+
5+
## Topics
6+
7+
### Enums
8+
9+
- ``GitPathGitFile``
10+
- ``GitPathFS``
11+
12+
### Functions
13+
14+
- ``gitPathIsGitFile(path:pathLen:gitFile:fs:)``
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the swift-libgit2 open source project.
4+
//
5+
// Copyright (c) Margins Technologies LLC.
6+
// Licensed under the Apache License, Version 2.0.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
import CLibgit2
11+
import XCTest
12+
@testable import SwiftLibgit2
13+
14+
15+
16+
final class PathTests: XCTestCaseStopOnFail
17+
{
18+
func testGitPathFS() throws
19+
{
20+
XCTAssertEqual(GitPathFS.gitPathFSGeneric.rawValue, GIT_PATH_FS_GENERIC.rawValue)
21+
XCTAssertEqual(GitPathFS.gitPathFSNTFS.rawValue, GIT_PATH_FS_NTFS.rawValue)
22+
XCTAssertEqual(GitPathFS.gitPathFSHFS.rawValue, GIT_PATH_FS_HFS.rawValue)
23+
24+
XCTAssertNil(GitPathFS(rawValue: 123))
25+
26+
XCTAssertEqual(GitPathFS.gitPathFSGeneric.cValue(), GIT_PATH_FS_GENERIC)
27+
XCTAssertEqual(GitPathFS.gitPathFSNTFS.cValue(), GIT_PATH_FS_NTFS)
28+
XCTAssertEqual(GitPathFS.gitPathFSHFS.cValue(), GIT_PATH_FS_HFS)
29+
30+
XCTAssertEqual(GitPathFS(cValue: GIT_PATH_FS_GENERIC), .gitPathFSGeneric)
31+
XCTAssertEqual(GitPathFS(cValue: GIT_PATH_FS_NTFS), .gitPathFSNTFS)
32+
XCTAssertEqual(GitPathFS(cValue: GIT_PATH_FS_HFS), .gitPathFSHFS)
33+
}
34+
35+
36+
37+
func testGitPathGitFile() throws
38+
{
39+
XCTAssertEqual(GitPathGitFile.gitPathGitFileGitignore.rawValue, GIT_PATH_GITFILE_GITIGNORE.rawValue)
40+
XCTAssertEqual(GitPathGitFile.gitPathGitFileGitmodules.rawValue, GIT_PATH_GITFILE_GITMODULES.rawValue)
41+
XCTAssertEqual(GitPathGitFile.gitPathGitFileGitattributes.rawValue, GIT_PATH_GITFILE_GITATTRIBUTES.rawValue)
42+
43+
XCTAssertNil(GitPathGitFile(rawValue: 123))
44+
45+
XCTAssertEqual(GitPathGitFile.gitPathGitFileGitignore.cValue(), GIT_PATH_GITFILE_GITIGNORE)
46+
XCTAssertEqual(GitPathGitFile.gitPathGitFileGitmodules.cValue(), GIT_PATH_GITFILE_GITMODULES)
47+
XCTAssertEqual(GitPathGitFile.gitPathGitFileGitattributes.cValue(), GIT_PATH_GITFILE_GITATTRIBUTES)
48+
49+
XCTAssertEqual(GitPathGitFile(cValue: GIT_PATH_GITFILE_GITIGNORE), .gitPathGitFileGitignore)
50+
XCTAssertEqual(GitPathGitFile(cValue: GIT_PATH_GITFILE_GITMODULES), .gitPathGitFileGitmodules)
51+
XCTAssertEqual(GitPathGitFile(cValue: GIT_PATH_GITFILE_GITATTRIBUTES), .gitPathGitFileGitattributes)
52+
}
53+
54+
55+
56+
func testGitPathIsGitFile() throws
57+
{
58+
let pathsTypesAndResults: [(String, GitPathGitFile, Bool)] =
59+
[
60+
(".gitignore" , .gitPathGitFileGitignore, true),
61+
(".gitmodules", .gitPathGitFileGitmodules, true),
62+
(".gitattributes", .gitPathGitFileGitattributes, true),
63+
("folder/.gitignore", .gitPathGitFileGitignore, false),
64+
("folder/.gitmodules", .gitPathGitFileGitmodules, false),
65+
("folder/.gitattributes", .gitPathGitFileGitattributes, false),
66+
("folder/.gitfile", .gitPathGitFileGitignore, false),
67+
("folder/.git", .gitPathGitFileGitignore, false),
68+
("gitignore", .gitPathGitFileGitignore, false),
69+
("gitmodules" , .gitPathGitFileGitignore, false),
70+
("gitattributes", .gitPathGitFileGitignore, false),
71+
(".git", .gitPathGitFileGitignore, false),
72+
("git", .gitPathGitFileGitattributes, false)
73+
]
74+
75+
for pathTypeAndResult in pathsTypesAndResults
76+
{
77+
let path : String = pathTypeAndResult.0
78+
let pathGitFile : GitPathGitFile = pathTypeAndResult.1
79+
let expectedResult : Bool = pathTypeAndResult.2
80+
81+
let isGitfile: Bool? = gitPathIsGitFile(
82+
path: path,
83+
pathLen: path.utf8.count,
84+
gitFile: pathGitFile,
85+
fs: .gitPathFSGeneric
86+
)
87+
88+
XCTAssertNotNil(isGitfile)
89+
XCTAssertEqual(isGitfile, expectedResult)
90+
}
91+
}
92+
}

0 commit comments

Comments
 (0)