| Age | Commit message (Collapse) | Author |
|
Go 1.22 now support for-range on numeric value.
|
|
|
|
On server with TryDirect is true, any GET request to a directory should
always rescan the content and the generate the new index.html.
While at it, return the generated time in UTC instead of local time.
|
|
The watchfs package now contains the original, v1, of the
Watcher and DirWatcher types.
This changes require exporting method
[memfs.MemFS.UpdateContent].
|
|
|
|
Some of warnings from those linter are false positives, so we just
annotated them.
|
|
Instead of annotating the lines that caught by linters, fix it to comply
with the recommendations.
This causes several breaking changes, especially related to naming,
* api/slack: [Message.IconUrl] become [Message.IconURL]
* lib/dns: DefaultSoaMinumumTtl become DefaultSoaMinimumTTL
* lib/email: [Message.SetBodyHtml] become [Message.SetBodyHTML]
* lib/http: [Client.GenerateHttpRequest] become
[Client.GenerateHTTPRequest]
* lib/http: [ClientOptions.ServerUrl] become [ClientOptions.ServerURL]
* lib/http: [EndpointRequest.HttpWriter] become
[EndpointRequest.HTTPWriter]
* lib/http: [EndpointRequest.HttpRequest] become
[EndpointRequest.HTTPRequest]
* lib/http: [ServerOptions.EnableIndexHtml] become
[ServerOptions.EnableIndexHTML]
* lib/http: [SSEConn.HttpRequest] become [SSEConn.HTTPRequest]
* lib/smtp: [ClientOptions.ServerUrl] become [ClientOptions.ServerURL]
* lib/ssh/sftp: [FileAttrs.SetUid] become [FileAttrs.SetUID]
* lib/ssh/sftp: [FileAttrs.Uid] become [FileAttrs.UID]
|
|
There are several reasons that why we move from github.com.
First, related to the name of package.
We accidentally name the package with "share" a common word in English
that does not reflect the content of repository.
By moving to other repository, we can rename it to better and unique
name, in this "pakakeh.go".
Pakakeh is Minang word for tools, and ".go" suffix indicate that the
repository related to Go programming language.
Second, supporting open source.
The new repository is hosted under sourcehut.org, the founder is known
to support open source, and all their services are licensed under AGPL,
unlike GitHub that are closed sources.
Third, regarding GitHub CoPilot.
The GitHub Terms of Service [1], allow any public content that are hosted
there granted them to parse the content.
On one side, GitHub helps and flourish the open source, but on another
side have an issues regarding scraping the copyleft license [2].
[1]: https://docs.github.com/en/site-policy/github-terms/github-terms-of-service#4-license-grant-to-us
[2]: https://githubcopilotinvestigation.com
|
|
There are some reports that I disagree with revive, in example, code
should not declare the type after variables.
In my opinion, on some cases, declaring the type make the code more
readable and explicit.
Since I did not want to add new configuration file, we changes it and
follow revive for now.
|
|
If the parameter withContent is true, which is default in MarshalJSON,
then all of the node content will be included in JSON output.
This also changes the parameter withoutModTime to withModTime because
working with negation make code not easy to read.
|
|
Another error for handling fs.ErrNotExist when scanning directory
which is may caused by broken symlink.
|
|
The JSON method encode the Node into JSON.
This method provides an alternative to MarshalJSON with granular options,
depth and withoutModTime.
The depth set the level of childs to be encoded.
The depth=0 only encode the Root Node itself (with its childs), depth=1
encode the Root node and its subdirectories, and so on.
If withoutModTime is set to true, all of the node ModTime will not be
included in output.
|
|
|
|
If the FileInfo for Mode changes, update its value and keep going
to check for modification time or size.
While at it, update Readdir comment to reflect the actual FileInfo being
returned.
|
|
The original idea of embedding those interface is to guard the Node
implementation to always follow all methods in the os.FileInfo and
http.File, in case there is additional methods in the future.
But, embedding interfaces make the struct store it as field "FileInfo"
and File with "<nil>" values, which add storage cost to Node.
|
|
Previously, only node content get updated.
In case in the MemFS, user set "Options.TryDirect" to true, the directory
content should be updated too on "MemFS.Get".
|
|
The Child method return the child node based on its node.
|
|
Error message should at least contains 4W in the following order,
WHEN WHO/WHERE WHAT WHY
By quoting, user or machine can parse that the value inside quote
is the value that cause the error (the what), not part of the cause of
the error (the why).
|
|
|
|
The panic is caused by the item in slice of Childs is being
removed during iteration.
To fix this, we remove the childs on the second iteration after
we remove any sub directories inside them.
|
|
Instead of calling filepath.EvalSymlink and Lstat, call os.Stat directly
to the symlink system path.
This also fix the modTime not currently set to the original file when
creating Node from symlink-ed file.
|
|
The GenerateIndexHtml generate simple directory listing as HTML for
all child in the node.
This method is only applicable if node is a directory.
|
|
|
|
Since Go 1.16, the ioutil package has been deprecated.
This changes replace any usage that use functions from ioutil package
with their replacement from package os or package io.
|
|
If the same Node's Path already exists on the Childs, adding another
Node with same Path should not add the Node to the Childs.
|
|
|
|
The realign save storage spaces on struct,
* Node: from 240 to 224 bytes (-16 bytes)
* Options: from 112 to 104 bytes (-8 bytes)
* PathNode: from 16 to 8 bytes (-8 bytes)
|
|
The original idea for option ContentEncoding in EmbedOptions and Node
is to save spaces, compressing the content on disk on embedding and
doing transport, when the MemFS instance is used to serve the (embedded)
contents of file system.
This option turns out break the HTTP content negotiation [1] of
accept-encoding header, if the HTTP server does not handle it properly,
which default Go HTTP server does not.
In order to prevent this issue in the future, for anyone who use the
memfs for serving static HTTP contents, we remove the options and store
the embedded content as is and let the HTTP server handle how the
compression by itself.
[1] https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation
|
|
Since the GoEmbed can be called only when MemFS instance is initiated,
it would be better if parameters for GoEmbed also initialized in the
struct Options.
In this way any additional parameters needed to add to GoEmbed does not
changes the method signature in the future.
This commit add new type EmbedOptions that contains the parameters
for GoEmbed.
In this new type, we add new field EmbedWithoutModTime.
if its true, the modification time for all files and directories are not
stored inside generated code, instead all files will use the current
time when the program is running.
|
|
One of the hardest when multiple packages is used is to detect where
there error happened. For example, if a program return an error io.EOF,
it's hard to detect the exact method or function that caused its,
especially when processing multiple files with network connection.
|
|
This changes rename the receiver name on Node from "leaf" to "node".
|
|
The reason why the field named V is because it's short. It's come
from my C/C++ experience that got carried away when writing this
package.
Now, after having more time writing Go, I prefer clarity over
cleverity(?).
|
|
This changes set all node modification time in embedded files to
the node modTime using Unix() and Nanosecond() values.
Since the time will always changes we need to remove the test to
generate file gen_test.go to prevent the file being modified and
re-adding the same file every time we run local tests.
|
|
The zero value for V ([]byte) is already nil and Node.Childs
([]*Node) does not need to be initialized with make if size is 0.
|
|
The Update method update the node metadata or content based on new
file information.
It accept two parameters: the new file information, newInfo, and
maximum file size, maxFileSize.
The newInfo parameter is optional, if its nil, it will read the file
information based on node's SysPath.
The maxFileSize parameter is also optional.
If its negative, the node content will not be updated.
If its zero, it will default to 5 MB.
There are two possible changes that will happen: its either change on
mode or change on content (size and modtime).
Change on mode will not affect the content of node.
|
|
When NewWatcher called from DirWatcher's Start(), it will called NewNode
with nil parent parameter. If the parent parameter is nil on NewNode
the SysPath of new node will be set to the FileInfo.Name() instead of
full or relative path based on current working directory.
Any operation using new node SysPath will failed because the path
does not exist or reachable from current directory.
For example, let say we have the following directory tree,
testdata
|
+--- A
|
+--- B
We then set DirWatcher Root to "testdata" from current directory.
The DirWatcher Start then iterate over all child of "testdata" directory,
and call NewWatcher("testdata/A", ...). On the NewWatcher, it will
call NewNode(nil, FileInfo, -1). Now since the parent is nil,
the Node.SysPath will be set to FileInfo.Name() or base name of the file,
which is "A".
Later, when node content need to be read, ioutil.ReadFile("A") will
fail because the path to "A" does not exist on current directory.
This fix require to force the parameter "parent" on NewNode to be
required.
|
|
Previously, if a symlink point to directory the memfs NewNode function
will return an error,
AddChild wui: NewNode: read x/y: is a directory
which cause the files inside y cannot be scanned (404).
This commit fix this issue by checking if the original node mode is a
directory and return immediately.
|
|
A negative MaxFileSize means the content of file will not be mapped to
memory, but the content type should be detected for other operation.
|
|
Previously, MarshalJSON on memfs will return an object of map
of all PathNodes and on Node it will return an object.
This changes make it the JSON response consistent. If its directory
it will return the node object with its childs, without "content".
If its file, it will return the node object with content.
While at it, use single "mod_time" with value is epoch and return
the node ContentType as "content_type".
|
|
The Save method will write the new content to file system and update
the content of Node using Encode().
|
|
Previously, we did not check if the file size is 0 before reading the
content or updating the content type, which cause the read on file
return io.EOF and the file not added to caches.
This commit fix this issue by checking for zero file size and for
io.EOF when reading the file content.
|
|
Previously, if file is symbolic link and has different name with their
original file, it will return an error when we tried to open the file
parentpath/filename: no such file or directory
because we use the original file name, not the symlinked file name.
This commit fix this issue by not replacing the original FileInfo for
symlink but by setting only the size and mode.
|
|
Encoding the PathNode to JSON will include the content of each Node, but
encoding only single Node will include the content.
|
|
The resetAllModTime method set the modTime field from Root to its child
to the value in parameter.
|
|
Previously, without MarshalJSON, encoding the MemFS or Node object will
result in incomplete information, for example, missing name, modification
time, and size.
This commit implement the json.Marshaler in MemFS which encode the
PathNode sorted by keys in ascending order.
|
|
|
|
Previously, AddFile set the internal path equal to path of file to be
included. This may cause conflict if the file is already included
due to the same sys path but different internal path.
This commit add parameter internalPath to set custom internal path in
the memfs map.
|
|
Remove unnecessary variable convertion.
|
|
The field WithContent is not necessary if we set MaxFileSize to negative
value.
|
|
Previously, the generated Go code from memfs can be used only once
on the package that use it. For example, if we have two instances of
memfs.MemFS and both of them call GoGenerate(), when we load them back
again only the last one will be active and set the global variable
memfs.GeneratedPathNode.
This changes refactoring on how we use memfs by storing the
generated path node into variable that is defined by user and pass
them to New Options.
This changes affect package http and io.
|