File indexing completed on 2025-03-09 05:11:41

0001 /*
0002 SPDX-FileCopyrightText: 2021 Hamed Masafi <hamed.masfi@gmail.com>
0003 
0004 SPDX-License-Identifier: GPL-3.0-or-later
0005 */
0006 
0007 #include "entities/file.h"
0008 #include "../gitmanager.h"
0009 
0010 #include <QFile>
0011 #include <QFileInfo>
0012 #include <QStandardPaths>
0013 #include <QUuid>
0014 #include <utility>
0015 
0016 #include "types.h"
0017 
0018 namespace Git
0019 {
0020 
0021 File::StorageType File::storage() const
0022 {
0023     return mStorage;
0024 }
0025 
0026 File::File()
0027     : mStorage{InValid}
0028 {
0029 }
0030 
0031 File::File(QString filePath)
0032     : mPlace()
0033     , mFilePath(std::move(filePath))
0034     , mStorage{Local}
0035 {
0036 }
0037 
0038 File::File(git_repository *repo, git_tree_entry *entry)
0039     : mRepo{repo}
0040     , mEntry{entry}
0041     , mStorage{Entry}
0042 {
0043 }
0044 
0045 File::~File()
0046 {
0047     if (mEntry)
0048         git_tree_entry_free(mEntry);
0049 }
0050 
0051 File::File(Manager *git, QString place, QString filePath)
0052     : mPlace(std::move(place))
0053     , mFilePath(std::move(filePath))
0054     , mGit(git)
0055     , mStorage{Git}
0056 {
0057     Q_ASSERT(mGit);
0058 
0059     if (mFilePath.startsWith("/"))
0060         mFilePath = mFilePath.mid(1);
0061 }
0062 
0063 File::File(const File &other) = default;
0064 
0065 // File::File(File &&other)
0066 //     : _place(std::move(other._place)), _filePath(std::move(other._filePath)),
0067 //       _git(std::move(other._git)), _storage(std::move(other._storage))
0068 //{
0069 
0070 //}
0071 
0072 File &File::operator=(const File &other) = default;
0073 
0074 const QString &File::place() const
0075 {
0076     return mPlace;
0077 }
0078 
0079 void File::setPlace(const QString &newPlace)
0080 {
0081     mPlace = newPlace;
0082 }
0083 
0084 QString File::fileName() const
0085 {
0086     if (mStorage == Entry) {
0087         QString name = git_tree_entry_name(mEntry);
0088         return name;
0089     }
0090     return mFilePath;
0091 }
0092 
0093 void File::setFileName(const QString &newFileName)
0094 {
0095     mFilePath = newFileName;
0096 }
0097 
0098 Manager *File::git() const
0099 {
0100     return mGit;
0101 }
0102 
0103 QString File::displayName() const
0104 {
0105     switch (mStorage) {
0106     case InValid:
0107         return {};
0108     case Local:
0109         return mFilePath;
0110     case Git:
0111         return mPlace + QLatin1Char(':') + mFilePath;
0112     case Entry: {
0113         QString name = git_tree_entry_name(mEntry);
0114         return name;
0115     }
0116     }
0117 
0118     return {};
0119 }
0120 
0121 bool File::save(const QString &path) const
0122 {
0123     QFile f{path};
0124     if (!f.open(QIODevice::WriteOnly))
0125         return false;
0126     const auto buffer = content(); // mGit->runGit({QStringLiteral("show"), mPlace + QLatin1Char(':') + mFilePath});
0127     f.write(buffer.toUtf8());
0128     f.close();
0129     return true;
0130 }
0131 
0132 QString File::saveAsTemp() const
0133 {
0134     QFileInfo fi{mFilePath};
0135     QString fileName;
0136     const auto tempLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
0137     if (tempLocation.isEmpty())
0138         return {};
0139 
0140     fileName = QStringLiteral("%1/%2-%3.%4").arg(tempLocation, fi.baseName(), QUuid::createUuid().toString(QUuid::Id128), fi.suffix());
0141 
0142     if (save(fileName))
0143         return fileName;
0144     return {};
0145 }
0146 
0147 QString File::content() const
0148 {
0149     switch (mStorage) {
0150     case InValid:
0151         return {};
0152     case Local: {
0153         QFile f(mFilePath);
0154         if (!f.open(QIODevice::ReadOnly))
0155             return {};
0156         return f.readAll();
0157     }
0158     case Git:
0159     case Entry:
0160         return stringContent(); // mGit->fileContent(mPlace, mFilePath); // mGit->runGit({QStringLiteral("show"), mPlace + QLatin1Char(':') + mFilePath});
0161     }
0162 
0163     return {};
0164 }
0165 
0166 QString File::stringContent() const
0167 {
0168     git_object *placeObject{nullptr};
0169     git_commit *commit{nullptr};
0170     git_tree *tree{nullptr};
0171     git_tree_entry *entry{nullptr};
0172     git_blob *blob{nullptr};
0173 
0174     BEGIN
0175     if (mEntry) {
0176         STEP git_blob_lookup(&blob, mRepo, git_tree_entry_id(mEntry));
0177     } else {
0178         STEP git_revparse_single(&placeObject, mGit->mRepo, toConstChars(mPlace));
0179         STEP git_commit_lookup(&commit, mGit->mRepo, git_object_id(placeObject));
0180         STEP git_commit_tree(&tree, commit);
0181 
0182         STEP git_tree_entry_bypath(&entry, tree, toConstChars(mFilePath));
0183         STEP git_blob_lookup(&blob, mGit->mRepo, git_tree_entry_id(entry));
0184     }
0185 
0186     if (err)
0187         return {};
0188 
0189     QString ch = (char *)git_blob_rawcontent(blob);
0190 
0191     git_object_free(placeObject);
0192     git_commit_free(commit);
0193     git_blob_free(blob);
0194     git_tree_entry_free(entry);
0195     git_tree_free(tree);
0196 
0197     return ch;
0198 }
0199 
0200 } // namespace Git