client_backend/
lib.rs

1//! # About
2//!
3//! Welcome to the documentation for the Please Package Manager client! This
4//! documentation will provide all of the nessecary information to install, run
5//! and prehaps contribute to this project (named `please-pm-client` from here
6//! on).
7//! # Examples
8//!
9//! ## As a library
10//!
11//! Install the official, dummy `test-package` and view the infomation for it:
12//!
13//! ```rust
14//! use please_pm_client::{get_package_info, install_package};
15//!
16//! fn main() {
17//!     println!(
18//!         "NEW PACKAGE INSTALLED:\n\n{:?}",
19//!         install_package("test-package".to_string(), false, false)
20//!     );
21//!     println!(
22//!         "INFO:\n\n{:?}",
23//!         get_package_info("test-package".to_string(), false)
24//!     );
25//! }
26//! ```
27//!
28//! This will install a new package named "test-package" with only the required
29//! dependencies and will print a fancy output (set `is_verbose` to `false` in
30//! [install_package] if you want a more verbose output).
31//!
32//! This is a basic example and such, it does not implamented the proper
33//! package checking (only debug prints `{:?}`).
34//!
35//! ## Config examples
36//!
37//! #### Basic `please.toml`:
38//!
39//! ```toml
40//! [package] # Basic package metadata
41//! name = "my-test-package" # Name of package (Not optional)
42//! description = "This is a small test package. The name of this should be like-this" # Package description
43//! icon = "logo.png" # The icon file
44//! readme = "README.md" # The readme file
45//!
46//! [dependencies]
47//!     [dependencies.required] # Required dependencies
48//!     node = "4.6.3"
49//!     flask = "2.0.4"
50//!
51//!     [dependencies.optional] # Optional dependencies that user can choose to install
52//!     python3 = "9.4.2"
53//!
54//!     [dependencies.build] # Build dependencies. This will not be uploaded to the api but is a shortcut for a build script
55//!     git = "1.0.2"
56//!     docker = "5.7.2"
57//!
58//! [build]
59//! build_script = "build.sh" # The bash build script (Not optional)
60//! launch_script = "launch.sh" # The launch script that determines how it will run after building
61//! binary_dir = "build/" # The directory where binaries are produced from build_script
62//! binary_pattern = "a.out|my_build" # Regex parsing to get the proper files.
63//! ```
64//!
65//! ##### `please.toml` notes
66//!
67//! - For `binary_pattern`, please see [here](#binary-pattern) for more
68//! information for more complicated binary outputs.
69//! - The only required parts of `please.toml` are the `name` in `[package]`
70//! and the full `[build]` for your package.
71//!
72//! #### Basic `please.json`
73//!
74//! ```json
75//! {
76//!     "package": {
77//!         "name": "my-test-package",
78//!         "description": "This is a small test package. The name of this should be like-this",
79//!         "icon": "logo.png",
80//!         "readme": "README.md"
81//!     },
82//!     "dependencies": {
83//!         "optional": {
84//!             "python3": "9.4.2"
85//!         },
86//!         "build": {
87//!             "git": "1.0.2",
88//!             "docker": "5.7.2"
89//!         },
90//!         "required": {
91//!             "node": "4.6.3",
92//!             "flask": "2.0.4"
93//!         }
94//!     },
95//!     "build": {
96//!         "build_script": "build.sh",
97//!         "launch_script": "launch.sh",
98//!         "binary_dir": "build/",
99//!         "binary_pattern": "a.out|my_build"
100//!     }
101//! }
102//! ```
103//!
104//! ## Basic usage
105//! ### Installing the Client
106//!
107//! #### From source
108//!
109//! 1. Clone the repository: `git clone https://gitlab.com/owez/please-pm-client`
110//! 2. Build the package manager with `cargo build --release`
111//! 3. Head to `please-pm-client/target/release/` and copy the executable named `client-backend`
112//!
113//! #### From [crates.io](https://crates.io/)
114//!
115//! As this repository is under heavy development, there is currently not a
116//! stable *[crates.io]((https://crates.io/))* release. For now, please build
117//! it from source using **[this](#from-source)** guide.
118//!
119
120use std::path::PathBuf;
121
122/// A simple trait for allowing the use of representing something as a string
123/// in an easy and extendible way.
124pub trait StringRep {
125    /// Basic `&str` representation of the generic implamented trait.
126    fn str_rep(&self) -> &'static str;
127
128    /// Customised representation addressing the individual part of the
129    /// implamented trait. If there is none, it is allowed to fall back to
130    /// [StringRep::str_rep].
131    fn string_rep(&self) -> String;
132}
133
134/// Main error enum for Please Package Manager. For more infomation on each
135/// type of Error, please view each of their individual docs.
136///
137/// To easily get a description of each error, please refer to the implament
138/// method that's *coming soon*.
139#[derive(Debug)]
140pub enum ErrorKind {
141    /// When the [publish_package] function didn't get a package path and could
142    /// not determine the current running path. This commonly happens when it
143    /// is being ran directly from functions instead of the API.
144    NoUploadPath,
145
146    /// When the `please.toml`/`please.json` file could not be decoded properly.
147    /// This error should be raised if the toml/json file has incorrect syntax.
148    MetadataDecodeError,
149}
150
151#[allow(non_snake_case, unreachable_patterns)]
152impl StringRep for ErrorKind {
153    /// Represent an error generically, allowing the use of a [str].
154    fn str_rep(&self) -> &'static str {
155        match self {
156            NoUploadPath => "Could not determine what directory to upload!",
157            MetadataDecodeError => "Could not decode the metadata (please.x)!",
158        }
159    }
160
161    /// Represent the [ErrorKind] as a customised error, allowing more
162    /// detailed responses at the cost of using a heap-allocated [String].
163    fn string_rep(&self) -> String {
164        match self {
165            // Add more in this as more with names come
166            _ => String::from(self.str_rep()), // No metadata, this is shortcut
167        }
168    }
169}
170
171/// Gets correctly-formatted infomation on a selected package by.
172///
173/// *NOTE: This function is a frontend and will therefore display a formatted
174/// answer; no matter what*.
175pub fn get_package_info(package_name: String, is_verbose: bool) -> Result<String, ErrorKind> {
176    unimplemented!();
177}
178
179/// Installs a package with the given name (`package_name`).
180///
181/// *NOTE: This function is a frontend and will therefore display a formatted
182/// answer; no matter what*.
183///
184/// # Arguments
185///
186/// - `package_name`: The unique package name.
187/// - `is_verbose`: Should give a verbose/detailed output when installing.
188/// - `install_optional`: If it should install requested optional packages.
189pub fn install_package(
190    package_name: String,
191    is_verbose: bool,
192    install_optional: bool,
193) -> Result<String, ErrorKind> {
194    unimplemented!();
195}
196
197/// Removes a given `package_name`. This function will not succeed if the
198/// package is not installed or is a dependancy (optional or otherwise) to
199/// another package.
200///
201/// `force_remove` foces the removal of a package. This should **not** be used
202/// unless it is an emergency.
203///
204/// *NOTE: This function is a frontend and will therefore display a formatted
205/// answer; no matter what*.
206pub fn remove_package(package_name: String, force_remove: bool) -> Result<String, ErrorKind> {
207    unimplemented!();
208}
209
210/// Publishes a given package path (must be package root & a valid package tree)
211/// to the Please Package Manager API.
212///
213/// If a `path` [PathBuf] is not provided in [Option]<[PathBuf]> is not
214/// provided, it will try to validate the directory the program is running from.
215/// If it cannot find this file, it will return a special error message.
216///
217/// *NOTE: This function is a frontend and will therefore display a formatted
218/// answer; no matter what*.
219pub fn publish_package(path: Option<PathBuf>) -> Result<String, ErrorKind> {
220    unimplemented!();
221}