Skip to content

Commit

Permalink
Added demo code logic
Browse files Browse the repository at this point in the history
  • Loading branch information
MadL1me committed May 1, 2024
1 parent 04c4a5c commit 21ebff6
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 110 deletions.
3 changes: 3 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
ar = "x86_64-w64-mingw32-gcc-ar"
53 changes: 0 additions & 53 deletions .vscode/launch.json

This file was deleted.

12 changes: 12 additions & 0 deletions Formula/hemlock.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Hemlock < Formula
desc "Vendor remote files to local folder - CLI"
homepage "<https://github.com/bharathvaj-ganesan/getfilesize-cli>"
url "<https://github.com/bharathvaj-ganesan/getfilesize-cli/releases/download/v1.0.1/getfilesize.tar.gz>"
sha256 "6c03100f5b1f8e61f5d49efab759a2efcdbcc4ac2677fcf98e7317ec660e6994"
license "MIT"
version "1.0.1"

def install
bin.install "hemlock"
end
end
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
build-add: build-linux build-mac build-x86_64_windows

build-linux:
cargo build --release --target=xy

build-mac:
cargo build --release --target=x86_64-pc-windows-gnu

build-x86_64_windows:
cargo build --release --target=x86_64-pc-windows-gnu

calc-sha:
shasum -a 256 getfilesize.tar.gz

.PHONY: build-linux \
4 changes: 2 additions & 2 deletions hemlock.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: 1
vendor_dir: vendor2
vendor_dir: vendor
external_deps:
- github.com/bufbuild/protoc-gen-validate/validate/validate.proto@master
- github.com/MadL1me/RhythmGE/src/index.scss@68f7379
28 changes: 28 additions & 0 deletions src/errors/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use std::fmt;

#[derive(Debug)]
pub struct ErrorBase {
details: String,
}

impl ErrorBase {
pub fn new(msg: &str) -> ErrorBase {
ErrorBase { details: msg.to_string() }
}

pub fn new_box(msg: &str) -> Box<ErrorBase> {
Box::new(ErrorBase::new(msg))
}
}

impl fmt::Display for ErrorBase {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.details)
}
}

impl std::error::Error for ErrorBase {
fn description(&self) -> &str {
&self.details
}
}
150 changes: 95 additions & 55 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use std::{fs::{self, File}, io, os::macos::raw, path::PathBuf};
mod errors;
use crate::errors::ErrorBase;

use std::{fs::{self, File}, io, path::PathBuf};
use reqwest::blocking::Client;
use clap::Parser;
use serde::{Deserialize, Serialize};
Expand All @@ -21,16 +24,20 @@ struct CliArgs {
#[derive(Debug, Serialize, Deserialize)]
struct YamlConfigV1 {
version: String,
vendor_dir: String,
vendor_dir: Option<String>,

#[serde(default)]
local_deps: Vec<String>,

#[serde(default)]
external_deps: Vec<String>,
}

type ErrTrait = Box<dyn std::error::Error>;
type AnyError = Box<dyn std::error::Error>;

fn main() -> Result<(), ErrTrait> {
fn main() -> Result<(), AnyError> {
let args = CliArgs::parse();

// Check if the config path was provided
let config_path = args.config.ok_or("No config path provided")?;

Expand All @@ -39,36 +46,31 @@ fn main() -> Result<(), ErrTrait> {
.map_err(|err| format!("Failed to read the config file: {}", err))?;

// Parse the YAML content
let config: YamlConfigV1 = serde_yaml::from_str(&file_res)
let mut config: YamlConfigV1 = serde_yaml::from_str(&file_res)
.map_err(|err| format!("Failed to parse config: {}", err))?;

// Use the parsed config (here, just printing it)
if args.verbose {
println!("Verbose mode enabled");
}

if config.vendor_dir.is_none() {
config.vendor_dir = Some(String::from("vendor_dir"));
}

println!("Config loaded successfully: {:?}", config);

for remote_dep in config.external_deps {
download_locally(&remote_dep[..], &config.vendor_dir[..], args.verbose)?;
download_locally(&remote_dep[..], &config.vendor_dir.as_ref().unwrap()[..], args.verbose)?;
}

Ok(())
}

fn download_locally(url: &str, dir: &str, verbose: bool) -> Result<&'static str, ErrTrait> {
let download_src: Result<String, &'static str>;

match source_matcher(&url) {
SourceOrigin::GitHub => download_src = github_to_raw(&url),
SourceOrigin::GitLab => todo!(),
SourceOrigin::Unknown => todo!(),
}

let raw_url = download_src
.map_err(|err| format!("Failed to read the config file: {err}"))?;
fn download_locally(url: &str, dir: &str, verbose: bool) -> Result<&'static str, AnyError> {
let source = RemoteFileSource::from_url(url)?;

let response = Client::new().get(&raw_url).send()?;
let response = Client::new().get(source.download_url).send()?;

let filename = url.split('/').last().ok_or("Error")?;

Expand All @@ -88,7 +90,70 @@ fn download_locally(url: &str, dir: &str, verbose: bool) -> Result<&'static str,
println!("Failed to download file: HTTP {}", response.status());
}

Ok("123")
Ok("successfully donwloaded a file")
}

pub struct RemoteFileSource {
original_url: String,
source_origin: SourceOrigin,

user: String,
repo: String,
commit_or_branch: String,
download_url: String,
}

impl RemoteFileSource {
pub fn from_url(url: &str) -> Result<RemoteFileSource, AnyError> {
let source_origin = SourceOrigin::source_matcher(url);
let result: Result<RemoteFileSource, AnyError>;

match source_origin {
SourceOrigin::GitHub => return RemoteFileSource::github_to_raw(url),
SourceOrigin::GitLab => todo!(),
SourceOrigin::Unknown => todo!(),
};
}

fn github_to_raw(url: &str) -> Result<RemoteFileSource, AnyError> {
let re = Regex::new(r"(?xi)
^(?:https?://)?github\.com/
(?P<user>[^/]+)
/(?P<repo>[^/]+)
/(?:blob/(?P<hash>[a-f0-9]{40})/)?(?P<path>.+?)(?:@(?P<commit_or_branch>[^@]+))?$
").unwrap();

if let Some(caps) = re.captures(url) {
let user = caps.name("user").unwrap().as_str();
let repo = caps.name("repo").unwrap().as_str();
let path = caps.name("path").unwrap().as_str();

// Determine the branch or commit hash
let commit_or_branch = match (caps.name("hash"), caps.name("commit_or_branch")) {
(Some(hash), _) => hash.as_str(), // Hash from blob format takes precedence
(_, Some(commit_or_branch)) => commit_or_branch.as_str(),
_ => "master", // Default branch if none specified
};

let raw_url = format!(
"https://raw.githubusercontent.com/{}/{}/{}/{}",
user, repo, commit_or_branch, path
);

println!("{raw_url}");

Ok(RemoteFileSource{
commit_or_branch: commit_or_branch.to_owned(),
download_url: raw_url.to_owned(),
repo: repo.to_owned(),
original_url: url.to_owned(),
user: user.to_owned(),
source_origin: SourceOrigin::GitHub
})
} else {
Err(ErrorBase::new_box("Invalid GitHub URL"))
}
}
}

enum SourceOrigin {
Expand All @@ -97,44 +162,19 @@ enum SourceOrigin {
Unknown,
}

fn source_matcher(url: &str) -> SourceOrigin {
if url.contains("github.com") {
SourceOrigin::GitHub
} else if url.contains("gitlab.com") {
SourceOrigin::GitLab
} else {
SourceOrigin::Unknown
impl SourceOrigin {
fn source_matcher(url: &str) -> SourceOrigin {
if url.contains("github.com") {
SourceOrigin::GitHub
} else if url.contains("gitlab.com") {
SourceOrigin::GitLab
} else {
SourceOrigin::Unknown
}
}
}

fn github_to_raw(url: &str) -> Result<String, &'static str> {
let re = Regex::new(r"(?x)
^(?:https?://)?github\.com/
(?P<user>[^/]+)
/(?P<repo>[^/]+)
/(?P<path>blob/)?(?P<branch>[^/]+)?
/(?P<file_path>.+?)(?:@(?P<commit>[a-f0-9]{40}))?$
").unwrap();

if let Some(caps) = re.captures(url) {
let user = caps.name("user").unwrap().as_str();
let repo = caps.name("repo").unwrap().as_str();
let file_path = caps.name("file_path").unwrap().as_str();
let branch = caps.name("branch").map_or("master", |m| m.as_str());
let commit = caps.name("commit").map_or(branch, |m| m.as_str());

let raw_url = format!(
"https://raw.githubusercontent.com/{}/{}/{}/{}",
user, repo, commit, file_path
);

println!("{raw_url}");

Ok(raw_url)
} else {
Err("Invalid GitHub URL")
}
}
// All cases needs to be addressed:

// https://github.com/MadL1me/RhythmGE/blob/68f7379aa960a365d7eb61577d536307334a4e2e/src/index.scss
// http://github.com/MadL1me/RhythmGE/blob/68f7379aa960a365d7eb61577d536307334a4e2e/src/index.scss
Expand Down

0 comments on commit 21ebff6

Please sign in to comment.