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}