Skip to content

Commit

Permalink
ci: enforce copyright boilerplate (#58)
Browse files Browse the repository at this point in the history
In this pass we can handle Rust, Go, YAML, and TOML files.  We ignore
testdata files, markdown, and mustache.
  • Loading branch information
coryan authored Oct 31, 2024
1 parent 3c8b542 commit 3e12221
Show file tree
Hide file tree
Showing 12 changed files with 278 additions and 5 deletions.
14 changes: 14 additions & 0 deletions .github/workflows/generator.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Client Generator

on: [push, pull_request]
Expand Down
28 changes: 28 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Lint

on: [push, pull_request]
Expand All @@ -18,3 +32,17 @@ jobs:
cargo install typos-cli --version 1.26.8
- run:
typos

misc-formatting:
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: |
~/.cargo
key: ${{ github.job }}-${{ runner.os }}-cargo-${{ hashFiles('Cargo.lock') }}
- run: |
git ls-files -z -- '*.yaml$' '*.toml$' '*.go$' '*.rs$' ':!:**/testdata/**' ':!:**.md' ':!:**.mustache' | \
xargs -0 cargo run --release --bin check-copyright
14 changes: 14 additions & 0 deletions .github/workflows/sdk.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Rust SDK

on: [push, pull_request]
Expand Down
45 changes: 45 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 15 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

[workspace]
resolver = "2"

members = ["auth", "types"]
members = ["auth", "tools/check-copyright", "types"]
14 changes: 14 additions & 0 deletions auth/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

[package]
name = "google-cloud-auth"
version = "0.1.0"
Expand Down
2 changes: 1 addition & 1 deletion generator/all_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
Expand Down
21 changes: 21 additions & 0 deletions tools/check-copyright/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

[package]
name = "check-copyright"
version = "0.1.0"
edition = "2021"

[dependencies]
regex = "1.11.1"
123 changes: 123 additions & 0 deletions tools/check-copyright/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use regex::Regex;
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
let checker = Checker::new()?;

let (_success, errors): (Vec<_>, Vec<_>) = std::env::args()
.skip(1)
.map(|filename| {
let r = checker.verify(&filename);
(filename, r)
})
.partition(|(_, b)| b.is_ok());

for (filename, result) in errors.iter() {
eprintln!("Error searching for copyright boiler plate in {filename}: {result:?}");
}
let _ = errors
.into_iter()
.map(|(_, b)| b)
.collect::<Result<Vec<()>, _>>()?;
Ok(())
}

struct Checker {
copyright: Regex,
boilerplate: Vec<String>,
}

impl Checker {
fn new() -> Result<Checker, Box<dyn Error>> {
const COPYRIGHT_RE: &str = "^ Copyright [0-9]{4} Google LLC$";

let boilerplate = Self::load_boilerplate(file!())?;
// Just panic on failures to compile the RE.
let copyright = Regex::new(COPYRIGHT_RE).unwrap();
Ok(Self {
boilerplate,
copyright,
})
}

fn verify(&self, filename: &str) -> Result<(), Box<dyn Error>> {
let found = Self::load_boilerplate(filename)?;
let mut lines = found.into_iter();
if let Some(first) = lines.next() {
if !self.copyright.is_match(&first) {
return Err(format!("Missing copyright in first line, found={first}"))?;
}
} else {
return Err("Could not read any boilerplate lines".to_string())?;
}

let first_mismatch = lines
.zip(self.boilerplate[1..].iter())
// Humans prefer "line 1" vs. "line 0", and we already consumed the first line.
.zip(2..)
.filter_map(|((found, expected), lineno)| {
if &found == expected {
None
} else {
Some((lineno, found, expected))
}
})
.map(|(lineno, found, expected)| {
format!(
"Mismatched boilerplate in line {lineno}, found={found}, expected={expected}"
)
})
.nth(0);
if let Some(msg) = first_mismatch {
return Err(msg)?;
}

Ok(())
}

fn load_boilerplate(filename: &str) -> Result<Vec<String>, Box<dyn Error>> {
let prefix = Self::comment_prefix(&filename);
use std::io::BufRead;
let file = std::fs::File::open(filename)?;
let lines = std::io::BufReader::new(file)
.lines()
.take(13)
.collect::<Result<Vec<_>, _>>()?;
Ok(lines
.iter()
.map(|line| line.strip_prefix(&prefix).unwrap_or(""))
.map(str::to_string)
.collect::<Vec<_>>())
}

fn comment_prefix(filename: &str) -> String {
const KNOWN_EXTENSIONS: &[(&str, &str); 5] = &[
(".rs", "//"),
(".go", "//"),
(".yaml", "#"),
(".yml", "#"),
(".toml", "#"),
];

for &(extension, prefix) in KNOWN_EXTENSIONS {
if filename.ends_with(extension) {
return prefix.to_string();
}
}
return String::new();
}
}
2 changes: 1 addition & 1 deletion types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
Expand Down
2 changes: 1 addition & 1 deletion types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
Expand Down
2 changes: 1 addition & 1 deletion types/src/timestamp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
Expand Down

0 comments on commit 3e12221

Please sign in to comment.