github.com/mcuadros/ascode@v1.3.1/starlark/module/filepath/filepath.go (about)

     1  package filepath
     2  
     3  import (
     4  	"path/filepath"
     5  	"sync"
     6  
     7  	"go.starlark.net/starlark"
     8  	"go.starlark.net/starlarkstruct"
     9  )
    10  
    11  const (
    12  	// ModuleName defines the expected name for this Module when used
    13  	// in starlark's load() function, eg: load('io/ioutil', 'json')
    14  	ModuleName = "path/filepath"
    15  
    16  	separatorVarName = "separator"
    17  	absFuncName      = "abs"
    18  	baseFuncName     = "base"
    19  	cleanFuncName    = "clean"
    20  	dirFuncName      = "dir"
    21  	extFuncName      = "ext"
    22  	globFuncName     = "glob"
    23  	isAbsFuncName    = "is_abs"
    24  	joinFuncName     = "join"
    25  	relFuncName      = "rel"
    26  )
    27  
    28  var (
    29  	once         sync.Once
    30  	ioutilModule starlark.StringDict
    31  )
    32  
    33  // LoadModule loads the os module.
    34  // It is concurrency-safe and idempotent.
    35  //
    36  //   outline: filepath
    37  //     filepath implements utility routines for manipulating filename paths in a
    38  //     way compatible with the target operating system-defined file path
    39  //     path: path/filepath
    40  func LoadModule() (starlark.StringDict, error) {
    41  	once.Do(func() {
    42  		ioutilModule = starlark.StringDict{
    43  			"filepath": &starlarkstruct.Module{
    44  				Name: "filepath",
    45  				Members: starlark.StringDict{
    46  					separatorVarName: starlark.String(string(filepath.Separator)),
    47  					globFuncName:     starlark.NewBuiltin(globFuncName, Glob),
    48  					absFuncName:      starlark.NewBuiltin(absFuncName, Abs),
    49  					baseFuncName:     starlark.NewBuiltin(baseFuncName, Base),
    50  					cleanFuncName:    starlark.NewBuiltin(cleanFuncName, Clean),
    51  					dirFuncName:      starlark.NewBuiltin(dirFuncName, Dir),
    52  					extFuncName:      starlark.NewBuiltin(extFuncName, Ext),
    53  					isAbsFuncName:    starlark.NewBuiltin(isAbsFuncName, IsAbs),
    54  					joinFuncName:     starlark.NewBuiltin(joinFuncName, Join),
    55  					relFuncName:      starlark.NewBuiltin(relFuncName, Rel),
    56  				},
    57  			},
    58  		}
    59  	})
    60  
    61  	return ioutilModule, nil
    62  }
    63  
    64  // Glob returns the names of all files matching pattern or nil if there is no
    65  // matching file.
    66  //
    67  //   outline: filepath
    68  //     functions:
    69  //       glob(pattern) list
    70  //         returns the names of all files matching pattern or None if there is
    71  //         no matching file.
    72  //         params:
    73  //           pattern string
    74  //             pattern ([syntax](https://golang.org/pkg/path/filepath/#Match))
    75  func Glob(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
    76  	var pattern string
    77  
    78  	err := starlark.UnpackArgs(globFuncName, args, kwargs, "pattern", &pattern)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  
    83  	list, err := filepath.Glob(pattern)
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  
    88  	values := make([]starlark.Value, len(list))
    89  	for i, entry := range list {
    90  		values[i] = starlark.String(entry)
    91  	}
    92  
    93  	return starlark.NewList(values), nil
    94  }
    95  
    96  // Abs returns an absolute representation of path. If the path is not absolute
    97  // it will be joined with the current working directory to turn it into an/
    98  // absolute path.
    99  //
   100  //   outline: filepath
   101  //     functions:
   102  //       abs(path) string
   103  //         returns an absolute representation of path. If the path is not
   104  //         absolute it will be joined with the current working directory to turn
   105  //         it into an absolute path.
   106  //         params:
   107  //           path string
   108  //             relative or absolute path
   109  func Abs(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
   110  	var path string
   111  
   112  	err := starlark.UnpackArgs(absFuncName, args, kwargs, "path", &path)
   113  	if err != nil {
   114  		return nil, err
   115  	}
   116  
   117  	abs, err := filepath.Abs(path)
   118  	if err != nil {
   119  		return nil, err
   120  	}
   121  
   122  	return starlark.String(abs), nil
   123  }
   124  
   125  // Base returns the last element of path. Trailing path separators are removed
   126  // before extracting the last element. If the path is empty, Base returns ".".
   127  // If the path consists entirely of separators, Base returns a single separator.
   128  //
   129  //   outline: filepath
   130  //     functions:
   131  //       base(path) string
   132  //         returns the last element of path. Trailing path separators are
   133  //         removed before extracting the last element. If the path is empty,
   134  //         `base` returns ".". If the path consists entirely of separators,
   135  //         `base` returns a single separator.
   136  //         params:
   137  //           path string
   138  //             input path
   139  func Base(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
   140  	var path string
   141  
   142  	err := starlark.UnpackArgs(baseFuncName, args, kwargs, "path", &path)
   143  	if err != nil {
   144  		return nil, err
   145  	}
   146  
   147  	return starlark.String(filepath.Base(path)), nil
   148  }
   149  
   150  // Clean returns the shortest path name equivalent to path by purely lexical processing.
   151  //
   152  //   outline: filepath
   153  //     functions:
   154  //       clean(path) string
   155  //         returns the shortest path name equivalent to path by purely lexical
   156  //         processing.
   157  //         params:
   158  //           path string
   159  //             input path
   160  func Clean(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
   161  	var path string
   162  
   163  	err := starlark.UnpackArgs(cleanFuncName, args, kwargs, "path", &path)
   164  	if err != nil {
   165  		return nil, err
   166  	}
   167  
   168  	return starlark.String(filepath.Clean(path)), nil
   169  }
   170  
   171  // Dir returns all but the last element of path, typically the path's directory.
   172  //
   173  //   outline: filepath
   174  //     functions:
   175  //       dir(path) string
   176  //         returns all but the last element of path, typically the path's
   177  //         directory. After dropping the final element, `dir` calls `clean` on the
   178  //         path and trailing slashes are removed. If the path is empty, `dir`
   179  //         returns ".". If the path consists entirely of separators, `dir`
   180  //         returns a single separator. The returned path does not end in a
   181  //         separator unless it is the root directory.
   182  //         params:
   183  //           path string
   184  //             input path
   185  func Dir(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
   186  	var path string
   187  
   188  	err := starlark.UnpackArgs(dirFuncName, args, kwargs, "path", &path)
   189  	if err != nil {
   190  		return nil, err
   191  	}
   192  
   193  	return starlark.String(filepath.Dir(path)), nil
   194  }
   195  
   196  // Ext returns the file name extension used by path. The extension is the suffix
   197  // beginning at the final dot in the final element of path; it is empty if there
   198  // is no dot.
   199  //
   200  //   outline: filepath
   201  //     functions:
   202  //       ext(path) string
   203  //         returns the file name extension used by path. The extension is the
   204  //         suffix beginning at the final dot in the final element of path; it
   205  //         is empty if there is no dot.
   206  //         params:
   207  //           path string
   208  //             input path
   209  func Ext(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
   210  	var path string
   211  
   212  	err := starlark.UnpackArgs(extFuncName, args, kwargs, "path", &path)
   213  	if err != nil {
   214  		return nil, err
   215  	}
   216  
   217  	return starlark.String(filepath.Ext(path)), nil
   218  }
   219  
   220  // IsAbs reports whether the path is absolute.
   221  //
   222  //   outline: filepath
   223  //     functions:
   224  //       is_abs(path) bool
   225  //         reports whether the path is absolute.
   226  //         params:
   227  //           path string
   228  //             input path
   229  func IsAbs(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
   230  	var path string
   231  
   232  	err := starlark.UnpackArgs(isAbsFuncName, args, kwargs, "path", &path)
   233  	if err != nil {
   234  		return nil, err
   235  	}
   236  
   237  	return starlark.Bool(filepath.IsAbs(path)), nil
   238  }
   239  
   240  // Join joins any number of path elements into a single path, adding a Separator
   241  // if necessary.
   242  //
   243  //   outline: filepath
   244  //     functions:
   245  //       join(elements) string
   246  //         joins any number of path elements into a single path, adding a
   247  //         `filepath.separator` if necessary. Join calls Clean on the result;
   248  //         in particular, all empty strings are ignored. On Windows, the result
   249  //         is a UNC path if and only if the first path element is a UNC path.
   250  //         params:
   251  //           elements lists
   252  //             list of path elements to be joined
   253  func Join(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
   254  	var elements *starlark.List
   255  
   256  	err := starlark.UnpackArgs(joinFuncName, args, kwargs, "elements", &elements)
   257  	if err != nil {
   258  		return nil, err
   259  	}
   260  
   261  	parts := make([]string, elements.Len())
   262  	for i := 0; i < cap(parts); i++ {
   263  		parts[i] = elements.Index(i).(starlark.String).GoString()
   264  	}
   265  
   266  	return starlark.String(filepath.Join(parts...)), nil
   267  }
   268  
   269  // Rel returns a relative path that is lexically equivalent to targpath when
   270  // joined to basepath with an intervening separator.
   271  //
   272  //   outline: filepath
   273  //     functions:
   274  //       rel(basepath, targpath) string
   275  //         returns a relative path that is lexically equivalent to targpath when
   276  //         joined to basepath with an intervening separator. That is, `filepath.join(basepath, filepath.rel(basepath, targpath))`
   277  //         is equivalent to targpath itself. On success, the returned path will
   278  //         always be relative to basepath, even if basepath and targpath share
   279  //         no elements. An error is returned if targpath can't be made relative
   280  //         to basepath or if knowing the current working directory would be
   281  //         necessary to compute it. Rel calls Clean on the result.
   282  //         params:
   283  //           basepath string
   284  //             relative or absolute path
   285  //           targpath string
   286  //             relative or absolute path
   287  func Rel(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
   288  	var basepath, targpath string
   289  
   290  	err := starlark.UnpackArgs(relFuncName, args, kwargs, "basepath", &basepath, "targpath", &targpath)
   291  	if err != nil {
   292  		return nil, err
   293  	}
   294  
   295  	rel, err := filepath.Rel(basepath, targpath)
   296  	if err != nil {
   297  		return nil, err
   298  	}
   299  
   300  	return starlark.String(rel), nil
   301  }