• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MerginMaps / input / 5256074890

pending completion
5256074890

push

github

web-flow
Merge pull request #2714 from MerginMaps/Add-build-number-to-diagnostic-log_CU-861mn4ge4

Add build number to diagnostic log

8139 of 13074 relevant lines covered (62.25%)

107.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.49
/core/coreutils.cpp
1
/***************************************************************************
2
 *                                                                         *
3
 *   This program is free software; you can redistribute it and/or modify  *
4
 *   it under the terms of the GNU General Public License as published by  *
5
 *   the Free Software Foundation; either version 2 of the License, or     *
6
 *   (at your option) any later version.                                   *
7
 *                                                                         *
8
 ***************************************************************************/
9

10
#include "coreutils.h"
11
#include "inputconfig.h"
12

13
#include <QDateTime>
14
#include <QDebug>
15
#include <QDir>
16
#include <QFile>
17
#include <QDirIterator>
18
#include <QTextStream>
19

20
#include "qcoreapplication.h"
21
#include "merginapi.h"
22

23
const QString CoreUtils::LOG_TO_DEVNULL = QStringLiteral();
17✔
24
const QString CoreUtils::LOG_TO_STDOUT = QStringLiteral( "TO_STDOUT" );
17✔
25
QString CoreUtils::sLogFile = CoreUtils::LOG_TO_DEVNULL;
17✔
26

27
QString CoreUtils::appInfo()
1,070✔
28
{
29
  return QString( "%1/%2 (%3/%4)" ).arg( QCoreApplication::applicationName() ).arg( QCoreApplication::applicationVersion() )
2,140✔
30
         .arg( QSysInfo::productType() ).arg( QSysInfo::productVersion() );
1,070✔
31
}
×
32

33
QString CoreUtils::appVersion()
17✔
34
{
35
  QString version;
17✔
36
#ifdef INPUT_VERSION
37
  version = STR( INPUT_VERSION );
17✔
38
#endif
39
  return version;
17✔
40
}
17✔
41

42
QString CoreUtils::appVersionCode()
17✔
43
{
44
  QString version;
17✔
45
#ifdef INPUT_VERSION_CODE
46
  version = STR( INPUT_VERSION_CODE );
17✔
47
#endif
48
  return version;
17✔
49
}
17✔
50

51
QString CoreUtils::localizedDateFromUTFString( QString timestamp )
26✔
52
{
53
  if ( timestamp.isEmpty() )
26✔
54
    return QString();
×
55

56
  QDateTime dateTime = QDateTime::fromString( timestamp, Qt::ISODate );
26✔
57
  if ( dateTime.isValid() )
26✔
58
  {
59
    QLocale locale = QLocale::system();
26✔
60
    return locale.toString( dateTime.date(), locale.dateFormat( QLocale::ShortFormat ) );
26✔
61
  }
26✔
62
  else
63
  {
64
    qDebug() << "Unable to convert UTF " << timestamp << " to QDateTime";
×
65
    return QString();
×
66
  }
67
}
26✔
68

69
QString CoreUtils::uuidWithoutBraces( const QUuid &uuid )
411✔
70
{
71
#if QT_VERSION >= QT_VERSION_CHECK( 5, 11, 0 )
72
  return uuid.toString( QUuid::WithoutBraces );
411✔
73
#else
74
  QString str = uuid.toString();
75
  str = str.mid( 1, str.length() - 2 );  // remove braces
76
  return str;
77
#endif
78
}
79

80
bool CoreUtils::removeDir( const QString &dir )
75✔
81
{
82
  if ( dir.isEmpty() || dir == "/" )
75✔
83
    return false;
×
84

85
  return QDir( dir ).removeRecursively();
75✔
86
}
75✔
87

88
QString CoreUtils::downloadInProgressFilePath( const QString &projectDir )
302✔
89
{
90
  return projectDir + "/.mergin/.project.downloading";
302✔
91
}
92

93

94
void CoreUtils::setLogFilename( const QString &value )
17✔
95
{
96
  sLogFile = value;
17✔
97
}
17✔
98

99
QString CoreUtils::logFilename()
2✔
100
{
101
  return sLogFile;
2✔
102
}
103

104
void CoreUtils::log( const QString &topic, const QString &info )
3,976✔
105
{
106
  QString logFilePath;
3,976✔
107
  QByteArray data;
3,976✔
108
  data.append( QString( "%1 %2: %3\n" ).arg( QDateTime().currentDateTimeUtc().toString( Qt::ISODateWithMs ) ).arg( topic ).arg( info ).toUtf8() );
3,976✔
109
  appendLog( data, sLogFile );
3,976✔
110
}
3,976✔
111

112
void CoreUtils::appendLog( const QByteArray &data, const QString &path )
3,976✔
113
{
114
  if ( path != LOG_TO_DEVNULL )
3,976✔
115
  {
116
    if ( path == LOG_TO_STDOUT )
3,976✔
117
    {
118
      QTextStream out( stdout );
×
119
      out << data;
×
120
    }
×
121
    else
122
    {
123
      qDebug() << data;
3,976✔
124
      QFile file( path );
3,976✔
125
      if ( path.isEmpty() || !file.open( QIODevice::Append ) )
3,976✔
126
      {
127
        qDebug() << "ERROR: Invalid log file";
×
128
        return;
×
129
      }
130
      file.write( data );
3,976✔
131
      file.close();
3,976✔
132
    }
3,976✔
133
  }
3,976✔
134
}
3,976✔
135

136
QDateTime CoreUtils::getLastModifiedFileDateTime( const QString &path )
313✔
137
{
138
  QDateTime lastModified;
313✔
139
  QDirIterator it( path, QStringList() << QStringLiteral( "*" ), QDir::Files, QDirIterator::Subdirectories );
313✔
140
  while ( it.hasNext() )
1,051✔
141
  {
142
    it.next();
738✔
143
    if ( !MerginApi::isInIgnore( it.fileInfo() ) )
738✔
144
    {
145
      if ( it.fileInfo().lastModified() > lastModified )
738✔
146
      {
147
        lastModified = it.fileInfo().lastModified();
405✔
148
      }
405✔
149
    }
738✔
150
  }
151
  return lastModified.toUTC();
313✔
152
}
313✔
153

154
int CoreUtils::getProjectFilesCount( const QString &path )
313✔
155
{
156
  int count = 0;
313✔
157
  QDirIterator it( path, QStringList() << QStringLiteral( "*" ), QDir::Files, QDirIterator::Subdirectories );
313✔
158
  while ( it.hasNext() )
1,051✔
159
  {
160
    it.next();
738✔
161
    if ( !MerginApi::isInIgnore( it.fileInfo() ) )
738✔
162
    {
163
      count++;
738✔
164
    }
738✔
165
  }
166
  return count;
313✔
167
}
313✔
168

169
QString CoreUtils::findUniquePath( const QString &path )
86✔
170
{
171
  QFileInfo originalPath( path );
86✔
172
  QString uniquePath = path;
86✔
173

174
  // are we dealing with directory?
175
  bool isDirectory = originalPath.isDir();
86✔
176

177
  int i = 0;
86✔
178
  QFileInfo f( uniquePath );
86✔
179

180
  while ( f.exists() )
97✔
181
  {
182
    ++i; // let's start from 1
11✔
183

184
    if ( isDirectory )
11✔
185
    {
186
      uniquePath = path + " (" + QString::number( i ) + ')';
3✔
187
    }
3✔
188
    else // file
189
    {
190
      uniquePath = originalPath.path() + '/' + originalPath.baseName() + " (" + QString::number( i ) + ")." + originalPath.completeSuffix();
8✔
191
    }
192
    f.setFile( uniquePath );
11✔
193
  }
194

195
  return uniquePath;
86✔
196
}
86✔
197

198
QString CoreUtils::createUniqueProjectDirectory( const QString &baseDataDir, const QString &projectName )
62✔
199
{
200
  QString projectDirPath = findUniquePath( baseDataDir + "/" + projectName );
62✔
201
  QDir projectDir( projectDirPath );
62✔
202
  if ( !projectDir.exists() )
62✔
203
  {
204
    QDir dir( "" );
62✔
205
    dir.mkdir( projectDirPath );
62✔
206
  }
62✔
207
  return projectDirPath;
62✔
208
}
62✔
209

210
bool CoreUtils::createEmptyFile( const QString &filePath )
62✔
211
{
212
  QFile newFile( filePath );
62✔
213
  if ( !newFile.open( QIODevice::WriteOnly ) )
62✔
214
    return false;
×
215

216
  newFile.close();
62✔
217
  return true;
62✔
218
}
62✔
219

220
QString CoreUtils::generateConflictedCopyFileName( const QString &file, const QString &username, int version )
16✔
221
{
222
  if ( file.isEmpty() )
16✔
223
    return QString();
1✔
224

225
  QFileInfo f( file );
15✔
226

227
  QString suffix = f.completeSuffix();
15✔
228
  if ( hasProjectFileExtension( file ) )
15✔
229
  {
230
    suffix += "~";
2✔
231
  }
2✔
232
  return QString( "%1/%2 (conflicted copy, %3 v%4).%5" ).arg( f.path(), f.baseName(), username, QString::number( version ).toUtf8(), suffix );
15✔
233
}
16✔
234

235
QString CoreUtils::generateEditConflictFileName( const QString &file, const QString &username, int version )
20✔
236
{
237
  if ( file.isEmpty() )
20✔
238
    return QString();
1✔
239

240
  QFileInfo f( file );
19✔
241
  return QString( "%1/%2 (edit conflict, %3 v%4).json" ).arg( f.path(), f.baseName(), username, QString::number( version ) );
19✔
242
}
20✔
243

244
bool CoreUtils::hasProjectFileExtension( const QString filePath )
18✔
245
{
246
  return filePath.contains( ".qgs", Qt::CaseInsensitive ) || filePath.contains( ".qgz", Qt::CaseInsensitive );
18✔
247
}
×
248

249
bool CoreUtils::isValidName( const QString &name )
81✔
250
{
251
  QRegularExpression reForbiddenmNames( R"([@#$%^&*\(\)\{\}\[\]\\\/\|\+=<>~\?:;,`\'\"]|^[\s^\.].*$|^CON$|^PRN$|^AUX$|^NUL$|^COM\d$|^LPT\d|^support$|^helpdesk$|^merginmaps$|^lutraconsulting$|^mergin$|^lutra$|^input$|^sales$|^admin$)", QRegularExpression::CaseInsensitiveOption );
81✔
252
  QRegularExpressionMatch matchForbiddenNames = reForbiddenmNames.match( name );
81✔
253
  return !matchForbiddenNames.hasMatch();
81✔
254
}
81✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc