mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-05 09:13:28 +00:00
[ENG-134] OSS Licenses and Projects (#575)
* add `deps-generator` crate
* move `clap` types to separate file
* idiomatic filtering
* experimentally update ci
* add *really* basic dependency page
* remove `license_id` from `License`
* add bare minimum JSON files
* Revert "experimentally update ci"
This reverts commit c04897d902
.
* re-insert comments
* Using reqwest blocking feature to avoid asyncness
---------
Co-authored-by: Ericson Soares <ericson.ds999@gmail.com>
This commit is contained in:
parent
e9e8d2286c
commit
4cc582e08c
40
Cargo.lock
generated
40
Cargo.lock
generated
|
@ -451,6 +451,12 @@ version = "0.20.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.5.2"
|
||||
|
@ -732,6 +738,20 @@ dependencies = [
|
|||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.15.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08a1ec454bc3eead8719cb56e15dbbfecdbc14e4b3a3ae4936cc6e31f5fc0d07"
|
||||
dependencies = [
|
||||
"camino",
|
||||
"cargo-platform",
|
||||
"semver 1.0.14",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo_toml"
|
||||
version = "0.11.8"
|
||||
|
@ -1453,6 +1473,18 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deps-generator"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cargo_metadata 0.15.3",
|
||||
"clap",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.2.0"
|
||||
|
@ -5219,11 +5251,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.12"
|
||||
version = "0.11.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc"
|
||||
checksum = "21eed90ec8570952d53b772ecf8f206aa1ec9a3d76b2521c56c42973f2d91ee9"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"base64 0.21.0",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
|
@ -6104,7 +6136,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8"
|
||||
dependencies = [
|
||||
"bytecount",
|
||||
"cargo_metadata",
|
||||
"cargo_metadata 0.14.2",
|
||||
"error-chain",
|
||||
"glob",
|
||||
"pulldown-cmark",
|
||||
|
|
14
crates/deps-generator/Cargo.toml
Normal file
14
crates/deps-generator/Cargo.toml
Normal file
|
@ -0,0 +1,14 @@
|
|||
[package]
|
||||
name = "deps-generator"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
authors = ["Jake Robinson <jake@spacedrive.com>"]
|
||||
description = "A tool to compile all Spacedrive dependencies and their respective licenses"
|
||||
|
||||
[dependencies]
|
||||
reqwest = { version = "0.11.14", features = ["blocking"] }
|
||||
clap = { version = "4.0.32", features = ["derive"] }
|
||||
anyhow = "1.0.68"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
cargo_metadata = "0.15.3"
|
75
crates/deps-generator/src/main.rs
Normal file
75
crates/deps-generator/src/main.rs
Normal file
|
@ -0,0 +1,75 @@
|
|||
use anyhow::Result;
|
||||
use cargo_metadata::CargoOpt;
|
||||
use clap::Parser;
|
||||
use std::{fs::File, path::PathBuf};
|
||||
use types::{
|
||||
backend::BackendDependency,
|
||||
cli::{Action, Arguments},
|
||||
frontend::FrontendDependency,
|
||||
};
|
||||
|
||||
pub mod types;
|
||||
|
||||
const FOSSA_BASE_URL: &str =
|
||||
"https://app.fossa.com/api/revisions/git%2Bgithub.com%2Fspacedriveapp%2Fspacedrive%24";
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let args = Arguments::parse();
|
||||
|
||||
match args.action {
|
||||
Action::Frontend(sub_args) => write_frontend_deps(sub_args.revision, sub_args.path),
|
||||
Action::Backend(sub_args) => {
|
||||
write_backend_deps(sub_args.manifest_path, sub_args.output_path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn write_backend_deps(manifest_path: PathBuf, output_path: PathBuf) -> Result<()> {
|
||||
let cmd = cargo_metadata::MetadataCommand::new()
|
||||
.manifest_path(manifest_path)
|
||||
.features(CargoOpt::AllFeatures)
|
||||
.exec()?;
|
||||
|
||||
let deps: Vec<BackendDependency> = cmd
|
||||
.packages
|
||||
.into_iter()
|
||||
.filter_map(|p| {
|
||||
(!cmd.workspace_members.iter().any(|t| &p.id == t)).then_some(BackendDependency {
|
||||
title: p.name,
|
||||
description: p.description,
|
||||
url: p.repository,
|
||||
version: p.version.to_string(),
|
||||
authors: p.authors,
|
||||
license: p.license,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut file = File::create(output_path)?;
|
||||
serde_json::to_writer(&mut file, &deps)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_frontend_deps(rev: String, path: PathBuf) -> Result<()> {
|
||||
let url = format!("{FOSSA_BASE_URL}{rev}/dependencies");
|
||||
|
||||
let response = reqwest::blocking::get(url)?.text()?;
|
||||
let json: Vec<types::frontend::Dependency> = serde_json::from_str(&response)?;
|
||||
|
||||
let deps: Vec<_> = json
|
||||
.into_iter()
|
||||
.map(|dep| FrontendDependency {
|
||||
title: dep.project.title,
|
||||
authors: dep.project.authors,
|
||||
description: dep.project.description,
|
||||
url: dep.project.url,
|
||||
license: dep.licenses,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut file = File::create(path)?;
|
||||
serde_json::to_writer(&mut file, &deps)?;
|
||||
|
||||
Ok(())
|
||||
}
|
12
crates/deps-generator/src/types/backend.rs
Normal file
12
crates/deps-generator/src/types/backend.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
use serde::Serialize;
|
||||
|
||||
#[allow(clippy::module_name_repetitions)]
|
||||
#[derive(Serialize)]
|
||||
pub struct BackendDependency {
|
||||
pub title: String,
|
||||
pub description: Option<String>,
|
||||
pub url: Option<String>,
|
||||
pub version: String,
|
||||
pub authors: Vec<String>,
|
||||
pub license: Option<String>,
|
||||
}
|
33
crates/deps-generator/src/types/cli.rs
Normal file
33
crates/deps-generator/src/types/cli.rs
Normal file
|
@ -0,0 +1,33 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
|
||||
#[derive(Parser)]
|
||||
pub struct Arguments {
|
||||
#[command(subcommand)]
|
||||
pub action: Action,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum Action {
|
||||
Frontend(FrontendArgs),
|
||||
Backend(BackendArgs),
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct FrontendArgs {
|
||||
// could source this from `$GITHUB_SHA` for CI, if not set
|
||||
#[arg(help = "the git revision")]
|
||||
pub revision: String,
|
||||
#[arg(help = "the output path")]
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct BackendArgs {
|
||||
// could use `Cargo.toml` as the default from current dir (if not set)
|
||||
#[arg(help = "path to the cargo manifest")]
|
||||
pub manifest_path: PathBuf,
|
||||
#[arg(help = "the output path")]
|
||||
pub output_path: PathBuf,
|
||||
}
|
36
crates/deps-generator/src/types/frontend.rs
Normal file
36
crates/deps-generator/src/types/frontend.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Dependency {
|
||||
pub project: Project,
|
||||
pub licenses: Vec<License>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Project {
|
||||
// pub locator: Option<String>,
|
||||
pub title: String,
|
||||
pub description: Option<String>,
|
||||
pub url: Option<String>,
|
||||
pub authors: Vec<Option<String>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct License {
|
||||
pub text: Option<String>,
|
||||
// pub license_id: Option<String>, // always null AFAIK
|
||||
pub copyright: Option<String>,
|
||||
// pub license_group_id: i64,
|
||||
// pub ignored: bool, // always false from my testing
|
||||
// pub revision_id: Option<String>,
|
||||
}
|
||||
|
||||
#[allow(clippy::module_name_repetitions)]
|
||||
#[derive(Serialize)]
|
||||
pub struct FrontendDependency {
|
||||
pub title: String,
|
||||
pub description: Option<String>,
|
||||
pub url: Option<String>,
|
||||
pub authors: Vec<Option<String>>,
|
||||
pub license: Vec<License>,
|
||||
}
|
3
crates/deps-generator/src/types/mod.rs
Normal file
3
crates/deps-generator/src/types/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
pub mod backend;
|
||||
pub mod cli;
|
||||
pub mod frontend;
|
10
packages/assets/deps/backend-deps.json
Normal file
10
packages/assets/deps/backend-deps.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
[
|
||||
{
|
||||
"title": "Placeholder",
|
||||
"description": "",
|
||||
"url": "https://spacedrive.com",
|
||||
"version": "0.0.0",
|
||||
"authors": [""],
|
||||
"license": ""
|
||||
}
|
||||
]
|
14
packages/assets/deps/frontend-deps.json
Normal file
14
packages/assets/deps/frontend-deps.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
[
|
||||
{
|
||||
"title": "Placeholder",
|
||||
"description": "",
|
||||
"url": "https://spacedrive.com",
|
||||
"authors": [""],
|
||||
"license": [
|
||||
{
|
||||
"text": "",
|
||||
"copyright": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -2,6 +2,7 @@ import {
|
|||
Books,
|
||||
FlyingSaucer,
|
||||
GearSix,
|
||||
Graph,
|
||||
HardDrive,
|
||||
Heart,
|
||||
Key,
|
||||
|
@ -83,6 +84,10 @@ export const SettingsSidebar = () => {
|
|||
<SettingsIcon component={Receipt} />
|
||||
Changelog
|
||||
</SidebarLink>
|
||||
<SidebarLink to="/settings/dependencies">
|
||||
<SettingsIcon component={Graph} />
|
||||
Dependencies
|
||||
</SidebarLink>
|
||||
<SidebarLink to="/settings/support">
|
||||
<SettingsIcon component={Heart} />
|
||||
Support
|
||||
|
|
|
@ -26,6 +26,7 @@ const routes: RouteProps[] = [
|
|||
{ path: 'privacy', element: lazyEl(() => import('./client/PrivacySettings')) },
|
||||
{ path: 'about', element: lazyEl(() => import('./info/AboutSpacedrive')) },
|
||||
{ path: 'changelog', element: lazyEl(() => import('./info/Changelog')) },
|
||||
{ path: 'dependencies', element: lazyEl(() => import('./info/Dependencies')) },
|
||||
{ path: 'support', element: lazyEl(() => import('./info/Support')) }
|
||||
];
|
||||
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import { useQuery } from '@tanstack/react-query';
|
||||
import { ScreenHeading } from '@sd/ui';
|
||||
import { usePlatform } from '~/util/Platform';
|
||||
|
||||
export default function DependenciesScreen() {
|
||||
const frontEnd = useQuery(['frontend-deps'], () => import('@sd/assets/deps/frontend-deps.json'));
|
||||
const backEnd = useQuery(['backend-deps'], () => import('@sd/assets/deps/backend-deps.json'));
|
||||
const platform = usePlatform();
|
||||
|
||||
return (
|
||||
<div className="flex flex-col w-full h-screen p-5 custom-scroll page-scroll app-background">
|
||||
<ScreenHeading>Dependencies</ScreenHeading>
|
||||
|
||||
{/* item has a LOT more data that we can display, i just went with the basics */}
|
||||
|
||||
<ScreenHeading className="mb-2">Frontend Dependencies</ScreenHeading>
|
||||
<div className="grid gap-6 space-x-1 xl:grid-cols-4 2xl:grid-cols-6">
|
||||
{frontEnd.data &&
|
||||
frontEnd.data?.default.map((item) => {
|
||||
return (
|
||||
<a key={item.title} onClick={() => platform.openLink(item.url ?? '')}>
|
||||
<div className="px-4 py-4 text-gray-300 border-2 border-gray-500 rounded">
|
||||
<h4 className="text-center">
|
||||
{item.title.trimEnd().substring(0, 24) + (item.title.length > 24 ? '...' : '')}
|
||||
</h4>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<ScreenHeading className="mb-2">Backend Dependencies</ScreenHeading>
|
||||
<div className="grid gap-6 space-x-1 lg:grid-cols-7">
|
||||
{backEnd.data &&
|
||||
backEnd.data?.default.map((item) => {
|
||||
return (
|
||||
<a key={item.title} onClick={() => platform.openLink(item.url ?? '')}>
|
||||
<div className="px-4 py-4 text-gray-300 border-2 border-gray-500 rounded">
|
||||
<h4 className="text-center">{item.title.trimEnd()}</h4>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
Loading…
Reference in a new issue