Skip to content

Commit

Permalink
Slightly update README.md, create release.yml for auto-compiling bina…
Browse files Browse the repository at this point in the history
…ries.
  • Loading branch information
boholder committed Nov 3, 2021
1 parent 0ae50af commit 9d3c3da
Show file tree
Hide file tree
Showing 4 changed files with 349 additions and 7 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Use https://github.com/marketplace/actions/rust-release-binary
# for convenience.

name: release

on:
release:
types: [created]

jobs:
release:
name: release ${{ matrix.target }}
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
include:
- target: x86_64-pc-windows-gnu
archive: zip
- target: x86_64-unknown-linux-musl
archive: tar.gz
- target: x86_64-apple-darwin
archive: zip

steps:
- uses: actions/checkout@v2
- name: Init submodules
run: git submodule update --init --recursive
- name: Compile and release
uses: rust-build/rust-build.action@latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RUSTTARGET: ${{ matrix.target }}
ARCHIVE_TYPES: ${{ matrix.archive }}
89 changes: 83 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,85 @@
# Naming
## naming

* Extract and convert the naming format(case|notation) of identifiers from files or stdin.
* Use this tool to prepare identifier name strings for further operations
(matching,replacing...) on relative files.
* It is recommended to use this tool in combination with "xargs".
[![CI](https://github.com/boholder/naming/actions/workflows/ci.yml/badge.svg)](https://github.com/boholder/naming/actions/workflows/ci.yml)

Working in progress...
naming is a command line tool that helps you extract and convert the naming format (case|notation)
of identifiers from files or stdin. Use this tool to prepare identifier name strings for further
operations (matching,replacing...) on relative files.

### Quick links

* [User guide](doc/USERGUIDE.md)
* Help information with the explanation of design ideas.
* Usage examples.
* [Installation](#installation)
* [Building & Running tests](#building)
* [Help us improve this tool](#contribution)

### What it can do?

You can convert one identifier to different naming cases, with multiple output formats.

```text
$ echo "userId" | naming
userId USER_ID user_id user-id userId UserId
$ echo "userId" | naming --json
{"result":[{"origin":"userId","screaming_snake":"USER_ID","snake":"user_id",
"kebab":"user-id","camel":"userId","pascal":"UserId"}]}
$ echo "userId" | naming --regex
userId USER_ID|user_id|user-id|userId|UserId
```

The following example is more complex than entering commands manually, but it automates the process,
which is why we made this tool in the first place. By combining this tool with others, you can write
shell scripts about identifier format relative jobs.

```text
# Search all positions of an identifier in project directory
$ echo "pageSize" | naming | xargs -n1 -I {} -- grep -r {} src_dir
# Change one identifier from camelCase to snake_case
$ echo "pageSize" | naming --output=s | \
xargs -l -t -- bash -c 'sed -i "s/$0/$1/g" src_file'
bash -c 'sed -i "s/$0/$1/g" src_file' pageSize page_size
(^-- `xargs -t` output) (run sed command...)
```

### Installation

We provide pre-compiled binaries for `x86_64-pc-windows-gnu`, `x86_64-unknown-linux-musl`
and `x86_64-apple-darwin` platforms, you can download them at
[release page](https://github.com/boholder/naming/releases). Or you can build it directly from
source code, following the [building](#building) progress.

### Building

Just routine process will work:

```text
$ git clone https://github.com/boholder/naming
$ cd naming
$ cargo build --release
$ ./target/release/naming --help
$ (print help information)
```

After cloning the source to your local machine, you can run all tests via:

```text
$ cd naming
$ cargo test --all
```

There are
[two ignored tests](crates/clt_lib/tests/identifying_ability_on_languages.rs)
, don't mind, these two tests made us to narrow down the capabilities of the tool, avoid duplicate
implementing grep's functionality.

# Contribution

* Does the [user guide](doc/USERGUIDE.md) and [help information](crates/core/app.rs) sound natural?
Help us fix grammatical errors and polish the description.
* When you found a bug or have suggestions, feel free to submit
new [issues](https://github.com/boholder/naming/issues/new).
2 changes: 1 addition & 1 deletion crates/clt_lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ edition = "2018"
[dependencies]
regex = "~1.5.4"
lazy_static = "~1.4.0"
naming_lib = { path = "../naming_lib" }
naming_lib = "~0.1.4"
230 changes: 230 additions & 0 deletions doc/USERGUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
## User Guide

Sorry! Only the help information is available now. More content will be added later.

```text
Extract and convert the naming format(case) of identifiers from files.
Use this tool to prepare identifier name strings for further operations
(matching, replacing...) on relative files.
It is recommended to use this tool in combination with `xargs`.
Check the [homepage] for more information:
-> https://github.com/boholder/naming
Feel free to submit new [issues] when you found a bug or have suggestions:
-> https://github.com/boholder/naming/issues/new
Use -h for a brief help information, and --help for a more detailed version.
USAGE:
naming.exe [FLAGS] [OPTIONS] [--] [files]...
FLAGS:
-h, --help
Prints help information
--json
Output result in json format. the output looks like:
{"result":[
{"origin":"<origin matched string>",
"screaming_snake":"...",
"snake":"...",
"kebab":"...",
"camel":"...",
"pascal":"..."},
...
]}
A "result" array field under the root, one element for
one match's result inside array. Json above is beautified,
the real output doesn't contain spaces, looks like:
"{"result":[{...},...]}".
NOTE: The presence of the format fields in result
depends on whether it is present in `--output` option.
--regex
Output result as an OR-joined (e.g. "x|y|z") regular expression.
This is useful when you want to perform further operations involving
"any given format of an identifier".
This option will replace target output formats in result
with a regex, which makes output looks like:
<origin match 1> <OR-regex of match 1>
<origin match 2> <OR-regex of match 2>
...
Combine with `--json` and `--regex` options will
makes output looks like (beautified):
{"result":[
{"origin":"<origin matched string>",
"regex":"..."},
...
]}
NOTE: Same as `--json` option, the presence of the formats inside
regex depends on whether it is present in `--output` option.
-V, --version
Prints version information
OPTIONS:
-e, --eof <eof>
Set logical EOF string, if occurs, the rest of the input is ignored.
This will actually be done *after reading the whole content*, so
it is recommended to use the following command to actually intercept
large files (to prevent long processing time):
$ sed '/<eof-word>/q' file_name | naming
Command above means that output content from first line
to the line contains given eof-word, to this tool.
-f, --filter <filter>...
Set which formats will be matched and extracted from input,
discard other format matches. Default add all formats into
filter, which means do not discard any match that can be
matched by one of the formats.
There are 6 available formats:
* S -> SCREAMING_SNAKE_CASE
* s -> snake_case
* k -> kebab-case
* c -> camelCase
* P -> PascalCase
* h -> hungarian notation
The last format, hungarian notation means that let the tool
recognize camel case matches as hungarian notation style,
strip the first lowercase word (as this identifier's type prefix)
and keep the remain part for further converting.
example: "iPageSize" --strip"i"--> "PageSize" --> ...
[!]NOTE: Due to the implementation of hungarian notation's matching,
at most one of the two, hungarian notation (h) and camel case (c)
can appear in `--filter` option. Pass both of them will let the tool
exits with non-zero signal.
-l, --locator <locator>...
Set locator pairs around identifiers, in each pair value,
the delimiter between prefix and suffix is a space.
[!] Although this tool provides this option for convenience,
be careful when using it. See warning information below for detail.
The two parts of a pair are inserted directly into the
regular pattern, so users need to manually escape the characters
that need to be escaped. For [the regex syntax], check this document:
https://docs.rs/regex/1.5.4/regex/index.html#syntax
Default(1): "\b \b", which will match the valid identifiers
separated by "Unicode word boundary (\w on one side and \W,
\A, or \z on other)" positions.
Each value passed to this option will be transformed to an regex
pattern looks like: "(?:<prefix>|\A)(identifier)(?:<suffix>|\z)",
where \A for matching the start of file position and
\z for matching the end of file position.
So there is no need to worry about having a match right next to
the start or end of the file. If the input is only one valid word,
that word will also be matched because of the hardcoded logic
described above.
[!]WARNING:
Sorry for letting you know these implementation details.
The rust regex library "regex" will matches text with a
"non-overlapping" way, while it doesn't support lookaround syntax.
So for the implementation, I used non-capture tuples to
match prefixes and suffixes, which have mentioned above.
An unintentional locator value, for example "\s \s",
will generates a pattern "(?:\s|\A)([a-zA-Z0-9_-]+)(?:\s|\z)".
This pattern will only matches "a" and "c" on text "a b c",
while "b" shares two space symbols with "a" and "c".
First matches "<start of file>a ", remain "b c<eof>",
then matches " c<eof>", further extracting via group number
gets "a" and "c" as final result.
As you can see, locators that represent characters rather than
positions may let to this unwanted result. Please use this option
carefully and make sure the output of this tool is as expected,
or use the grep method mentioned below as an alternative to
extracting words from input text.
[!]NOTE: Any incomplete pair value that couldn't be split
into two part by space delimiter like "a"," a","a "
will let the tool outputs nothing and exits with non-zero signal.
NOTE:
Due to the technical limitation, there is no guarantee that
the order of matches in output (in normal output format, that
means the order of lines) will be same as the order in
origin file content.
Each generated pattern will matches the input independently
and all matches will be concatenated according to the order of
values passed to this `--locator` option.
If you want to keep this order, you can use tools like `grep`
with a complex regex that contains lookaround syntax and OR operator
to match all patterns at once, then extract the wanted part.
For example:
$ echo "@first@ #second#" | \
grep -oP "(?<=@)[a-z]+(?=@)|(?<=#)[a-z]+(?=#)" | naming
Commands above piped "first\nsecond" to this tool.
-o, --output <output>...
Set which naming cases that matches will be converted to.
There are 5 available formats:
* S -> SCREAMING_SNAKE_CASE
* s -> snake_case
* k -> kebab-case
* c -> camelCase
* P -> PascalCase
Default output all formats in a fix order --
6 words separated by spaces, one line per match in output,
origin match followed with naming cases of it:
<origin match 1> <SCREAMING_SNAKE_CASE> <snake_case> \
<kebab-case> <camelCase> <PascalCase>\n
...
The order of target formats in the output is sames as
the order of the corresponding values that passed to
this option, so you can arrange the order of formats
(in normal output format, that means the order of words
in line) in output as you wish.
This will be useful when you want to process the output
of this tool, like, pass them to `xargs`.
ARGS:
<files>...
pass file names, or directly pass text via shell pipe
EXAMPLE:
1. Default output all 5 format conventions, starting with origin input
$ echo "pageSize" | naming
pageSize PAGE_SIZE page_size page-size pageSize PageSize
2. Search all positions of one identifier
$ echo "pageSize" | naming | xargs -n1 -I {} -- grep -r {} src_dir
3. Change one identifier from camelCase to snake_case
$ echo "pageSize" | naming --output=s | \
xargs -l -t -- bash -c 'sed -i "s/$0/$1/g" src_file'
bash -c 'sed -i "s/$0/$1/g" src_file' pageSize page_size
(^-- `xargs -t` output) (run sed command...)
```

0 comments on commit 9d3c3da

Please sign in to comment.