Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Add indexing_slicing lint #637

Merged
merged 3 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ members = ["component", "ci/build-channel", "ci/compare-versions"]
[dev-dependencies]
chrono = "0.4.33"
strip-ansi-escapes = "0.2.0"

[lints.clippy]
indexing_slicing = "warn"
7 changes: 5 additions & 2 deletions src/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ pub fn get_latest_version(name: &str) -> Result<Version> {
let response: LatestReleaseApiResponse =
serde_json::from_str(&String::from_utf8_lossy(&data))?;

let version_str = &response.tag_name["v".len()..];
let version_str = response.tag_name.trim_start_matches('v');
let version = Version::parse(version_str)?;
Ok(version)
} else {
Expand Down Expand Up @@ -333,7 +333,10 @@ fn write_response_with_progress_bar<W: Write>(
if bytes_read == 0 {
break;
}
if let Err(e) = writer.write_all(&buffer[..bytes_read]) {
let buf = buffer
.get(..bytes_read)
.ok_or_else(|| anyhow!("Failed to read buffer"))?;
if let Err(e) = writer.write_all(buf) {
log_progress_bar(&progress_bar);
if target.is_empty() {
bail!("Something went wrong writing data: {}", e)
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![cfg_attr(test, allow(clippy::indexing_slicing))]

pub mod channel;
pub mod commands;
pub mod config;
Expand Down
7 changes: 5 additions & 2 deletions src/ops/fuelup_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
toolchain::{DistToolchainDescription, Toolchain},
};
use ansiterm::Color;
use anyhow::Result;
use anyhow::{anyhow, Result};
use component::{self, Components};
use semver::Version;
use std::collections::HashMap;
Expand Down Expand Up @@ -114,7 +114,10 @@ fn check_toolchain(toolchain: &str, verbose: bool) -> Result<()> {

if !plugin.is_main_executable() {
print!("{:>2}", "");
plugin_name = &plugin.executables[index];
plugin_name = plugin
.executables
.get(index)
.ok_or_else(|| anyhow!("Plugin name not found"))?;
}

let maybe_latest_version = plugin.publish.map_or_else(
Expand Down
6 changes: 3 additions & 3 deletions src/proxy_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ pub fn proxy_run(arg0: &str) -> Result<ExitCode> {
let cmd_args: Vec<_> = env::args_os().skip(1).collect();
let toolchain = Toolchain::from_settings()?;

if !cmd_args.is_empty() {
let plugin = format!("{}-{}", arg0, &cmd_args[0].to_string_lossy());
if let Some(first_arg) = cmd_args.first() {
let plugin = format!("{}-{}", arg0, first_arg.to_string_lossy());
if Components::collect_plugin_executables()?.contains(&plugin) {
direct_proxy(&plugin, &cmd_args[1..], &toolchain)?;
direct_proxy(&plugin, cmd_args.get(1..).unwrap_or_default(), &toolchain)?;
}
}

Expand Down
164 changes: 122 additions & 42 deletions src/toolchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,23 @@ fn consume_back<T>(parts: &mut VecDeque<T>, number: usize) {
}
}

/// Attempts to parse a date from the front of the parts list, returning the date and consuming the
/// date parts if they are available
/// Attempts to parse a date from the end of the parts list, returning the date and consuming the
/// date parts if they are available.
fn extract_date(parts: &mut VecDeque<&str>) -> Option<Date> {
let len = parts.len();
if len < 3 {
return None;
}

let date_str = format!("{}-{}-{}", parts[len - 3], parts[len - 2], parts[len - 1]);
let date_str = parts
.iter()
.rev()
.take(3)
.cloned()
.rev()
.collect::<Vec<&str>>()
.join("-");

match Date::parse(&date_str, DATE_FORMAT) {
Ok(d) => {
consume_back(parts, 3);
Expand All @@ -122,41 +130,33 @@ fn extract_date(parts: &mut VecDeque<&str>) -> Option<Date> {
}
}

/// Attemps to parse the target from a vector of parts, returning the target and consuming the
/// target parts if they are available
/// Attempts to parse the target from the end of the parts list, returning the target and consuming the
/// target parts if they are available.
fn extract_target(parts: &mut VecDeque<&str>) -> Option<TargetTriple> {
if parts.len() < 3 {
return None;
}

let len = parts.len();
let target_str = format!("{}-{}-{}", parts[len - 3], parts[len - 2], parts[len - 1]);
match TargetTriple::new(&target_str) {
Ok(t) => {
consume_back(parts, 3);
Some(t)
fn try_extract(parts: &mut VecDeque<&str>, count: usize) -> Option<TargetTriple> {
if parts.len() < count {
return None;
}
Err(_) => {
if parts.len() < 4 {
return None;
}

let target_str = format!(
"{}-{}-{}-{}",
parts[len - 4],
parts[len - 3],
parts[len - 2],
parts[len - 1]
);
match TargetTriple::new(&target_str) {
Ok(t) => {
consume_back(parts, 4);
Some(t)
}
Err(_) => None,
let target_str: String = parts
.iter()
.rev()
.take(count)
.cloned()
.rev()
.collect::<Vec<&str>>()
.join("-");

match TargetTriple::new(&target_str) {
Ok(t) => {
consume_back(parts, count);
Some(t)
}
Err(_) => None,
}
}

try_extract(parts, 3).or_else(|| try_extract(parts, 4))
}

/// Parses a distributable toolchain description from a string.
Expand All @@ -177,12 +177,16 @@ impl FromStr for DistToolchainDescription {
}

let mut parts = s.split('-').collect::<VecDeque<_>>();

match parts.len() {
1 => Ok(Self {
name: DistToolchainName::from_str(parts[0])?,
target: TargetTriple::from_host().ok(),
date: None,
}),
1 => {
let first_part = *parts.front().unwrap_or(&"");
Ok(Self {
name: DistToolchainName::from_str(first_part)?,
target: TargetTriple::from_host().ok(),
date: None,
})
}
_ => {
let date = extract_date(&mut parts);
let target = extract_target(&mut parts);
Expand Down Expand Up @@ -420,11 +424,13 @@ impl Toolchain {

Ok(())
}
fn remove_executables(&self, component: &str) -> Result<()> {
let executables = &Components::collect().unwrap().component[component].executables;
for executable in executables {
remove_file(self.bin_path.join(executable))
.with_context(|| format!("failed to remove executable '{executable}'"))?;
fn remove_executables(&self, component_name: &str) -> Result<()> {
let components = Components::collect()?;
if let Some(component) = components.component.get(component_name) {
for executable in &component.executables {
remove_file(self.bin_path.join(executable))
.with_context(|| format!("failed to remove executable '{executable}'"))?;
}
}
Ok(())
}
Expand Down Expand Up @@ -673,4 +679,78 @@ mod tests {
DistToolchainDescription::from_str(channel).expect_err("invalid channel");
}
}

#[test]
fn test_extract_target_with_three_parts() {
let mut parts: VecDeque<&str> = VecDeque::from(vec!["aarch64", "apple", "darwin"]);
let target = extract_target(&mut parts).expect("target triple");
assert_eq!(target.to_string(), "aarch64-apple-darwin");
assert!(parts.is_empty()); // Ensure parts are consumed
}

#[test]
fn test_extract_target_with_four_parts() {
let mut parts: VecDeque<&str> = VecDeque::from(vec!["x86_64", "unknown", "linux", "gnu"]);
let target = extract_target(&mut parts).expect("target triple");
assert_eq!(target.to_string(), "x86_64-unknown-linux-gnu");
assert!(parts.is_empty()); // Ensure parts are consumed
}

#[test]
fn test_extract_target_with_five_parts() {
let mut parts: VecDeque<&str> =
VecDeque::from(vec!["my", "custom", "aarch64", "apple", "darwin"]);
let target = extract_target(&mut parts).expect("target triple");
assert_eq!(target.to_string(), "aarch64-apple-darwin");
assert_eq!(parts.len(), 2); // Ensure 3 parts were consumed
}

#[test]
fn test_extract_target_with_insufficient_parts() {
let mut parts: VecDeque<&str> = VecDeque::from(vec!["apple", "darwin"]);
assert!(extract_target(&mut parts).is_none());
assert_eq!(parts.len(), 2); // Ensure parts are not consumed
}

#[test]
fn test_extract_target_with_invalid_target() {
let mut parts: VecDeque<&str> = VecDeque::from(vec!["invalid", "target", "string"]);
assert!(extract_target(&mut parts).is_none());
assert_eq!(parts.len(), 3); // Ensure parts are not consumed

let mut parts: VecDeque<&str> =
VecDeque::from(vec!["still", "invalid", "target", "string"]);
assert!(extract_target(&mut parts).is_none());
assert_eq!(parts.len(), 4); // Ensure parts are not consumed
}

#[test]
fn test_extract_date_with_valid_date() {
let mut parts: VecDeque<&str> = VecDeque::from(vec!["2022", "12", "25"]);
let date = extract_date(&mut parts).expect("date");
assert_eq!(date.to_string(), "2022-12-25");
assert!(parts.is_empty()); // Ensure all parts are consumed
}

#[test]
fn test_extract_date_with_insufficient_parts() {
let mut parts: VecDeque<&str> = VecDeque::from(vec!["2022", "12"]);
assert!(extract_date(&mut parts).is_none());
assert_eq!(parts.len(), 2); // Ensure parts are not consumed
}

#[test]
fn test_extract_date_with_invalid_date() {
let mut parts: VecDeque<&str> = VecDeque::from(vec!["12", "25", "2022"]);
assert!(extract_date(&mut parts).is_none());
assert_eq!(parts.len(), 3); // Ensure parts are not consumed
}

#[test]
fn test_extract_date_with_extra_parts() {
let mut parts: VecDeque<&str> = VecDeque::from(vec!["extra", "2022", "12", "25"]);
let date = extract_date(&mut parts).expect("date");
assert_eq!(date.to_string(), "2022-12-25");
assert_eq!(parts.len(), 1); // Ensure only the date parts are consumed
}
}
1 change: 1 addition & 0 deletions src/toolchain_override.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ impl ToolchainOverride {
Ok(Self { cfg, path })
}

#[allow(clippy::indexing_slicing)]
pub fn to_toml(&self) -> Document {
let mut document = toml_edit::Document::new();

Expand Down
Loading