| Age | Commit message (Collapse) | Author |
|
|
|
Go 1.22 now support for-range on numeric value.
|
|
|
|
Due to "byte" is considered as "uint8" during reflection, we cannot tell
whether the value is slice of byte of slice of number with type uint8.
|
|
HTTP request now implicitly create request with context.
Any false positive related to not closing HTTP response body has been
annotated with "nolint:bodyclose".
In the example code, use consistent "// Output:" comment format, by
prefixing with single space.
Any comment on code now also prefixing with single space.
An error returned without variables now use [errors.New] instead of
[fmt.Errorf].
Any error returned using [fmt.Errorf] now wrapped using "%w" instead of
"%s".
Also, replace error checking using [errors.Is] or [errors.As], instead
of using equal/not-equal operator.
Any statement like "x = x OP y" now replaced with "x OP= y".
Also, swap statement is simplified using "x, y = y, x".
Any switch statement with single case now replaced with if-condition.
Any call to defer on function or program that call [os.Exit], now
replaced by calling the deferred function directly.
Any if-else condition now replaced with switch statement, if possible.
|
|
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
|
|
The Keys method return sorted list of all section, subsection, and
variables as string where each of them separated by ":", for example
"section:sub:var".
|
|
Since Go 1.17, the [reflect.StructField] add method IsExported which
give clear indication that the field is exported rather than checking
not-empty PkgPath.
|
|
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.
|
|
|
|
The shadow tool [1] report a variable where its name is declared twice
or more, in different scope.
[1] https://pkg.go.dev/golang.org/x/tools@v0.13.0/go/analysis/passes/shadow
|
|
The rtype and rval parameters are never used inside the unmarshal method.
|
|
Using global debug value for all packages turns out is not a good
idea.
|
|
While at it, clean up some codes to make it more readable and debug-able.
|
|
Previously, if INI file contains multi line variables, for example
key = a \
b
The Get and saved value is "a \tb", where it should be "a b" for Get and
"a \\\n\t\b" again when saved.
This changes require refactoring how the variable's value is parsed and
stored.
A variable value is parsed and stored from character after "=" until new
line or comment as raw value, and the real value is derived by trimming
white spaces, handle escaped character and double quotes.
|
|
|
|
A colon `:` is escaped using double backslash `\\`, for example
`a:b\\:c:d` contains section `a`, subsection `b:c`, and variable `d`.
A double quote `"` is escaped using triple backslash, for example `\\\"`.
|
|
|
|
If the field is pointer, the code will thrown panic if its point to
nil struct or print "<invalid reflct.Value>" for String.
|
|
While at it, split the example for marshaling and unmarshaling
struct into separate examples.
|
|
For a field F with type map[K]S `ini:"sec"`, where K is string and S is
a struct or pointer to struct element, marshaling the field F will
result in the following ini format,
[sec "K"]
<S.Field.Tag> = <S.Field.Value>
Each field in struct S unmarshaled normally as "key = value".
This rule is also applied when unmarshalling from ini text into map[K]V.
This implementation allow multiple section with dynamic subsections as
key.
|
|
Given the following struct,
type ADT struct {
Amap map[string]string `ini:"section:sub"`
}
and ini text,
[test "map"]
c = 3
b = 2
a = 1
Unmarshal-ing the text into ADT and then Marshal-ing it again will
result in unpredictable keys order.
This changes fix this issue by sorting the keys on ADT.Amap on
Marshal-ing, to make the written output predictable.
|
|
In case the root struct contains field like []*T, it should be marshalled
the same as []T.
|
|
Give the following field struct with tag,
V *T `ini:"sec:sub"
If the V is not nil, it will marshal it into,
[sec "sub"]
<field name or tag> = <field value>
|
|
Previously, we use the passed struct as reference for unmarshalling
the ini text into struct. This model on unmarshaling does not works well
if we want to unmarshal to slice of struct.
This commit changes the way the unmarshal works by iterating over
section and variables from parsed ini text file and do a lookup on the
passed struct to find field that match the section, subsection and key.
With this model we can unmarshal a section-subsction into struct
or slice of struct.
|
|
Given a struct with exported field is slice of struct and tagged with
section and sub-section, the exported field will be marshalled as,
[section "sub"]
field = value
|
|
|
|
|
|
The UnsetAll method will remove all variables in section and/or
subsection that match with the key.
|
|
In Git specification, an empty variable is equal to boolean true.
This cause inconsistency between empty string and boolean true.
This changes make the empty value become an empty string instead of
boolean true.
|
|
|
|
|
|
|
|
Previously, Gets return uniq, non-duplicate values. This changes make
the Gets return the values as is.
|
|
|
|
|
|
|
|
|
|
|
|
The Unmarshal function parse the INI stream as slice of byte and store
its value into struct of `v`.
All the property and specification of field's tag follow the Marshal
function.
|
|
Marshal encode the struct of v into stream of ini formatted string.
To encode a struct, an exported fields must have tagged with "ini" key;
untagged field will not be exported.
Each exported field in the struct must have at least one tag: a section
where the field's name (the key) and field's value will be saved.
An optional subsection can be defined by adding a string separated by
colon ":" after section's name.
An optional key's name also can be defined by adding string after
subsection name.
If key's name is not defined it would be default to lowercase string of
field's name.
An array or slice will be encoded as multiple keys.
One exception to above rule is map type.
A map's key will override the key defined in tag.
|
|
For readibility, each section should start with an empty line.
|
|
Previous behaviour of Set() method will return false if the section
or subsection of key to be set not found on database.
This commit change the behaviour of Set(). If no section or subsection
found on database, the new section with key-value will be created.
If no key found, the new key-value will be added to the specific section.
|
|
The valid syntax to suppress linter warnings is "//nolint:<name>" with
no space between comment and "nolint" and between ":". Also, we move the
placement of nolint directive to the top of statements for multiple
nolint in the same scope.
While at it, fix and supress some linter warnings.
|
|
|
|
Given a section name and/or subsection name, Vars() method will return
all variables as map of key and value.
If there is a duplicate in key's name, only the last key value that will
be store on map value.
This method is a shortcut that can be used in templating.
|
|
If section name is not empty, only the keys will be listed in the map.
|
|
The following methods are added to support templating using this package,
* Subs(): a method that return all non-empty subsections
* Val(): a method that return the last variable's value using key's path
as combination of section-name ":" sub-section-name ":" key.
* Vals(): a method that return all variable values as slice of string
This changes cause the section type to be exported back, again.
|
|
The Add() method will add new key and value to the last item in section
and/or subsection.
The Set() method set the last variable's value in section-subsection that
match with the key.
The Unset() method will remove the last variable's in section and/or
subsection that match with the key.
|