fix(fstab): Improvements; Bugfixes

This commit is contained in:
Myzel394 2024-10-09 14:41:40 +02:00
parent 30c68e0d99
commit 5a13487db8
No known key found for this signature in database
GPG Key ID: ED20A1D1D423AF3F
5 changed files with 178 additions and 140 deletions

View File

@ -16,11 +16,16 @@ func analyzeValuesAreValid(
for it.Next() { for it.Next() {
entry := it.Value().(*ast.FstabEntry) entry := it.Value().(*ast.FstabEntry)
mountOptions := entry.FetchMountOptionsField(true)
checkField(ctx, entry.Fields.Spec, fields.SpecField) checkField(ctx, entry.Fields.Spec, fields.SpecField)
checkField(ctx, entry.Fields.MountPoint, fields.MountPointField) checkField(ctx, entry.Fields.MountPoint, fields.MountPointField)
checkField(ctx, entry.Fields.FilesystemType, fields.FileSystemTypeField) checkField(ctx, entry.Fields.FilesystemType, fields.FileSystemTypeField)
checkField(ctx, entry.Fields.Options, entry.GetMountOptionsField())
if mountOptions != nil {
checkField(ctx, entry.Fields.Options, mountOptions)
}
checkField(ctx, entry.Fields.Freq, fields.FreqField) checkField(ctx, entry.Fields.Freq, fields.FreqField)
checkField(ctx, entry.Fields.Pass, fields.PassField) checkField(ctx, entry.Fields.Pass, fields.PassField)
} }
@ -34,8 +39,7 @@ func checkField(
invalidValues := docOption.DeprecatedCheckIsValid(field.Value.Value) invalidValues := docOption.DeprecatedCheckIsValid(field.Value.Value)
for _, invalidValue := range invalidValues { for _, invalidValue := range invalidValues {
err := docvalues.LSPErrorFromInvalidValue(field.Start.Line, *invalidValue) err := docvalues.LSPErrorFromInvalidValue(field.Start.Line, *invalidValue).ShiftCharacter(field.Start.Character)
err.ShiftCharacter(field.Start.Character)
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{ ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
Range: err.Range.ToLSPRange(), Range: err.Range.ToLSPRange(),

View File

@ -4,6 +4,7 @@ import (
"config-lsp/common" "config-lsp/common"
docvalues "config-lsp/doc-values" docvalues "config-lsp/doc-values"
"config-lsp/handlers/fstab/fields" "config-lsp/handlers/fstab/fields"
"config-lsp/utils"
) )
// func (c FstabConfig) GetEntry(line uint32) *FstabEntry { // func (c FstabConfig) GetEntry(line uint32) *FstabEntry {
@ -40,16 +41,44 @@ func (e FstabEntry) GetFieldAtPosition(position common.Position) FstabFieldName
return FstabFieldPass return FstabFieldPass
} }
func (e FstabEntry) GetMountOptionsField() docvalues.DeprecatedValue { // Create a mount options field for the entry
fileSystemType := e.Fields.FilesystemType.Value.Value func (e FstabEntry) FetchMountOptionsField(includeDefaults bool) docvalues.DeprecatedValue {
if e.Fields.FilesystemType == nil {
var optionsField docvalues.DeprecatedValue return nil
if foundField, found := fields.MountOptionsMapField[fileSystemType]; found {
optionsField = foundField
} else {
optionsField = fields.DefaultMountOptionsField
} }
return optionsField option, found := fields.MountOptionsMapField[e.Fields.FilesystemType.Value.Value]
if !found {
return nil
}
var enums []docvalues.EnumString
var assignable map[docvalues.EnumString]docvalues.DeprecatedValue
if includeDefaults {
enums = append(option.Enums, fields.DefaultOptions...)
assignable = utils.MergeMaps(option.Assignable, fields.DefaultAssignOptions)
} else {
enums = option.Enums
assignable = option.Assignable
}
return &docvalues.ArrayValue{
Separator: ",",
DuplicatesExtractor: &fields.MountOptionsExtractor,
SubValue: docvalues.OrValue{
Values: []docvalues.DeprecatedValue{
docvalues.KeyEnumAssignmentValue{
Values: assignable,
ValueIsOptional: false,
Separator: "=",
},
docvalues.EnumValue{
EnforceValues: true,
Values: enums,
},
},
},
}
} }

View File

@ -6,7 +6,7 @@ import (
"strings" "strings"
) )
var mountOptionsExtractor = func(value string) string { var MountOptionsExtractor = func(value string) string {
separatorIndex := strings.Index(value, "=") separatorIndex := strings.Index(value, "=")
if separatorIndex == -1 { if separatorIndex == -1 {
@ -17,7 +17,7 @@ var mountOptionsExtractor = func(value string) string {
} }
// From https://www.man7.org/linux/man-pages/man8/mount.8.html // From https://www.man7.org/linux/man-pages/man8/mount.8.html
var defaultOptions = []docvalues.EnumString{ var DefaultOptions = []docvalues.EnumString{
// Default options // Default options
docvalues.CreateEnumStringWithDoc( docvalues.CreateEnumStringWithDoc(
"async", "async",
@ -228,7 +228,7 @@ type assignOption struct {
Handler func(context docvalues.KeyValueAssignmentContext) docvalues.DeprecatedValue Handler func(context docvalues.KeyValueAssignmentContext) docvalues.DeprecatedValue
} }
var defaultAssignOptions = map[docvalues.EnumString]docvalues.DeprecatedValue{ var DefaultAssignOptions = map[docvalues.EnumString]docvalues.DeprecatedValue{
docvalues.CreateEnumStringWithDoc( docvalues.CreateEnumStringWithDoc(
"context", "context",
"The context= option is useful when mounting filesystems that do not support extended attributes, such as a floppy or hard disk formatted with VFAT, or systems that are not normally running under SELinux, such as an ext3 or ext4 formatted disk from a non-SELinux workstation. You can also use context= on filesystems you do not trust, such as a floppy. It also helps in compatibility with xattr-supporting filesystems on earlier 2.4.<x> kernel versions. Even where xattrs are supported, you can save time not having to label every file by assigning the entire disk one security context. A commonly used option for removable media is context=\"system_u:object_r:removable_t\".", "The context= option is useful when mounting filesystems that do not support extended attributes, such as a floppy or hard disk formatted with VFAT, or systems that are not normally running under SELinux, such as an ext3 or ext4 formatted disk from a non-SELinux workstation. You can also use context= on filesystems you do not trust, such as a floppy. It also helps in compatibility with xattr-supporting filesystems on earlier 2.4.<x> kernel versions. Even where xattrs are supported, you can save time not having to label every file by assigning the entire disk one security context. A commonly used option for removable media is context=\"system_u:object_r:removable_t\".",
@ -347,7 +347,7 @@ func createMountOptionField(
return docvalues.ArrayValue{ return docvalues.ArrayValue{
Separator: ",", Separator: ",",
DuplicatesExtractor: &mountOptionsExtractor, DuplicatesExtractor: &MountOptionsExtractor,
SubValue: docvalues.OrValue{ SubValue: docvalues.OrValue{
Values: []docvalues.DeprecatedValue{ Values: []docvalues.DeprecatedValue{
docvalues.KeyEnumAssignmentValue{ docvalues.KeyEnumAssignmentValue{
@ -364,103 +364,114 @@ func createMountOptionField(
} }
} }
var DefaultMountOptionsField = createMountOptionField(defaultOptions, defaultAssignOptions) type optionField struct {
Assignable map[docvalues.EnumString]docvalues.DeprecatedValue
var MountOptionsMapField = map[string]docvalues.DeprecatedValue{ Enums []docvalues.EnumString
"adfs": createMountOptionField( }
commondocumentation.AdfsDocumentationEnums,
commondocumentation.AdfsDocumentationAssignable, var DefaultMountOptionsField = createMountOptionField(DefaultOptions, DefaultAssignOptions)
),
"affs": createMountOptionField( var MountOptionsMapField = map[string]optionField{
commondocumentation.AffsDocumentationEnums, "adfs": {
commondocumentation.AffsDocumentationAssignable, Enums: commondocumentation.AdfsDocumentationEnums,
), Assignable: commondocumentation.AdfsDocumentationAssignable,
"btrfs": createMountOptionField( },
commondocumentation.BtrfsDocumentationEnums, "affs": {
commondocumentation.BtrfsDocumentationAssignable, Enums: commondocumentation.AffsDocumentationEnums,
), Assignable: commondocumentation.AffsDocumentationAssignable,
"debugfs": createMountOptionField( },
commondocumentation.DebugfsDocumentationEnums, "btrfs": {
commondocumentation.DebugfsDocumentationAssignable, Enums: commondocumentation.BtrfsDocumentationEnums,
), Assignable: commondocumentation.BtrfsDocumentationAssignable,
"ext2": createMountOptionField( },
commondocumentation.Ext2DocumentationEnums, "debugfs": {
commondocumentation.Ext2DocumentationAssignable, Enums: commondocumentation.DebugfsDocumentationEnums,
), Assignable: commondocumentation.DebugfsDocumentationAssignable,
"ext3": createMountOptionField( },
append(commondocumentation.Ext2DocumentationEnums, commondocumentation.Ext3DocumentationEnums...), "ext2": {
docvalues.MergeKeyEnumAssignmentMaps(commondocumentation.Ext2DocumentationAssignable, commondocumentation.Ext3DocumentationAssignable), Enums: commondocumentation.Ext2DocumentationEnums,
), Assignable: commondocumentation.Ext2DocumentationAssignable,
"ext4": createMountOptionField( },
append(append(commondocumentation.Ext2DocumentationEnums, commondocumentation.Ext3DocumentationEnums...), commondocumentation.Ext4DocumentationEnums...), "ext3": {
docvalues.MergeKeyEnumAssignmentMaps(commondocumentation.Ext2DocumentationAssignable, docvalues.MergeKeyEnumAssignmentMaps(commondocumentation.Ext3DocumentationAssignable, commondocumentation.Ext4DocumentationAssignable)), Enums: append(commondocumentation.Ext2DocumentationEnums, commondocumentation.Ext3DocumentationEnums...),
), Assignable: docvalues.MergeKeyEnumAssignmentMaps(commondocumentation.Ext2DocumentationAssignable, commondocumentation.Ext3DocumentationAssignable),
"devpts": createMountOptionField( },
commondocumentation.DevptsDocumentationEnums, "ext4": {
commondocumentation.DevptsDocumentationAssignable, Enums: append(
), append(
"fat": createMountOptionField( commondocumentation.Ext2DocumentationEnums,
commondocumentation.FatDocumentationEnums, commondocumentation.Ext3DocumentationEnums...,
commondocumentation.FatDocumentationAssignable, ),
), commondocumentation.Ext4DocumentationEnums...,
"hfs": createMountOptionField( ),
commondocumentation.HfsDocumentationEnums, Assignable: docvalues.MergeKeyEnumAssignmentMaps(commondocumentation.Ext2DocumentationAssignable, docvalues.MergeKeyEnumAssignmentMaps(commondocumentation.Ext3DocumentationAssignable, commondocumentation.Ext4DocumentationAssignable)),
commondocumentation.HfsDocumentationAssignable, },
), "devpts": {
"hpfs": createMountOptionField( Enums: commondocumentation.DevptsDocumentationEnums,
commondocumentation.HpfsDocumentationEnums, Assignable: commondocumentation.DevptsDocumentationAssignable,
commondocumentation.HpfsDocumentationAssignable, },
), "fat": {
"iso9660": createMountOptionField( Enums: commondocumentation.FatDocumentationEnums,
commondocumentation.Iso9660DocumentationEnums, Assignable: commondocumentation.FatDocumentationAssignable,
commondocumentation.Iso9660DocumentationAssignable, },
), "hfs": {
"jfs": createMountOptionField( Enums: commondocumentation.HfsDocumentationEnums,
commondocumentation.JfsDocumentationEnums, Assignable: commondocumentation.HfsDocumentationAssignable,
commondocumentation.JfsDocumentationAssignable, },
), "hpfs": {
"msdos": createMountOptionField( Enums: commondocumentation.HpfsDocumentationEnums,
commondocumentation.MsdosDocumentationEnums, Assignable: commondocumentation.HpfsDocumentationAssignable,
commondocumentation.MsdosDocumentationAssignable, },
), "iso9660": {
"ncpfs": createMountOptionField( Enums: commondocumentation.Iso9660DocumentationEnums,
commondocumentation.NcpfsDocumentationEnums, Assignable: commondocumentation.Iso9660DocumentationAssignable,
commondocumentation.NcpfsDocumentationAssignable, },
), "jfs": {
"ntfs": createMountOptionField( Enums: commondocumentation.JfsDocumentationEnums,
commondocumentation.NtfsDocumentationEnums, Assignable: commondocumentation.JfsDocumentationAssignable,
commondocumentation.NtfsDocumentationAssignable, },
), "msdos": {
"overlay": createMountOptionField( Enums: commondocumentation.MsdosDocumentationEnums,
commondocumentation.OverlayDocumentationEnums, Assignable: commondocumentation.MsdosDocumentationAssignable,
commondocumentation.OverlayDocumentationAssignable, },
), "ncpfs": {
"reiserfs": createMountOptionField( Enums: commondocumentation.NcpfsDocumentationEnums,
commondocumentation.ReiserfsDocumentationEnums, Assignable: commondocumentation.NcpfsDocumentationAssignable,
commondocumentation.ReiserfsDocumentationAssignable, },
), "ntfs": {
"usbfs": createMountOptionField( Enums: commondocumentation.NtfsDocumentationEnums,
commondocumentation.UsbfsDocumentationEnums, Assignable: commondocumentation.NtfsDocumentationAssignable,
commondocumentation.UsbfsDocumentationAssignable, },
), "overlay": {
"ubifs": createMountOptionField( Enums: commondocumentation.OverlayDocumentationEnums,
commondocumentation.UbifsDocumentationEnums, Assignable: commondocumentation.OverlayDocumentationAssignable,
commondocumentation.UbifsDocumentationAssignable, },
), "reiserfs": {
"udf": createMountOptionField( Enums: commondocumentation.ReiserfsDocumentationEnums,
commondocumentation.UdfDocumentationEnums, Assignable: commondocumentation.ReiserfsDocumentationAssignable,
commondocumentation.UdfDocumentationAssignable, },
), "usbfs": {
"ufs": createMountOptionField( Enums: commondocumentation.UsbfsDocumentationEnums,
commondocumentation.UfsDocumentationEnums, Assignable: commondocumentation.UsbfsDocumentationAssignable,
commondocumentation.UfsDocumentationAssignable, },
), "ubifs": {
"umsdos": createMountOptionField( Enums: commondocumentation.UbifsDocumentationEnums,
commondocumentation.UmsdosDocumentationEnums, Assignable: commondocumentation.UbifsDocumentationAssignable,
commondocumentation.UmsdosDocumentationAssignable, },
), "udf": {
"vfat": createMountOptionField( Enums: commondocumentation.UdfDocumentationEnums,
commondocumentation.VfatDocumentationEnums, Assignable: commondocumentation.UdfDocumentationAssignable,
commondocumentation.VfatDocumentationAssignable, },
), "ufs": {
Enums: commondocumentation.UfsDocumentationEnums,
Assignable: commondocumentation.UfsDocumentationAssignable,
},
"umsdos": {
Enums: commondocumentation.UmsdosDocumentationEnums,
Assignable: commondocumentation.UmsdosDocumentationAssignable,
},
"vfat": {
Enums: commondocumentation.VfatDocumentationEnums,
Assignable: commondocumentation.VfatDocumentationAssignable,
},
} }

View File

@ -42,6 +42,7 @@ func GetCompletion(
fileSystemType := entry.Fields.FilesystemType.Value.Value fileSystemType := entry.Fields.FilesystemType.Value.Value
completions := make([]protocol.CompletionItem, 0, 50) completions := make([]protocol.CompletionItem, 0, 50)
println("fetching field options now", line, cursor)
for _, completion := range fields.DefaultMountOptionsField.DeprecatedFetchCompletions(line, cursor) { for _, completion := range fields.DefaultMountOptionsField.DeprecatedFetchCompletions(line, cursor) {
var documentation string var documentation string
@ -59,8 +60,7 @@ func GetCompletion(
completions = append(completions, completion) completions = append(completions, completion)
} }
if optionsField, found := fields.MountOptionsMapField[fileSystemType]; found { for _, completion := range entry.FetchMountOptionsField(false).DeprecatedFetchCompletions(line, cursor) {
for _, completion := range optionsField.DeprecatedFetchCompletions(line, cursor) {
var documentation string var documentation string
switch completion.Documentation.(type) { switch completion.Documentation.(type) {
@ -76,7 +76,6 @@ func GetCompletion(
} }
completions = append(completions, completion) completions = append(completions, completion)
} }
}
return completions, nil return completions, nil
case ast.FstabFieldFreq: case ast.FstabFieldFreq:
@ -109,5 +108,5 @@ func getFieldSafely(field *ast.FstabField, cursor common.CursorPosition) (string
return "", 0 return "", 0
} }
return field.Value.Raw, common.CursorToCharacterIndex(uint32(cursor)) - field.Start.Character return field.Value.Raw, common.CursorToCharacterIndex(uint32(cursor) - field.Start.Character)
} }

View File

@ -2,9 +2,7 @@ package handlers
import ( import (
"config-lsp/common" "config-lsp/common"
"config-lsp/doc-values"
"config-lsp/handlers/fstab/ast" "config-lsp/handlers/fstab/ast"
"config-lsp/handlers/fstab/fields"
"strings" "strings"
"github.com/tliron/glsp/protocol_3_16" "github.com/tliron/glsp/protocol_3_16"
@ -25,13 +23,10 @@ func GetHoverInfo(
case ast.FstabFieldFileSystemType: case ast.FstabFieldFileSystemType:
return &FileSystemTypeField, nil return &FileSystemTypeField, nil
case ast.FstabFieldOptions: case ast.FstabFieldOptions:
fileSystemType := entry.Fields.FilesystemType.Value.Value optionsField := entry.FetchMountOptionsField(true)
var optionsField docvalues.DeprecatedValue
if foundField, found := fields.MountOptionsMapField[fileSystemType]; found { if optionsField == nil {
optionsField = foundField return nil, nil
} else {
optionsField = fields.DefaultMountOptionsField
} }
relativeCursor := uint32(index) - entry.Fields.Options.Start.Character relativeCursor := uint32(index) - entry.Fields.Options.Start.Character