source_weaver_3-contract-lab/contracts/RepositoryExplorer.sol
source_weaver_3 63171aea03
Some checks are pending
CI / build-and-test (push) Waiting to run
CI / slither (push) Waiting to run
citizen: implement Implement: Serves as the entry point that imports and wires together all other modules
2026-04-19 09:09:28 +00:00

136 lines
4.4 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "./Repository.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
contract RepositoryExplorer is Ownable, ReentrancyGuard {
Repository[] public repositories;
mapping(address => bool) public registeredRepositories;
uint256 public totalRepositories;
event RepositoryAdded(address indexed repositoryAddress, uint256 indexed repositoryId);
event RepositoryRemoved(address indexed repositoryAddress, uint256 indexed repositoryId);
constructor() Ownable(msg.sender) {}
function createRepository(
string memory name,
string memory description,
address[] memory initialContributors
) external nonReentrant returns (address) {
require(bytes(name).length > 0, "Repository name cannot be empty");
require(bytes(description).length > 0, "Repository description cannot be empty");
Repository newRepository = new Repository(
name,
description,
initialContributors,
msg.sender
);
address repositoryAddress = address(newRepository);
repositories.push(newRepository);
registeredRepositories[repositoryAddress] = true;
totalRepositories++;
emit RepositoryAdded(repositoryAddress, totalRepositories - 1);
return repositoryAddress;
}
function removeRepository(uint256 repositoryId) external onlyOwner {
require(repositoryId < repositories.length, "Invalid repository ID");
Repository repository = repositories[repositoryId];
address repositoryAddress = address(repository);
require(registeredRepositories[repositoryAddress], "Repository not registered");
// Remove repository by replacing with last element and reducing array length
repositories[repositoryId] = repositories[repositories.length - 1];
repositories.pop();
registeredRepositories[repositoryAddress] = false;
totalRepositories--;
emit RepositoryRemoved(repositoryAddress, repositoryId);
}
function getRepositoryDetails(uint256 repositoryId)
external
view
returns (
string memory name,
string memory description,
address owner,
uint256 contributorCount
)
{
require(repositoryId < repositories.length, "Invalid repository ID");
Repository repository = repositories[repositoryId];
return (
repository.getName(),
repository.getDescription(),
repository.owner(),
repository.getContributorCount()
);
}
function listRepositories() external view returns (Repository[] memory) {
return repositories;
}
function searchRepositoriesByName(string memory searchTerm)
external
view
returns (Repository[] memory)
{
Repository[] memory matchingRepositories = new Repository[](repositories.length);
uint256 matchCount = 0;
for (uint256 i = 0; i < repositories.length; i++) {
if (containsSearchTerm(repositories[i].getName(), searchTerm)) {
matchingRepositories[matchCount] = repositories[i];
matchCount++;
}
}
// Trim array to actual matches
Repository[] memory trimmedResults = new Repository[](matchCount);
for (uint256 i = 0; i < matchCount; i++) {
trimmedResults[i] = matchingRepositories[i];
}
return trimmedResults;
}
function containsSearchTerm(string memory source, string memory searchTerm)
internal
pure
returns (bool)
{
bytes memory sourceBytes = bytes(source);
bytes memory searchBytes = bytes(searchTerm);
if (sourceBytes.length < searchBytes.length) {
return false;
}
for (uint256 i = 0; i <= sourceBytes.length - searchBytes.length; i++) {
bool found = true;
for (uint256 j = 0; j < searchBytes.length; j++) {
if (sourceBytes[i + j] != searchBytes[j]) {
found = false;
break;
}
}
if (found) {
return true;
}
}
return false;
}
}