C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

VBAで.gitignoreを読み込み、判断する

VBAで".gitignore"ファイルを読み込み、判断したいんです。
".gitignore"ファイルはgitで監視対象から無視するためのファイルです。
(わかりにくい表現ですね。調べて下さい・・・)

".gitignore"ファイルでは、フォルダーの指定も出来るのですが、
VBAのプロジェクトではフォルダーの観念が無いため無視。
取りあえずファイルだけを対象として考えます。

で、こんなものを試しに作りました。

'vba

Option Explicit

Private Const TARGET_FOLDER = "C:\temp\test\"

Sub main()
    Dim gitignorePath As String
    gitignorePath = TARGET_FOLDER & ".gitignore"

    'http://officetanaka.net/excel/vba/filesystemobject/filesystemobject.htm
    Dim fso As Object
    Set fso = get_fso
    
    If Not fso.FileExists(gitignorePath) Then Exit Sub

    Dim aryFilter As Variant
    aryFilter = read_file(gitignorePath)

    Dim folder As Object
    Set folder = fso.GetFolder(TARGET_FOLDER)
    
    Dim file As Object
    Dim res As Boolean
    For Each file In folder.Files
        res = is_valid(file.name, aryFilter)
        dump file.name & " : " & res
    Next

End Sub


Private Function is_valid( _
    ByVal name As String, _
    ByVal aryFilter As Variant) As Boolean

    Dim i As Long
    Dim filter As String
    On Error Resume Next
    For i = 0 To UBound(aryFilter)
        filter = aryFilter(i)
        If Len(filter) < 1 Then GoTo continue

        If name Like filter Then
            is_valid = False
            Exit Function
        End If
continue:
    Next
    
    is_valid = True
    
End Function


Private Function get_fso() As Object
    Set get_fso = CreateObject("Scripting.FileSystemObject")
End Function


Private Function read_file( _
    ByVal path As String) As Variant

    On Error Resume Next
    
    Dim buf As Variant
    With get_fso.GetFile(path).OpenAsTextStream
        buf = .ReadAll
        .Close
    End With
    
    Dim newLine As String
    newLine = get_newline_character(buf)
    
    read_file = Split(buf, newLine)
    
    On Error GoTo 0

End Function


Private Function get_newline_character( _
    ByVal txt As String) As String

    Dim res As String

    Select Case True
        Case InStr(txt, vbCrLf) > 0
            res = vbCrLf
        Case InStr(txt, vbCr) > 0
            res = vbCr
        Case InStr(txt, vbLf) > 0
            res = vbLf
        Case Else
            res = ""
    End Select

    get_newline_character = res

End Function


Private Sub dump(ByVal msg As String)
    Debug.Print msg
End Sub

正直の申し上げると、is_valid関数内では Like を使用していますが、
最初は正規表現で挑戦していましたが、上手く行かず挫折しました。

試しに、TARGET_FOLDERとなるフォルダーには、こんなファイルが
入っているとします。

".gitignore"ファイルの中身はこんな感じです。

.gitignore
#*.bas

あぁフォーマットについては何処かで調べて下さい。
自分も分かっていないので・・・。

この状態で実行した結果はこちらです。

.gitignore : False
hoge.bas : True
huga.bas : True
piyo.cls : True

"True"となるものは監視対象を意味します。
取りあえずOKです。

この様に変更して

.gitignore
*.bas

再度実行した結果

.gitignore : False
hoge.bas : False
huga.bas : False
piyo.cls : True

OKです。

続いてこの様に変更して

.gitignore
hoge.bas

再度実行した結果

.gitignore : False
hoge.bas : False
huga.bas : True
piyo.cls : True

OKです。


順調なのですが、これはNGパターンです。

.gitignore
*.bas
!hoge.bas

再度実行した結果

.gitignore : False
hoge.bas : False
huga.bas : False
piyo.cls : True

これはダメなんです。
これになって欲しかった。

.gitignore : False
hoge.bas : True
huga.bas : False
piyo.cls : True

原因はis_valid関数内の処理だと十分理解しているのですが、
どうやって書けば良いのか・・・。

**************

本文と無関係なのですが、Hatena Blogに”AIタイトルアシスタント”と言う
機能が追加されていました。
ブログ本文からAIでタイトル候補を幾つか提案してくれる機能の様です。
凄いですね。今回はこんな感じでした。

無視してやった。