feat: initialize project
This commit is contained in:
commit
bbc91d22a3
|
@ -0,0 +1,11 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
tab_width = 4
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
max_line_length = 80
|
|
@ -0,0 +1 @@
|
||||||
|
ko_fi: aldy505
|
|
@ -0,0 +1,23 @@
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ["*"]
|
||||||
|
pull_request:
|
||||||
|
branches: ["*"]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Build:
|
||||||
|
name: API
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: rust:1.56-buster
|
||||||
|
timeout-minutes: 15
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Check
|
||||||
|
run: cargo check
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cargo build
|
|
@ -0,0 +1 @@
|
||||||
|
/target
|
|
@ -0,0 +1,106 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "add-editorconfig"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"dirs",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs"
|
||||||
|
version = "4.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||||
|
dependencies = [
|
||||||
|
"dirs-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs-sys"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"redox_users",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.107"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.2.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_users"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"redox_syscall",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.10.2+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "add-editorconfig"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Generate .editorconfig file in current directory"
|
||||||
|
edition = "2018"
|
||||||
|
authors = ["Reinaldy Rafli <aldy505@tutanota.com>"]
|
||||||
|
categories = ["command-line-utilities"]
|
||||||
|
license = "MIT"
|
||||||
|
homepage = "https://github.com/aldy505/add-editorconfig"
|
||||||
|
repository = "https://github.com/aldy505/add-editorconfig"
|
||||||
|
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
dirs = "4.0"
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 Reinaldy Rafli <aldy505@tutanota.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,35 @@
|
||||||
|
# add-editorconfig
|
||||||
|
|
||||||
|
Small and simple CLI app to generate .editorconfig based on a given settings.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Will create an .editorconfig in the current directory
|
||||||
|
$ add-editorconfig
|
||||||
|
|
||||||
|
# Will create an .editorconfig with the default config from .editorconfig that
|
||||||
|
# exists on the home directory.
|
||||||
|
$ add-editorconfig default
|
||||||
|
|
||||||
|
# Show help
|
||||||
|
$ add-editorconfig help
|
||||||
|
|
||||||
|
# Show current version
|
||||||
|
$ add-editorconfig version
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Yes, you'll need to build from source.
|
||||||
|
|
||||||
|
1. Clone this repository.
|
||||||
|
2. Make sure to have Rust in your system. At this point of time, I have v1.54.0.
|
||||||
|
3. Run `cargo build`.
|
||||||
|
4. Run `sudo cp -v target/debug/add-editorconfig /usr/local/bin`.
|
||||||
|
If you're not running in Linux, try to check how to move file on your own.
|
||||||
|
5. Check it via `add-editorconfig version`.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[MIT](./LICENSE)
|
|
@ -0,0 +1,269 @@
|
||||||
|
use std::{env, fs::{self, File}, io::{self, Error, Write}, path::{Path, PathBuf}};
|
||||||
|
extern crate dirs;
|
||||||
|
|
||||||
|
#[derive(Debug,Clone)]
|
||||||
|
pub struct Settings {
|
||||||
|
end_of_line: String,
|
||||||
|
indent_size: i32,
|
||||||
|
indent_style: String,
|
||||||
|
tab_width: i32,
|
||||||
|
charset: String,
|
||||||
|
root: bool,
|
||||||
|
trim_trailing_whitespace: bool,
|
||||||
|
insert_final_newline: bool,
|
||||||
|
max_line_length: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
let current_path: PathBuf = Path::new(".editorconfig").to_path_buf();
|
||||||
|
|
||||||
|
// Check if the user supplied any args
|
||||||
|
if args.len() > 1 {
|
||||||
|
if args[1] == "default" {
|
||||||
|
let default_path: PathBuf = dirs::home_dir().unwrap().join(".editorconfig");
|
||||||
|
// Check if there is default editorconfig
|
||||||
|
// already exists on `~/.editorconfig`
|
||||||
|
if !Path::new(default_path.as_os_str()).exists() {
|
||||||
|
println!("Looks like there is no default .editorconfig on your home directory. Creating one..");
|
||||||
|
let p: Settings = prompt();
|
||||||
|
// If not, create one
|
||||||
|
match create_config(default_path, p.clone()) {
|
||||||
|
Ok(_) => println!("Successfully created .editorconfig on your home directory."),
|
||||||
|
Err(e) => println!("Error: {}", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
match create_config(current_path, p.clone()) {
|
||||||
|
Ok(_) => println!("Successfully created .editorconfig on current directory."),
|
||||||
|
Err(e) => println!("Error: {}", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is, print a message
|
||||||
|
println!("Using default .editorconfig...\n");
|
||||||
|
match fs::read_to_string(default_path) {
|
||||||
|
Ok(s) => {
|
||||||
|
match create_config(current_path, parse_settings(s)) {
|
||||||
|
Ok(_) => println!("Successfully created .editorconfig"),
|
||||||
|
Err(e) => println!("Error: {}", e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => println!("Error: {}", e),
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if args[1] == "version" || args[1] == "--version" || args[1] == "-v" {
|
||||||
|
println!("add-editorconfig 0.1.0");
|
||||||
|
return;
|
||||||
|
} else if args[1] == "help" || args[1] == "--help" || args[1] == "-h" {
|
||||||
|
println!("add-editorconfig");
|
||||||
|
println!("Small and simple CLI app to generate .editorconfig based on a given settings.\n");
|
||||||
|
println!("Usage:");
|
||||||
|
println!(" add-editorconfig - Create an .editorconfig in the current directory");
|
||||||
|
println!(" add-editorconfig default - Create an .editorconfig with the default config");
|
||||||
|
println!(" from .editorconfig that exists on the home directory.");
|
||||||
|
println!(" add-editorconfig help - Print this help command");
|
||||||
|
println!(" add-editorconfig version - Show current version\n");
|
||||||
|
println!("If you had encountered with any bugs, please open an issue at:");
|
||||||
|
println!("https://github.com/aldy505/add-editorconfig");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let p: Settings = prompt();
|
||||||
|
match create_config(current_path, p) {
|
||||||
|
Ok(_) => println!("Successfully created .editorconfig"),
|
||||||
|
Err(e) => println!("Error: {}", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_settings() -> Settings {
|
||||||
|
return Settings {
|
||||||
|
end_of_line: String::from("lf"),
|
||||||
|
indent_size: 4,
|
||||||
|
indent_style: String::from("space"),
|
||||||
|
tab_width: 4,
|
||||||
|
charset: String::from("utf-8"),
|
||||||
|
root: true,
|
||||||
|
trim_trailing_whitespace: true,
|
||||||
|
insert_final_newline: true,
|
||||||
|
max_line_length: 80
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prompt() -> Settings {
|
||||||
|
let mut settings: Settings = Settings {
|
||||||
|
..default_settings()
|
||||||
|
};
|
||||||
|
let mut temp = String::new();
|
||||||
|
println!("Fill the config with the provided options.");
|
||||||
|
println!("Entering nothing will set the parameter to its' default value.\n");
|
||||||
|
|
||||||
|
// indent_style
|
||||||
|
print!("Indentation style (space / tabs): ");
|
||||||
|
io::stdout().flush().unwrap();
|
||||||
|
io::stdin().read_line(&mut temp).unwrap();
|
||||||
|
if temp.trim() == "tabs" {
|
||||||
|
settings.indent_style = String::from("tabs");
|
||||||
|
} else {
|
||||||
|
settings.indent_style = String::from("space");
|
||||||
|
}
|
||||||
|
temp = String::from("");
|
||||||
|
|
||||||
|
// indent_size
|
||||||
|
print!("Indent size (number): ");
|
||||||
|
io::stdout().flush().unwrap();
|
||||||
|
io::stdin().read_line(&mut temp).unwrap();
|
||||||
|
if temp.trim().parse::<i32>().is_ok() {
|
||||||
|
settings.indent_size = temp.trim().parse::<i32>().unwrap();
|
||||||
|
} else {
|
||||||
|
settings.indent_size = 4;
|
||||||
|
}
|
||||||
|
temp = String::from("");
|
||||||
|
|
||||||
|
|
||||||
|
// tab_width
|
||||||
|
print!("Tab width (number): ");
|
||||||
|
io::stdout().flush().unwrap();
|
||||||
|
io::stdin().read_line(&mut temp).unwrap();
|
||||||
|
if temp.trim().parse::<i32>().is_ok() {
|
||||||
|
settings.tab_width = temp.trim().parse::<i32>().unwrap();
|
||||||
|
} else {
|
||||||
|
settings.tab_width = 4;
|
||||||
|
}
|
||||||
|
temp = String::from("");
|
||||||
|
|
||||||
|
// tab_width
|
||||||
|
print!("End of line (lf / crlf / cr): ");
|
||||||
|
io::stdout().flush().unwrap();
|
||||||
|
io::stdin().read_line(&mut temp).unwrap();
|
||||||
|
if temp.trim() == "lf" {
|
||||||
|
settings.end_of_line = String::from("lf");
|
||||||
|
} else if temp.trim() == "crlf" {
|
||||||
|
settings.end_of_line = String::from("crlf");
|
||||||
|
} else if temp.trim() == "cr" {
|
||||||
|
settings.end_of_line = String::from("cr");
|
||||||
|
} else {
|
||||||
|
settings.end_of_line = String::from("lf");
|
||||||
|
}
|
||||||
|
temp = String::from("");
|
||||||
|
|
||||||
|
// charset
|
||||||
|
print!("Charset (latin1 / utf-8 / utf-16be / utf-16le / utf-8-bom): ");
|
||||||
|
io::stdout().flush().unwrap();
|
||||||
|
io::stdin().read_line(&mut temp).unwrap();
|
||||||
|
if temp.trim() == "latin1" {
|
||||||
|
settings.charset = String::from("latin1");
|
||||||
|
} else if temp.trim() == "utf-8" {
|
||||||
|
settings.charset = String::from("utf-8");
|
||||||
|
} else if temp.trim() == "utf-16be" {
|
||||||
|
settings.charset = String::from("utf-16be");
|
||||||
|
} else if temp.trim() == "utf-16le" {
|
||||||
|
settings.charset = String::from("utf-16le");
|
||||||
|
} else if temp.trim() == "utf-8-bom" {
|
||||||
|
settings.charset = String::from("utf-8-bom");
|
||||||
|
} else {
|
||||||
|
settings.charset = String::from("utf-8");
|
||||||
|
}
|
||||||
|
temp = String::from("");
|
||||||
|
|
||||||
|
// trim_trailing_whitespace
|
||||||
|
print!("Trim trailing whitespace (true / false): ");
|
||||||
|
io::stdout().flush().unwrap();
|
||||||
|
io::stdin().read_line(&mut temp).unwrap();
|
||||||
|
if temp.trim() == "true" {
|
||||||
|
settings.trim_trailing_whitespace = true;
|
||||||
|
} else {
|
||||||
|
settings.trim_trailing_whitespace = false;
|
||||||
|
}
|
||||||
|
temp = String::from("");
|
||||||
|
|
||||||
|
// insert_final_newline
|
||||||
|
print!("Insert final newline (true / false): ");
|
||||||
|
io::stdout().flush().unwrap();
|
||||||
|
io::stdin().read_line(&mut temp).unwrap();
|
||||||
|
if temp.trim() == "true" {
|
||||||
|
settings.insert_final_newline = true;
|
||||||
|
} else {
|
||||||
|
settings.insert_final_newline = false;
|
||||||
|
}
|
||||||
|
temp = String::from("");
|
||||||
|
|
||||||
|
// max_line_length
|
||||||
|
print!("Max line length (number): ");
|
||||||
|
io::stdout().flush().unwrap();
|
||||||
|
io::stdin().read_line(&mut temp).unwrap();
|
||||||
|
if temp.trim().parse::<i32>().is_ok() {
|
||||||
|
settings.max_line_length = temp.trim().parse::<i32>().unwrap();
|
||||||
|
} else {
|
||||||
|
settings.max_line_length = 80;
|
||||||
|
}
|
||||||
|
print!("\n");
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_config(path: PathBuf, settings: Settings) -> Result<(), Error> {
|
||||||
|
let mut file = File::create(path)?;
|
||||||
|
let config: Vec<String> = vec![
|
||||||
|
format!("root = {}", settings.root),
|
||||||
|
format!(""),
|
||||||
|
format!("[*]"),
|
||||||
|
format!("end_of_line = {}", settings.end_of_line),
|
||||||
|
format!("indent_size = {}", settings.indent_size),
|
||||||
|
format!("indent_style = {}", settings.indent_style),
|
||||||
|
format!("tab_width = {}", settings.tab_width),
|
||||||
|
format!("charset = {}", settings.charset),
|
||||||
|
format!("trim_trailing_whitespace = {}", settings.trim_trailing_whitespace),
|
||||||
|
format!("insert_final_newline = {}", settings.insert_final_newline),
|
||||||
|
format!("max_line_length = {}", settings.max_line_length),
|
||||||
|
];
|
||||||
|
let w = file.write_all(config.join("\n").as_bytes());
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_settings(str: String) -> Settings {
|
||||||
|
let s: Vec<&str> = str.split_terminator("\n").collect();
|
||||||
|
let mut settings: Settings = Settings {
|
||||||
|
..default_settings()
|
||||||
|
};
|
||||||
|
for x in s.iter() {
|
||||||
|
let kv = x.split("=").collect::<Vec<&str>>();
|
||||||
|
match kv[0].trim() {
|
||||||
|
"end_of_line" => {
|
||||||
|
settings.end_of_line = kv[1].trim().to_string();
|
||||||
|
},
|
||||||
|
"indent_size" => {
|
||||||
|
settings.indent_size = kv[1].trim().parse::<i32>().unwrap();
|
||||||
|
},
|
||||||
|
"indent_style" => {
|
||||||
|
settings.indent_style = kv[1].trim().to_string();
|
||||||
|
},
|
||||||
|
"tab_width" => {
|
||||||
|
settings.tab_width = kv[1].trim().parse::<i32>().unwrap();
|
||||||
|
},
|
||||||
|
"charset" => {
|
||||||
|
settings.charset = kv[1].trim().to_string();
|
||||||
|
},
|
||||||
|
"root" => {
|
||||||
|
settings.root = kv[1].trim().to_string().parse::<bool>().unwrap();
|
||||||
|
},
|
||||||
|
"trim_trailing_whitespace" => {
|
||||||
|
settings.trim_trailing_whitespace = kv[1].trim().parse::<bool>().unwrap();
|
||||||
|
},
|
||||||
|
"insert_final_newline" => {
|
||||||
|
settings.insert_final_newline = kv[1].trim().parse::<bool>().unwrap();
|
||||||
|
},
|
||||||
|
"max_line_length" => {
|
||||||
|
settings.max_line_length = kv[1].trim().parse::<i32>().unwrap();
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
Loading…
Reference in New Issue