diff --git a/.github/markdownlint/markdownlint.yaml b/.github/markdownlint/markdownlint.yaml new file mode 100644 index 00000000..01da110c --- /dev/null +++ b/.github/markdownlint/markdownlint.yaml @@ -0,0 +1,38 @@ +# Markdownlint configuration +# refet to the documentation for details: +# - [Linter for markdown](https://github.com/avto-dev/markdown-lint) +# - [Rules configuration](https://github.com/DavidAnson/markdownlint/blob/main/schema/.markdownlint.yaml) +# - [github](https://github.com/markdownlint/markdownlint?tab=readme-ov-file) +# Default state for all rules +default: true + +# Path to configuration file to extend +extends: null + +# MD013/line-length : Line length : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md +MD013: + # Number of characters + line_length: 160 + # Number of characters for headings + heading_line_length: 80 + # Number of characters for code blocks + code_block_line_length: 160 + # Include code blocks + code_blocks: true + # Include tables + tables: true + # Include headings + headings: true + # Strict length checking + strict: false + # Stern length checking + stern: false + +# MD033/no-inline-html : Inline HTML : https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md033.md +MD033: + # Allowed elements + allowed_elements: [ + details, + summary, + ] + \ No newline at end of file diff --git a/.github/workflows/packaging/deb/build.sh b/.github/workflows/packaging/deb/build.sh new file mode 100755 index 00000000..f63a7f1d --- /dev/null +++ b/.github/workflows/packaging/deb/build.sh @@ -0,0 +1,176 @@ +#!/bin/bash +# create a deb package from rust sources +# +############ LIST OF MANAGED VARIABLES REQUIRED FOR DEB PACKAGE ############ +name=api-server +# version=x.y.z - reading from first arg $1 +descriptionShort="API Server wrapping databases, executable and python scripts plugins" +descriptionExtended="API Server - service running on the socket. +Provides simple and universe access to the databases, executable and python plugins. +Wrapping databases: + SQLite + MySQL + PostgreSQL +Runs puthon script: + Python script received some json data via stdin + Python script handle some algorithms + Python script can access to the databases data via self API or directly + Python script returns some json data +Runs binaty executable: + Executable received some json data via stdin + Executable handle some algorithms + Executable can access to the databases data via self API or directly + Executable returns some json data" +changeDetails=" +- TcpServer | clean threads +- Some fixes in the TcpConnection +- ApiQuery moved to the library +" +copyrightNotice="Copyright 2024 anton lobanov" +maintainer="anton lobanov " +licenseName="GNU GENERAL PUBLIC LICENSE v3.0" +licenseFile="LICENSE" + +############ READING VERDION FROM ARGIMENT ############ +RED='\033[0;31m' +NC='\033[0m' # No Color +version=$1 +if [[ "$version" =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then + echo "Version: $version" +else + echo -e "${RED}ERROR${NC}: Version not supplied.\nDebian package build script required proper version of your softvare in the format: x.y.z, passed as argument" +fi +############ LIST OF MANAGED VARIABLES OPTIONAL FOR DEB PACKAGE ############ +# preinst, postinst, prerm and postrm scripts: +preinst="./.github/workflows/packaging/deb/preinst" +postinst="./.github/workflows/packaging/deb/postinst" +prerm="./.github/workflows/packaging/deb/prerm" +postrm="./.github/workflows/packaging/deb/postrm" +# list of assets in the format: +# +assets=( + "./target/release/api-server /usr/bin/ 755", + "./service/api-server.service /etc/systemd/system/ 644" + "./config.yaml /home/scada/api-server/" +) +outputDir=target/ +# 'any', 'all' or one of the supported architecture (e.g., 'amd64', 'arm64', 'i386', 'armhf') +# you can choose one of the provided by `dpkg-architecture -L` or leave the field blank for automatic detection +arch= +# comma separated list of the package dependecies in the following format: +# " [(<<|>>|<=|>=|= )], ..." +# e.g. "foo (>=2.34), bar" +depends="" + +# check required variables +echo "Checking reqired variables ..." +missedVarMsg="non-empty value required" +echo "${!name@}=${name:?$missedVarMsg}" +echo "${!version@}=${version:?$missedVarMsg}" +echo "${!descriptionShort@}=${descriptionShort:?$missedVarMsg}" +echo "${!descriptionExtended@}=${descriptionExtended:?$missedVarMsg}" +echo "${!changeDetails@}=${changeDetails:?$missedVarMsg}" +echo "${!copyrightNotice@}=${copyrightNotice:?$missedVarMsg}" +echo "${!maintainer@}=${maintainer:?$missedVarMsg}" +echo "${!licenseName@}=${licenseName:?$missedVarMsg}" +echo "${!licenseFile@}=${licenseFile:?$missedVarMsg}" + +echo "Start packaging ..." + +############ INITIALIZE THE PACKAGE SOURCE STRUCTURE AND COPY RESOURCES ############ + +arch=${arch:=$(dpkg --print-architecture)} +debFileName="${name}_${version}_${arch}" +packageRoot=$(readlink -m "/tmp/debian/${debFileName}") + +if [[ -d $packageRoot ]]; then + echo "Freeing the directory for temporary build files ..." + rm -rf $packageRoot +fi + +echo "Creating ${packageRoot} directory for temporary build files ..." +mkdir -p "$packageRoot" +echo "Creating ${packageRoot}/DEBIAN directory ..." +mkdir -p "${packageRoot}/DEBIAN" + +copyAsset() { + sourcePath=$1; targetDir=$2; permissions=$3 + assetPath=$(readlink -m "$sourcePath") + if [[ ! -d $assetPath && ! -f $assetPath ]]; then + echo "Asset ${assetPath} not found." + exit 1 + fi + installPath=$(readlink -m "${packageRoot}/${targetDir}") + mkdir -p $installPath && cp -r "$assetPath" "$installPath" + echo "Copying ${assetPath} to ${installPath} ..." + if [[ -d $assetPath ]]; then + chmod -R "$permissions" "$installPath" + elif [[ -f $assetPath ]]; then + chmod "$permissions" "${installPath}/$(basename ${assetPath})" + fi +} +for asset in "${assets[@]}"; do + read -ra assetOptions <<< $asset + copyAsset ${assetOptions[0]} ${assetOptions[1]} ${assetOptions[2]} +done +copyAsset ${preinst} "DEBIAN" "755" +copyAsset ${postinst} "DEBIAN" "755" +copyAsset ${prerm} "DEBIAN" "755" +copyAsset ${postrm} "DEBIAN" "755" + +############ CREATE A DEB CONTROL FILE ############ + +echo "Creating ${packageRoot}/DEBIAN/control file ..." +cat > "${packageRoot}/DEBIAN/control" <<- CONTROL + Section: misc + Priority: optional + Version: $version + Maintainer: $maintainer + Package: $name + Architecture: $arch + Depends: $depends + Description: $descriptionShort + $(echo "$descriptionExtended" | sed "s/^/ /") +CONTROL + +############ CREATE CHANGELOG AND COPYRIGHT FILES ############ + +docDir="${packageRoot}/usr/share/doc/${name}" +mkdir -p "$docDir" + +echo "Generating changelog file ..." +changelogFile="${docDir}/changelog" +cat > "$changelogFile" <<- CHANGELOG + $name ($version) unstable; urgency=medium + + $(echo "$changeDetails" | sed "s/^/ * /") + + $(echo " -- $maintainer $(date -R)") + + +CHANGELOG +gzip -n --best "$changelogFile" +rm -f "$changelogFile" + +echo "Generating copyright file ..." +copyrightFile="${docDir}/copyright" +cat > "$copyrightFile" <<- COPYRIGHT + Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ + Upstream-Name: $name + Copyright: $copyrightNotice + License: $licenseName + $(cat "$licenseFile" | sed "s/^/ /") +COPYRIGHT + +############ CREATE MD5 SUM FILES ############ + +cd $packageRoot +md5sum $(find . -type f -printf "%P\n" | grep -v "^DEBIAN/") > DEBIAN/md5sums +cd - > /dev/null + +############ BUILD A DEB PACKAGE ############ +echo "Building deb package ..." +dpkg-deb --build "${packageRoot}" "$outputDir" > /dev/null || exit 1 +echo "Deleting temporary created ${packageRoot} directory" +# rm -rf "${packageRoot}" +echo "Debian package created and saved in $(readlink -m "${outputDir}/${debFileName}.deb")" \ No newline at end of file diff --git a/.github/workflows/packaging/deb/install-api-server.sh b/.github/workflows/packaging/deb/install-api-server.sh new file mode 100755 index 00000000..e418a9aa --- /dev/null +++ b/.github/workflows/packaging/deb/install-api-server.sh @@ -0,0 +1,26 @@ +#!/bin/bash +rm -rf /tmp/api-server +git clone --progress -b packaging https://github.com/a-givertzman/api-server.git /tmp/api-server +current=$PWD +cd /tmp/api-server + +echo "" +echo "building release..." +cargo build --release + +echo "" +echo "building deb package..." +/tmp/api-server/.github/workflows/packaging/deb/build.sh + +echo "" +echo "installing api server" +sudo apt install -y /tmp/api-server/target/api-server_0.1.15_amd64.deb + +echo "" +echo "enabling api-server service..." +sudo systemctl daemon-reload +sudo systemctl --now enable api-server + +echo "" +echo "cleaning temp files..." +# rm -rf /tmp/api-server diff --git a/.github/workflows/packaging/deb/postinst b/.github/workflows/packaging/deb/postinst new file mode 100755 index 00000000..10a68be7 --- /dev/null +++ b/.github/workflows/packaging/deb/postinst @@ -0,0 +1,19 @@ +#!/bin/bash +# +# Deb package postinst script for API Server +# +echo "" +systemctl daemon-reload +name="api-server" +if [[ $(systemctl list-unit-files --all -t service --full --no-legend "$name.service" | sed 's/^\s*//g' | cut -f1 -d' ') == $name.service ]]; then + if ! systemctl is-enabled --quiet "$name.service" ; then + echo "Enabling $name service..." + systemctl enable api-server + fi + if ! systemctl is-active --quiet "$name.service" ; then + echo "Starting $name service..." + systemctl start api-server + fi +else + echo "$name service - not found" +fi diff --git a/.github/workflows/packaging/deb/postrm b/.github/workflows/packaging/deb/postrm new file mode 100755 index 00000000..c6fefcad --- /dev/null +++ b/.github/workflows/packaging/deb/postrm @@ -0,0 +1,7 @@ +#!/bin/bash +# +# Deb package postrm script for API Server +# +echo "" +echo "Reload systemd manager configuration..." +systemctl daemon-reload diff --git a/.github/workflows/packaging/deb/preinst b/.github/workflows/packaging/deb/preinst new file mode 100755 index 00000000..e6622dbb --- /dev/null +++ b/.github/workflows/packaging/deb/preinst @@ -0,0 +1,16 @@ +#!/bin/bash +# +# Deb package prinst script for API Server +# +echo "" +name="api-server" +if [[ $(systemctl list-units --all -t service --full --no-legend "$name.service" | sed 's/^\s*//g' | cut -f1 -d' ') == $name.service ]]; then + if systemctl is-active --quiet "$name.service" ; then + echo "Stopping $name service..." + systemctl stop api-server + fi + if systemctl is-enabled --quiet "$name.service" ; then + echo "Disabling $name service..." + systemctl disable api-server + fi +fi diff --git a/.github/workflows/packaging/deb/prerm b/.github/workflows/packaging/deb/prerm new file mode 100755 index 00000000..fa5f9961 --- /dev/null +++ b/.github/workflows/packaging/deb/prerm @@ -0,0 +1,16 @@ +#!/bin/bash +# +# Deb package prerem script for API Server +# +echo "" +name="api-server" +if [[ $(systemctl list-units --all -t service --full --no-legend "$name.service" | sed 's/^\s*//g' | cut -f1 -d' ') == $name.service ]]; then + if systemctl is-active --quiet "$name.service" ; then + echo "Stopping $name service..." + systemctl stop api-server + fi + if systemctl is-enabled --quiet "$name.service" ; then + echo "Disabling $name service..." + systemctl disable api-server + fi +fi diff --git a/.github/workflows/packaging/deb/service/api-server.service b/.github/workflows/packaging/deb/service/api-server.service new file mode 100644 index 00000000..3a1bc00a --- /dev/null +++ b/.github/workflows/packaging/deb/service/api-server.service @@ -0,0 +1,17 @@ +[Unit] +Description=API Server +After=syslog.target network.target multi-user.target + +[Service] +User=scada +Type=simple +Restart=always +RestartSec=5 +# WorkingDirectory=/home/scada/api-server/ +ExecStart=api-server --config /home/scada/api-server/config.yaml + +StandardOutput=append:/var/log/api-server.log +StandardError=append:/var/log/api-server.log + +[Install] +WantedBy=multi-user.target diff --git a/.github/workflows/packaging/deb/uninstall-api-server.sh b/.github/workflows/packaging/deb/uninstall-api-server.sh new file mode 100755 index 00000000..1aaa2ae8 --- /dev/null +++ b/.github/workflows/packaging/deb/uninstall-api-server.sh @@ -0,0 +1,27 @@ +#!/bin/bash +echo "" +echo "disabling api-server service..." +sudo systemctl stop api-server +sudo systemctl disable api-server + +echo "" +echo "uninstalling api-server..." +sudo apt purge -y api-server + +echo "" +echo "removing api-server service unit file..." +sudo rm /etc/systemd/system/api-server.service + +echo "" +echo "reloading systemd..." +sudo systemctl daemon-reload +sudo systemctl reset-failed + +# systemctl stop [servicename] +# systemctl disable [servicename] +# rm /etc/systemd/system/[servicename] +# rm /etc/systemd/system/[servicename] # and symlinks that might be related +# rm /usr/lib/systemd/system/[servicename] +# rm /usr/lib/systemd/system/[servicename] # and symlinks that might be related +# systemctl daemon-reload +# systemctl reset-failed diff --git a/.github/workflows/release_deb_package.yaml b/.github/workflows/release_deb_package.yaml new file mode 100644 index 00000000..81f97efd --- /dev/null +++ b/.github/workflows/release_deb_package.yaml @@ -0,0 +1,60 @@ +name: Create release with beb pacage + +on: + pull_request: + # workflow_dispatch: + +env: + TERM: dumb + CARGO_TERM_COLOR: always + API_SERVER_ADDR: '0.0.0.0' + API_SERVER_PORT: 8080 + POSTGRES_PASSWORD: postgres + PYTHON_VERSION: 'python3.10' + +jobs: + build_and_test: + name: Creating new release with beb pacage + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - name: Update version number in the Cargo.toml + run: | + old_version_var=$(cat ./Cargo.toml | sed -rn 's/^version[\t ]*=[\t ]*\"([0-9]+\.[0-9]+\.[0-9]+)\"\s*$/\1/gp') + echo "old version: $old_version_var" + echo "new build: ${{ github.run_number }}" + sed -i -r "s/^(version[\t ]*=[\t ]*\"[0-9]+\.[0-9]+\.)[0-9]+\"\s*$/\1${{ github.run_number }}\"/g" ./Cargo.toml + new_version_var=$(cat ./Cargo.toml | sed -rn 's/^version[\t ]*=[\t ]*\"([0-9]+\.[0-9]+\.[0-9]+)\"\s*$/\1/gp') + echo "new version: $new_version_var" + echo "NEW_VERSION=$new_version_var" >> $GITHUB_ENV + echo "new version: ${{ env.NEW_VERSION }}" + + - name: Build release + run: cargo build --release + + - name: Commit new version ${{ env.NEW_VERSION }} + run: | + echo "on repositiry: ${{ github.repository }}" + git config --global user.name 'anton.lobanov' + git config --global user.email 'lobanov.anton@gmail.com' + git remote set-url origin https://a-givertzman:${{ secrets.RELEASES_TOKEN }}@github.com/${{ github.repository }} + git commit -am "Automated version update to: ${{ env.NEW_VERSION }}" + + - name: Push to protected branch "master" + uses: CasperWA/push-protected@v2 + with: + token: ${{ secrets.RELEASES_TOKEN }} + branch: master + unprotect_reviews: true + + - name: Zip artifact for deployment + run: zip ./target/release/release.zip -r ./target/release/* ./config.yaml ./extensions/* + + - name: Publish release + uses: ncipollo/release-action@v1 + with: + artifacts: "./target/release/release.zip" + tag: internal_v${{ env.NEW_VERSION }} + token: ${{ secrets.RELEASES_TOKEN }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 2ca4b423..b2f1a439 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -16,14 +16,6 @@ jobs: build_and_test: name: Testing runs-on: ubuntu-latest - # strategy: - # matrix: - # toolchain: - # - stable - # - beta - # - nightly - - # Service containers to run with `container-job` services: # Label used to access the service container @@ -55,15 +47,25 @@ jobs: toolchain: stable override: true - # - name: Static analisis - # run: | - # cargo check - # # - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} - # # - run: cargo build --release + - name: Static analysis | Markdown lint tool + uses: docker://avtodev/markdown-lint:v1 + with: + config: '.github/markdownlint/markdownlint.yaml' + args: "**/*.md" + - name: Static analysis | cargo check + run: | + cargo check + - name: Static analysis | cargo clippy + run: | + cargo clippy + # cargo fmt --check + - name: Static analysis | cargo fmt + run: | + echo "escaped for now because of to much of errors, will be turned on later" + # cargo fmt --check - name: Unit tests run: cargo test -- --show-output - - name: Integration tests run: | diff --git a/Cargo.lock b/Cargo.lock index 62439730..fa4b91cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,6 +125,7 @@ dependencies = [ "api-tools", "bytes", "chrono", + "clap", "env_logger", "indexmap 2.2.5", "linked-hash-map", @@ -329,6 +330,46 @@ dependencies = [ "windows-targets 0.52.4", ] +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim 0.11.1", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + [[package]] name = "colorchoice" version = "1.0.0" @@ -380,7 +421,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 2.0.52", ] @@ -598,6 +639,12 @@ dependencies = [ "hashbrown 0.14.3", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hex" version = "0.4.3" @@ -1290,6 +1337,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "subtle" version = "2.5.0" diff --git a/Cargo.toml b/Cargo.toml index ae8998c9..5e55687e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,4 +40,6 @@ rust_decimal = { version = "^1.32", features = [ "tokio-pg" ] } rand = "^0.8" -indexmap = {version = "^2.1", features = ["serde"] } +indexmap = { version = "^2.1", features = ["serde"] } + +clap = { version = "^4.5", features = ["derive"] } diff --git a/src/config.rs b/src/config.rs index 058e8edc..baf45f6c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,5 @@ use log::{trace, debug}; -use std::{fs, collections::HashMap}; +use std::{collections::HashMap, fs, path::Path}; use linked_hash_map::LinkedHashMap; use yaml_rust::{YamlLoader, Yaml}; @@ -12,7 +12,7 @@ pub struct Config { pub services: HashMap, } impl Config { - pub fn new(path: &str) -> Config { + pub fn new

(path: P) -> Config where P: AsRef { match fs::read_to_string(&path) { Ok(yaml_string) => { let yaml_vec = YamlLoader::load_from_str(&yaml_string).unwrap(); @@ -21,7 +21,7 @@ impl Config { let services_vec = yaml_doc["services"] .as_vec() .expect( - format!("Config | error reading 'services' from config file {:?}", &path).as_str(), + format!("Config | error reading 'services' from config file {:?}", path.as_ref()).as_str(), ); for item in services_vec { trace!("Config | service config item: {:?}", item); @@ -33,7 +33,7 @@ impl Config { // debug!("Config | dataBaseConfigMap: {:?}", dataBaseConfigMap); let service_config = ServiceConfig::new(service_config_key, service_config_map); if services.contains_key(&service_config.name) { - panic!("Duplicated service name: \"{}\" in the config: \"{}\"", &service_config.name, path) + panic!("Duplicated service name: '{}' in the config: '{}'", &service_config.name, path.as_ref().display()) } else { // services.insert((&serviceConfig.name).clone(), serviceConfig); services.insert(service_config.name.clone(), service_config); @@ -44,7 +44,7 @@ impl Config { yaml_doc["address"] .as_str() .expect( - format!("Config | error reading 'address' from config file {:?}", &path).as_str(), + format!("Config | error reading 'address' from config file {:?}", path.as_ref()).as_str(), ) ), services, @@ -52,7 +52,7 @@ impl Config { }, Err(err) => { // warn!("File {} reading error: {:?}", path, err); - panic!("File {} reading error: {:?}", path, err) + panic!("File {} reading error: {:?}", path.as_ref().display(), err) }, } } diff --git a/src/core_/cli/cli.rs b/src/core_/cli/cli.rs new file mode 100644 index 00000000..ef1e6231 --- /dev/null +++ b/src/core_/cli/cli.rs @@ -0,0 +1,10 @@ +use clap::Parser; +/// +/// Application cli arguments +#[derive(Parser, Debug)] +#[command(version = "0.1.14", about = "API Server | Wrapping databases, executable and python scripts plugins", long_about = None)] +pub struct Cli { + /// Optional path to configuration file, if omitted 'config.yaml' from current dir will be used + #[arg(short, long)] + pub config: Option, +} \ No newline at end of file diff --git a/src/core_/cli/mod.rs b/src/core_/cli/mod.rs new file mode 100644 index 00000000..5d863fb7 --- /dev/null +++ b/src/core_/cli/mod.rs @@ -0,0 +1 @@ +pub mod cli; \ No newline at end of file diff --git a/src/core_/mod.rs b/src/core_/mod.rs index 1be1de2f..4759196a 100644 --- a/src/core_/mod.rs +++ b/src/core_/mod.rs @@ -1,3 +1,4 @@ pub mod aprox_eq; pub mod debug; // pub mod error; +pub mod cli; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 0ee27667..df499784 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,22 +16,23 @@ mod sql_query_postgre; mod sql_query_mysql; mod tcp_connection; -use std::sync::{Arc, Mutex}; - +use std::{path::{Path, PathBuf}, sync::{Arc, Mutex}}; +use clap::Parser; use log::debug; - use crate::{ - config::Config, - tcp_server::TcpServer, - core_::debug::debug_session::{DebugSession, LogLevel, Backtrace}, + config::Config, core_::{cli::cli::Cli, debug::debug_session::{Backtrace, DebugSession, LogLevel}}, tcp_server::TcpServer }; fn main() { DebugSession::init(LogLevel::Debug, Backtrace::Short); + let cli = Cli::parse(); debug!("starting api server..."); - let dir = std::env::current_dir().unwrap(); - let path: &str = &format!("{}/config.yaml", dir.to_str().unwrap()); - debug!("reading config file: {}", path); + let path = cli.config.map_or_else( + || PathBuf::from("config.yaml"), // || std::env::current_dir().unwrap().join("config.yaml"), + |path| PathBuf::from(path) + ); + let path = Path::new(&path); + debug!("reading config file: {}", path.to_str().unwrap()); let config = Config::new(path); let tcp_server = Arc::new(Mutex::new( TcpServer::new(