mirror of
https://github.com/ModOrganizer2/mob.git
synced 2026-07-27 14:07:05 -07:00
Compare commits
54
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a408ff99b | ||
|
|
ecd210d700 | ||
|
|
d1965acd1a | ||
|
|
27483d6ddc | ||
|
|
73d7d3dd2b | ||
|
|
11dafd063b | ||
|
|
b0688f81b9 | ||
|
|
eaae1e44c9 | ||
|
|
0cb5771762 | ||
|
|
5ca1a76ff8 | ||
|
|
a03d95fef4 | ||
|
|
a835d167b2 | ||
|
|
bd4f529078 | ||
|
|
6b1b8ef6ea | ||
|
|
6cee3f2411 | ||
|
|
80618cd3e1 | ||
|
|
5ff7221b80 | ||
|
|
144548aef5 | ||
|
|
cdc666a1d5 | ||
|
|
2816871e93 | ||
|
|
1b05181858 | ||
|
|
b2eae1bd23 | ||
|
|
13ed5bcd26 | ||
|
|
29eb8a7598 | ||
|
|
7e08ce29c0 | ||
|
|
9fdf00417b | ||
|
|
ac15674069 | ||
|
|
b31d41b539 | ||
|
|
09886da058 | ||
|
|
e03ea3854d | ||
|
|
fe710715aa | ||
|
|
d7061cc18c | ||
|
|
e935d9adde | ||
|
|
d0913d07d3 | ||
|
|
6b51c170c1 | ||
|
|
a4213dd4c6 | ||
|
|
9ebabacc32 | ||
|
|
70983cb2e7 | ||
|
|
d61079e1f6 | ||
|
|
76e8c56235 | ||
|
|
10db7fe1a5 | ||
|
|
8afb96c229 | ||
|
|
66539d7f1f | ||
|
|
5f7c5eb1a2 | ||
|
|
886dadfedb | ||
|
|
66daf5054b | ||
|
|
9aec5a70a8 | ||
|
|
42aef59f9e | ||
|
|
5cb43da0e5 | ||
|
|
858662e225 | ||
|
|
a30dd8399b | ||
|
|
3e4b31aebb | ||
|
|
e3401732c1 | ||
|
|
6284f7869f |
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
# We'll use defaults from the LLVM style, but with 4 columns indentation.
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
IndentWidth: 4
|
||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
# Force pointers to the type for C++.
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
PointerAlignment: Left
|
||||||
|
AlignConsecutiveAssignments: true
|
||||||
|
AllowShortFunctionsOnASingleLine: Inline
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLambdasOnASingleLine: Empty
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignTrailingComments: true
|
||||||
|
SpacesBeforeTrailingComments: 2
|
||||||
|
NamespaceIndentation: All
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
BreakBeforeBraces: Stroustrup
|
||||||
|
ColumnLimit: 88
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"pch.h"$'
|
||||||
|
Priority: -1
|
||||||
|
SortPriority: -1
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
d0913d07d33929d7b753a3a09a0dac70e5befbc1
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
# Explicitly declare text files you want to always be normalized and converted
|
||||||
|
# to native line endings on checkout.
|
||||||
|
*.cpp text eol=crlf
|
||||||
|
*.h text eol=crlf
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
name: Build Mob
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: master
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: windows-2022
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Build Mob
|
||||||
|
shell: pwsh
|
||||||
|
run: ./bootstrap.ps1 -Verbose
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
name: Lint Mob
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Check format
|
||||||
|
uses: ModOrganizer2/check-formatting-action@master
|
||||||
|
with:
|
||||||
|
check-path: "."
|
||||||
|
exclude-regex: "third-party"
|
||||||
+43
-7
@@ -1,19 +1,55 @@
|
|||||||
|
param(
|
||||||
|
[switch]
|
||||||
|
$Verbose,
|
||||||
|
[ValidateSet("Debug", "RelWithDebInfo", "Release")]
|
||||||
|
[string]
|
||||||
|
$Config = "Release"
|
||||||
|
)
|
||||||
|
|
||||||
$root = $PSScriptRoot
|
$root = $PSScriptRoot
|
||||||
if (!$root) {
|
if (!$root) {
|
||||||
$root = "."
|
$root = "."
|
||||||
}
|
}
|
||||||
|
|
||||||
cmake -B build $root | Out-Null
|
$output = if ($Verbose) { "Out-Default" } else { "Out-Null" }
|
||||||
cmake --build $root/build --config Release -- `
|
|
||||||
"-p:UseMultiToolTask=true" `
|
cmake -B $root/build $root | & $output
|
||||||
"-noLogo" `
|
|
||||||
"-p:EnforceProcessCountAcrossBuilds=true" `
|
$installationPath = & $root\third-party\bin\vswhere.exe -products * -nologo -prerelease -latest -property installationPath
|
||||||
"-clp:ErrorsOnly;Verbosity=minimal"
|
if (! $?) {
|
||||||
|
Write-Error "vswhere returned $LastExitCode"
|
||||||
|
exit $LastExitCode
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $installationPath) {
|
||||||
|
Write-Error "Empty installation path"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$opts = ""
|
||||||
|
$opts += " $root\build\mob.sln"
|
||||||
|
$opts += " -m"
|
||||||
|
$opts += " -p:Configuration=${Config}"
|
||||||
|
$opts += " -noLogo"
|
||||||
|
$opts += " -p:UseMultiToolTask=true"
|
||||||
|
$opts += " -p:EnforceProcessCountAcrossBuilds=true"
|
||||||
|
|
||||||
|
if (!$Verbose) {
|
||||||
|
$opts += " -clp:ErrorsOnly;Verbosity=minimal"
|
||||||
|
}
|
||||||
|
|
||||||
|
$vsDevCmd = "$installationPath\Common7\Tools\VsDevCmd.bat"
|
||||||
|
if (!(Test-Path "$vsDevCmd")) {
|
||||||
|
Write-Error "VdDevCmd.bat not found at $vsDevCmd"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
& "${env:COMSPEC}" /c "`"$vsDevCmd`" -no_logo -arch=amd64 -host_arch=amd64 && msbuild $opts"
|
||||||
|
|
||||||
if (! $?) {
|
if (! $?) {
|
||||||
Write-Error "Build failed"
|
Write-Error "Build failed"
|
||||||
exit $LastExitCode
|
exit $LastExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
Copy-Item "$root\build\src\Release\mob.exe" "$root\mob.exe"
|
Copy-Item "$root\build\src\${Config}\mob.exe" "$root\mob.exe"
|
||||||
Write-Output "run ``.\mob -d prefix/path build`` to start building"
|
Write-Output "run ``.\mob -d prefix/path build`` to start building"
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) Matthias Moeller 2016 m_moeller@live.de
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
+170
-118
@@ -1,125 +1,177 @@
|
|||||||
|
|
||||||
LICENSE ISSUES
|
Apache License
|
||||||
==============
|
Version 2.0, January 2004
|
||||||
|
https://www.apache.org/licenses/
|
||||||
|
|
||||||
The OpenSSL toolkit stays under a double license, i.e. both the conditions of
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
the OpenSSL License and the original SSLeay license apply to the toolkit.
|
|
||||||
See below for the actual license texts.
|
|
||||||
|
|
||||||
OpenSSL License
|
1. Definitions.
|
||||||
---------------
|
|
||||||
|
|
||||||
/* ====================================================================
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
* Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in
|
|
||||||
* the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
*
|
|
||||||
* 3. All advertising materials mentioning features or use of this
|
|
||||||
* software must display the following acknowledgment:
|
|
||||||
* "This product includes software developed by the OpenSSL Project
|
|
||||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
|
||||||
*
|
|
||||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
|
||||||
* endorse or promote products derived from this software without
|
|
||||||
* prior written permission. For written permission, please contact
|
|
||||||
* openssl-core@openssl.org.
|
|
||||||
*
|
|
||||||
* 5. Products derived from this software may not be called "OpenSSL"
|
|
||||||
* nor may "OpenSSL" appear in their names without prior written
|
|
||||||
* permission of the OpenSSL Project.
|
|
||||||
*
|
|
||||||
* 6. Redistributions of any form whatsoever must retain the following
|
|
||||||
* acknowledgment:
|
|
||||||
* "This product includes software developed by the OpenSSL Project
|
|
||||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
|
||||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
|
||||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
* ====================================================================
|
|
||||||
*
|
|
||||||
* This product includes cryptographic software written by Eric Young
|
|
||||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
|
||||||
* Hudson (tjh@cryptsoft.com).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
Original SSLeay License
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
-----------------------
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
* All rights reserved.
|
other entities that control, are controlled by, or are under common
|
||||||
*
|
control with that entity. For the purposes of this definition,
|
||||||
* This package is an SSL implementation written
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
* by Eric Young (eay@cryptsoft.com).
|
direction or management of such entity, whether by contract or
|
||||||
* The implementation was written so as to conform with Netscapes SSL.
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
*
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
* This library is free for commercial and non-commercial use as long as
|
|
||||||
* the following conditions are aheared to. The following conditions
|
|
||||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
|
||||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
|
||||||
* included with this distribution is covered by the same copyright terms
|
|
||||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
|
||||||
*
|
|
||||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
|
||||||
* the code are not to be removed.
|
|
||||||
* If this package is used in a product, Eric Young should be given attribution
|
|
||||||
* as the author of the parts of the library used.
|
|
||||||
* This can be in the form of a textual message at program startup or
|
|
||||||
* in documentation (online or textual) provided with the package.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
|
||||||
* must display the following acknowledgement:
|
|
||||||
* "This product includes cryptographic software written by
|
|
||||||
* Eric Young (eay@cryptsoft.com)"
|
|
||||||
* The word 'cryptographic' can be left out if the rouines from the library
|
|
||||||
* being used are not cryptographic related :-).
|
|
||||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
|
||||||
* the apps directory (application code) you must include an acknowledgement:
|
|
||||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* The licence and distribution terms for any publically available version or
|
|
||||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
|
||||||
* copied and put under another distribution licence
|
|
||||||
* [including the GNU Public Licence.]
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ mo_fallback =
|
|||||||
no_pull = false
|
no_pull = false
|
||||||
ignore_ts = false
|
ignore_ts = false
|
||||||
revert_ts = false
|
revert_ts = false
|
||||||
|
configuration = RelWithDebInfo
|
||||||
|
|
||||||
git_url_prefix = https://github.com/
|
git_url_prefix = https://github.com/
|
||||||
git_shallow = true
|
git_shallow = true
|
||||||
@@ -89,45 +90,49 @@ lz4 = true
|
|||||||
openssl = true
|
openssl = true
|
||||||
pyqt = true
|
pyqt = true
|
||||||
python = true
|
python = true
|
||||||
usvfs = false
|
|
||||||
|
|
||||||
[versions]
|
[versions]
|
||||||
vs = 17
|
vs = 17
|
||||||
vs_year = 2022
|
vs_year = 2022
|
||||||
vs_toolset = 14.3
|
vs_toolset = 14.3
|
||||||
sdk = 10.0.22621.0
|
sdk = 10.0.22621.0
|
||||||
sevenz = 23.01
|
sevenz = 24.05
|
||||||
boost = 1.82.0
|
boost = 1.85.0
|
||||||
boost_vs = 14.3
|
boost_vs = 14.3
|
||||||
fmt = 8.1.1
|
fmt = 10.2.1
|
||||||
gtest = main
|
gtest = main
|
||||||
libloot = 0.19.4
|
libloot = 0.22.4
|
||||||
lz4 = v1.9.4
|
lz4 = v1.9.4
|
||||||
nmm = 0.71.2
|
nmm = 0.71.2
|
||||||
openssl = 1.1.1u
|
openssl = 3.3.0
|
||||||
pyqt = 6.5.1
|
pyqt = 6.7.0
|
||||||
pyqt_builder = 1.15.1
|
pyqt_builder = 1.16.2
|
||||||
pyqt_sip = 13.5.1
|
pyqt_sip = 13.7.0
|
||||||
python = v3.10.12
|
python = v3.12.3
|
||||||
pybind11 = v2.10.4
|
pybind11 = v2.12.0
|
||||||
bzip2 = 1.0.8
|
bzip2 = 1.0.8
|
||||||
sip = 6.7.1
|
sip = 6.8.3
|
||||||
spdlog = v1.10.0
|
spdlog = v1.14.1
|
||||||
qt = 6.5.1
|
qt = 6.7.0
|
||||||
qt_vs = 2019
|
qt_vs = 2019
|
||||||
zlib = v1.2.13
|
zlib = v1.3.1
|
||||||
libbsarch = 0.0.9
|
libbsarch = 0.0.9
|
||||||
usvfs = qt6
|
usvfs = master
|
||||||
explorerpp = 1.3.5
|
explorerpp = 1.4.0
|
||||||
|
ss_paper_lad_6788 = 7.2
|
||||||
ss_paper_lad_6788 = 7.0
|
ss_paper_automata_6788 = 3.2
|
||||||
ss_paper_automata_6788 = 3.0
|
ss_paper_mono_6788 = 3.2
|
||||||
ss_paper_mono_6788 = 2.2
|
|
||||||
ss_dark_mode_1809_6788 = 3.0
|
ss_dark_mode_1809_6788 = 3.0
|
||||||
ss_morrowind_trosski = 1.1
|
ss_morrowind_trosski = 1.1
|
||||||
ss_skyrim_trosski = v1.1
|
ss_skyrim_trosski = v1.1
|
||||||
ss_fallout3_trosski = v1.1
|
ss_starfield_trosski = V1.11
|
||||||
ss_fallout4_trosski = v1.1
|
ss_fallout3_trosski = v1.11
|
||||||
|
ss_fallout4_trosski = v1.11
|
||||||
|
|
||||||
|
[build-types]
|
||||||
|
libbsarch = release
|
||||||
|
pyqt = release
|
||||||
|
python = release
|
||||||
|
|
||||||
[paths]
|
[paths]
|
||||||
third_party =
|
third_party =
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
--- publish.bat Thu Apr 30 00:08:44 2020
|
|
||||||
+++ publish.bat Thu Apr 30 00:08:14 2020
|
|
||||||
@@ -1,6 +1,6 @@
|
|
||||||
set _NMMPATH=%~dp0..\Nexus-Mod-Manager
|
|
||||||
set _NMMCLIPATH=%~dp0
|
|
||||||
-set outputPath=..\..\install\bin
|
|
||||||
+set outputPath=%~1
|
|
||||||
|
|
||||||
mkdir "%outputPath%\NCC"
|
|
||||||
copy "%_NMMPATH%\Stage\Release\AntlrUtil.dll" "%outputPath%\NCC"
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
--- PCbuild/openssl.props (revision 5c02a39a0b31a330e06b4d6f44835afb205dc7cc)
|
--- PCbuild/openssl.props (revision 5c02a39a0b31a330e06b4d6f44835afb205dc7cc)
|
||||||
+++ PCbuild/openssl.props (date 1575994670797)
|
+++ PCbuild/openssl.props (date 1575994670797)
|
||||||
@@ -13,6 +13,7 @@
|
@@ -13,6 +13,7 @@
|
||||||
<_DLLSuffix>-1_1</_DLLSuffix>
|
<_DLLSuffix>-3</_DLLSuffix>
|
||||||
<_DLLSuffix Condition="$(Platform) == 'ARM'">$(_DLLSuffix)-arm</_DLLSuffix>
|
<_DLLSuffix Condition="$(Platform) == 'ARM'">$(_DLLSuffix)-arm</_DLLSuffix>
|
||||||
<_DLLSuffix Condition="$(Platform) == 'ARM64'">$(_DLLSuffix)-arm64</_DLLSuffix>
|
<_DLLSuffix Condition="$(Platform) == 'ARM64'">$(_DLLSuffix)-arm64</_DLLSuffix>
|
||||||
+ <_DLLSuffix Condition="$(Platform) == 'x64'">$(_DLLSuffix)-x64</_DLLSuffix>
|
+ <_DLLSuffix Condition="$(Platform) == 'x64'">$(_DLLSuffix)-x64</_DLLSuffix>
|
||||||
|
<OpenSSLDLLSuffix Condition="$(OpenSSLDLLSuffix) == ''">$(_DLLSuffix)</OpenSSLDLLSuffix>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<_SSLDLL Include="$(opensslOutDir)\libcrypto$(_DLLSuffix).dll" />
|
|
||||||
|
|||||||
@@ -25,26 +25,51 @@
|
|||||||
|
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
```
|
```powershell
|
||||||
> git clone https://github.com/ModOrganizer2/mob
|
> git clone https://github.com/ModOrganizer2/mob
|
||||||
> cd mob
|
> cd mob
|
||||||
> bootstrap
|
> bootstrap
|
||||||
> mob -d c:\somewhere build
|
> mob -d c:\somewhere build
|
||||||
```
|
```
|
||||||
|
|
||||||
## Slow start
|
## Extended start
|
||||||
- Install Qt 6.5.1 ([Installer](https://download.qt.io/official_releases/online_installers/qt-unified-windows-x64-online.exe)) and select these components:
|
|
||||||
|
### Qt - CLI based install using [aqt](https://github.com/miurahr/aqtinstall)
|
||||||
|
|
||||||
|
[aqt](https://github.com/miurahr/aqtinstall) is a CLI installer for Qt, it makes installing Qt extremely quick and painless, and doesn't require a login
|
||||||
|
|
||||||
|
#### Installing aqt via package manager
|
||||||
|
- Start an administrative terminal
|
||||||
|
- Install aqt using one of the two popular packaage managers
|
||||||
|
- `winget install --id=miurahr.aqtinstall -e`
|
||||||
|
- `choco install aqt`
|
||||||
|
|
||||||
|
#### Installing aqt via python/pip
|
||||||
|
|
||||||
|
- Install [Python 3.9](https://www.python.org/downloads/release/python-390/)
|
||||||
|
- Install [aqt](https://github.com/miurahr/aqtinstall) using `pip`
|
||||||
|
|
||||||
|
#### Using aqt
|
||||||
|
- Open a terminal with administrative rights, and run
|
||||||
|
```powershell
|
||||||
|
aqt install-qt --outputdir "C:\Qt" windows desktop 6.7.0 win64_msvc2019_64 -m qtwebengine qtimageformats qtpositioning qtserialport qtwebchannel qtwebsockets
|
||||||
|
```
|
||||||
|
|
||||||
|
### Qt - Manual installation
|
||||||
|
- Install Qt 6.7.0 ([Installer](https://download.qt.io/official_releases/online_installers/qt-unified-windows-x64-online.exe)) and select these components:
|
||||||
- MSVC 2019 64-bit
|
- MSVC 2019 64-bit
|
||||||
- Additional Libraries:
|
- Additional Libraries:
|
||||||
- Qt WebEngine (display nexus pages)
|
- Qt WebEngine (display nexus pages)
|
||||||
- Qt Image Formats (display images in image tab and preview)
|
- Qt Image Formats (display images in image tab and preview)
|
||||||
- Qt Positioning (required by QtWebEngine)
|
- Qt Positioning (required by QtWebEngine)
|
||||||
- Qt Serial Port (required by Qt Core)
|
- Qt Serial Port (required by Qt Core)
|
||||||
- Qt Web Channel (required by QtWebEngine)
|
- Qt WebChannel (required by QtWebEngine)
|
||||||
- Qt WebSockets (Nexus api/download)
|
- Qt WebSockets (Nexus api/download)
|
||||||
- Optional:
|
- Optional:
|
||||||
- Qt Source Files
|
- Qt Source Files
|
||||||
- Qt Debug Files
|
- Qt Debug Files
|
||||||
|
|
||||||
|
### Visual Studio
|
||||||
- Install Visual Studio 2022 ([Installer](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community&channel=Release&version=VS2022&source=VSLandingPage&cid=2030&passive=false))
|
- Install Visual Studio 2022 ([Installer](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community&channel=Release&version=VS2022&source=VSLandingPage&cid=2030&passive=false))
|
||||||
- Desktop development with C++
|
- Desktop development with C++
|
||||||
- Desktop .NET desktop development (needed by OMOD and FOMOD installers)
|
- Desktop .NET desktop development (needed by OMOD and FOMOD installers)
|
||||||
@@ -56,22 +81,20 @@
|
|||||||
- C++ /CLI support for v143 build Tools (Latest) (for OMOD and FOMOD installers)
|
- C++ /CLI support for v143 build Tools (Latest) (for OMOD and FOMOD installers)
|
||||||
- Windows 11 SDK (get latest)
|
- Windows 11 SDK (get latest)
|
||||||
- C++ Build Tools core features
|
- C++ Build Tools core features
|
||||||
- Optional:
|
- Git for Windows (Skip if you have this already installed outside of the VS installer)
|
||||||
- Git for Windows (if you don't have git already installed)
|
- CMake tools for Windows (Skip if you have this already installed outside of the VS installer)
|
||||||
- Start a shell
|
|
||||||
- If you have git in your path, a regular cmd shell works.
|
|
||||||
- If not, start the _x64 Native Tools Command Prompt for VS 2019_, it'll use Git for Windows installed above.
|
|
||||||
- Do:
|
|
||||||
```
|
|
||||||
mkdir C:\dev
|
|
||||||
cd C:\dev
|
|
||||||
git clone https://github.com/ModOrganizer2/mob
|
|
||||||
cd mob
|
|
||||||
bootstrap
|
|
||||||
mob -d C:\dev\modorganizer build
|
|
||||||
```
|
|
||||||
- Once `mob` is finished, everything will be in `C:\dev\modorganizer`. Mod Organizer can be run from `install\bin\ModOrganizer.exe`. The Visual Studio solution for Mod Organizer itself is `build\modorganizer_super\modorganizer\vsbuild\organizer.sln`.
|
|
||||||
|
|
||||||
|
## Setting up MOB
|
||||||
|
- Open a shell. If you've installed Git or CMake through the VS installer, they won't be on your PATH, so you must use x64 Native Tools Command Prompt for VS 2022.- Pick a folder to develop MO2 in, for these steps it'll be `C:\dev`
|
||||||
|
- Execute these commands
|
||||||
|
```powershell
|
||||||
|
mkdir C:\dev
|
||||||
|
cd C:\dev
|
||||||
|
git clone https://github.com/ModOrganizer2/mob
|
||||||
|
./bootstrap.ps1
|
||||||
|
mob -d C:\dev\modorganizer build
|
||||||
|
```
|
||||||
|
- Once `mob` is finished, everything will be in `C:\dev\modorganizer`. Mod Organizer can be run from `install\bin\ModOrganizer.exe`. The Visual Studio solution for Mod Organizer itself is `build\modorganizer_super\modorganizer\vsbuild\organizer.sln`.
|
||||||
|
|
||||||
### Prebuilts
|
### Prebuilts
|
||||||
Some third-parties are not normally built from source, but this can be changed in the options by setting the various tasks in `[prebuilt]` to `false`. If OpenSSL is built from source, perl is required ([Strawberry Perl 5.30.2.1 installer](http://strawberryperl.com/download/5.30.2.1/strawberry-perl-5.30.2.1-64bit.msi)).
|
Some third-parties are not normally built from source, but this can be changed in the options by setting the various tasks in `[prebuilt]` to `false`. If OpenSSL is built from source, perl is required ([Strawberry Perl 5.30.2.1 installer](http://strawberryperl.com/download/5.30.2.1/strawberry-perl-5.30.2.1-64bit.msi)).
|
||||||
@@ -121,6 +144,7 @@ Options for individual tasks. Can be `[task_name:task]`, where `task_name` is th
|
|||||||
| Option | Type | Description |
|
| Option | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `enabled` | bool | Whether this task is enabled. Disabled tasks are never built. When specifying task names with `mob build task1 task2...`, all tasks except those given are turned off. |
|
| `enabled` | bool | Whether this task is enabled. Disabled tasks are never built. When specifying task names with `mob build task1 task2...`, all tasks except those given are turned off. |
|
||||||
|
| `configuration` | enum | Which configuration to build, should be one of Debug, Release or RelWithDebInfo with RelWithDebInfo being the default.|
|
||||||
|
|
||||||
#### Common git options
|
#### Common git options
|
||||||
Unless otherwise stated, applies to any task that is a git repo.
|
Unless otherwise stated, applies to any task that is a git repo.
|
||||||
|
|||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
file(GLOB_RECURSE source_files *.cpp)
|
file(GLOB_RECURSE source_files *.cpp)
|
||||||
file(GLOB RECURSE header_files *.h)
|
file(GLOB_RECURSE header_files *.h)
|
||||||
|
|
||||||
add_executable(mob ${source_files})
|
add_executable(mob ${source_files} ${header_files})
|
||||||
set_target_properties(mob PROPERTIES CXX_STANDARD 20)
|
set_target_properties(mob PROPERTIES CXX_STANDARD 20)
|
||||||
|
|
||||||
target_compile_definitions(mob PUBLIC NOMINMAX)
|
target_compile_definitions(mob PUBLIC NOMINMAX)
|
||||||
|
|||||||
+84
-89
@@ -1,95 +1,99 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "commands.h"
|
|
||||||
#include "../core/ini.h"
|
|
||||||
#include "../core/conf.h"
|
#include "../core/conf.h"
|
||||||
#include "../core/context.h"
|
#include "../core/context.h"
|
||||||
|
#include "../core/ini.h"
|
||||||
#include "../core/op.h"
|
#include "../core/op.h"
|
||||||
#include "../tasks/task_manager.h"
|
#include "../tasks/task_manager.h"
|
||||||
|
#include "commands.h"
|
||||||
|
|
||||||
namespace mob
|
namespace mob {
|
||||||
{
|
|
||||||
|
|
||||||
build_command::build_command()
|
build_command::build_command() : command(requires_options | handle_sigint) {}
|
||||||
: command(requires_options | handle_sigint)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
command::meta_t build_command::meta() const
|
command::meta_t build_command::meta() const
|
||||||
{
|
|
||||||
return
|
|
||||||
{
|
{
|
||||||
"build",
|
return {"build", "builds tasks"};
|
||||||
"builds tasks"
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
clipp::group build_command::do_group()
|
clipp::group build_command::do_group()
|
||||||
{
|
{
|
||||||
return
|
return (clipp::command("build")).set(picked_),
|
||||||
(clipp::command("build")).set(picked_),
|
|
||||||
|
|
||||||
(clipp::option("-h", "--help") >> help_)
|
(clipp::option("-h", "--help") >> help_) % ("shows this message"),
|
||||||
% ("shows this message"),
|
|
||||||
|
|
||||||
(clipp::option("-g", "--redownload") >> redownload_)
|
(clipp::option("-g", "--redownload") >> redownload_) %
|
||||||
% "redownloads archives, see --reextract",
|
"redownloads archives, see --reextract",
|
||||||
|
|
||||||
(clipp::option("-e", "--reextract") >> reextract_)
|
(clipp::option("-e", "--reextract") >> reextract_) %
|
||||||
% "deletes source directories and re-extracts archives",
|
"deletes source directories and re-extracts archives",
|
||||||
|
|
||||||
(clipp::option("-c", "--reconfigure") >> reconfigure_)
|
(clipp::option("-c", "--reconfigure") >> reconfigure_) %
|
||||||
% "reconfigures the task by running cmake, configure scripts, "
|
"reconfigures the task by running cmake, configure scripts, "
|
||||||
"etc.; some tasks might have to delete the whole source "
|
"etc.; some tasks might have to delete the whole source "
|
||||||
"directory",
|
"directory",
|
||||||
|
|
||||||
(clipp::option("-b", "--rebuild") >> rebuild_)
|
(clipp::option("-b", "--rebuild") >> rebuild_) %
|
||||||
% "cleans and rebuilds projects; some tasks might have to "
|
"cleans and rebuilds projects; some tasks might have to "
|
||||||
"delete the whole source directory",
|
"delete the whole source directory",
|
||||||
|
|
||||||
(clipp::option("-n", "--new") >> new_)
|
(clipp::option("-n", "--new") >> new_) %
|
||||||
% "deletes everything and starts from scratch",
|
"deletes everything and starts from scratch",
|
||||||
|
|
||||||
(
|
(clipp::option("--clean-task").call([&] {
|
||||||
clipp::option("--clean-task").call([&]{ clean_ = true; }) |
|
clean_ = true;
|
||||||
clipp::option("--no-clean-task").call([&]{ clean_ = false; })
|
}) |
|
||||||
) % "sets whether tasks are cleaned",
|
clipp::option("--no-clean-task").call([&] {
|
||||||
|
clean_ = false;
|
||||||
|
})) %
|
||||||
|
"sets whether tasks are cleaned",
|
||||||
|
|
||||||
(
|
(clipp::option("--fetch-task").call([&] {
|
||||||
clipp::option("--fetch-task").call([&]{ fetch_ = true; }) |
|
fetch_ = true;
|
||||||
clipp::option("--no-fetch-task").call([&]{ fetch_ = false; })
|
}) |
|
||||||
) % "sets whether tasks are fetched",
|
clipp::option("--no-fetch-task").call([&] {
|
||||||
|
fetch_ = false;
|
||||||
|
})) %
|
||||||
|
"sets whether tasks are fetched",
|
||||||
|
|
||||||
(
|
(clipp::option("--build-task").call([&] {
|
||||||
clipp::option("--build-task").call([&]{ build_ = true; }) |
|
build_ = true;
|
||||||
clipp::option("--no-build-task").call([&]{ build_ = false; })
|
}) |
|
||||||
) % "sets whether tasks are built",
|
clipp::option("--no-build-task").call([&] {
|
||||||
|
build_ = false;
|
||||||
|
})) %
|
||||||
|
"sets whether tasks are built",
|
||||||
|
|
||||||
(
|
(clipp::option("--pull").call([&] {
|
||||||
clipp::option("--pull").call([&]{ nopull_ = false; }) |
|
nopull_ = false;
|
||||||
clipp::option("--no-pull").call([&]{ nopull_ = true; })
|
}) |
|
||||||
) % "whether to pull repos that are already cloned; global override",
|
clipp::option("--no-pull").call([&] {
|
||||||
|
nopull_ = true;
|
||||||
|
})) %
|
||||||
|
"whether to pull repos that are already cloned; global override",
|
||||||
|
|
||||||
(
|
(clipp::option("--revert-ts").call([&] {
|
||||||
clipp::option("--revert-ts").call([&]{ revert_ts_ = true; }) |
|
revert_ts_ = true;
|
||||||
clipp::option("--no-revert-ts").call([&]{ revert_ts_ = false; })
|
}) |
|
||||||
) % "whether to revert all the .ts files in a repo before pulling to "
|
clipp::option("--no-revert-ts").call([&] {
|
||||||
|
revert_ts_ = false;
|
||||||
|
})) %
|
||||||
|
"whether to revert all the .ts files in a repo before pulling to "
|
||||||
"avoid merge errors; global override",
|
"avoid merge errors; global override",
|
||||||
|
|
||||||
(clipp::option("--ignore-uncommitted-changes") >> ignore_uncommitted_)
|
(clipp::option("--ignore-uncommitted-changes") >> ignore_uncommitted_) %
|
||||||
% "when --reextract is given, directories controlled by git will "
|
"when --reextract is given, directories controlled by git will "
|
||||||
"be deleted even if they contain uncommitted changes",
|
"be deleted even if they contain uncommitted changes",
|
||||||
|
|
||||||
(clipp::option("--keep-msbuild") >> keep_msbuild_)
|
(clipp::option("--keep-msbuild") >> keep_msbuild_) %
|
||||||
% "don't terminate msbuild.exe instances after building",
|
"don't terminate msbuild.exe instances after building",
|
||||||
|
|
||||||
(clipp::opt_values(
|
(clipp::opt_values(clipp::match::prefix_not("-"), "task", tasks_)) %
|
||||||
clipp::match::prefix_not("-"), "task", tasks_))
|
"tasks to run; specify 'super' to only build modorganizer "
|
||||||
% "tasks to run; specify 'super' to only build modorganizer "
|
|
||||||
"projects";
|
"projects";
|
||||||
}
|
}
|
||||||
|
|
||||||
void build_command::convert_cl_to_conf()
|
void build_command::convert_cl_to_conf()
|
||||||
{
|
{
|
||||||
command::convert_cl_to_conf();
|
command::convert_cl_to_conf();
|
||||||
|
|
||||||
if (redownload_ || new_)
|
if (redownload_ || new_)
|
||||||
@@ -107,40 +111,35 @@ void build_command::convert_cl_to_conf()
|
|||||||
if (ignore_uncommitted_)
|
if (ignore_uncommitted_)
|
||||||
common.options.push_back("global/ignore_uncommitted=true");
|
common.options.push_back("global/ignore_uncommitted=true");
|
||||||
|
|
||||||
if (clean_)
|
if (clean_) {
|
||||||
{
|
|
||||||
if (*clean_)
|
if (*clean_)
|
||||||
common.options.push_back("global/clean_task=true");
|
common.options.push_back("global/clean_task=true");
|
||||||
else
|
else
|
||||||
common.options.push_back("global/clean_task=false");
|
common.options.push_back("global/clean_task=false");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fetch_)
|
if (fetch_) {
|
||||||
{
|
|
||||||
if (*fetch_)
|
if (*fetch_)
|
||||||
common.options.push_back("global/fetch_task=true");
|
common.options.push_back("global/fetch_task=true");
|
||||||
else
|
else
|
||||||
common.options.push_back("global/fetch_task=false");
|
common.options.push_back("global/fetch_task=false");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (build_)
|
if (build_) {
|
||||||
{
|
|
||||||
if (*build_)
|
if (*build_)
|
||||||
common.options.push_back("global/build_task=true");
|
common.options.push_back("global/build_task=true");
|
||||||
else
|
else
|
||||||
common.options.push_back("global/build_task=false");
|
common.options.push_back("global/build_task=false");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nopull_)
|
if (nopull_) {
|
||||||
{
|
|
||||||
if (*nopull_)
|
if (*nopull_)
|
||||||
common.options.push_back("_override:task/no_pull=true");
|
common.options.push_back("_override:task/no_pull=true");
|
||||||
else
|
else
|
||||||
common.options.push_back("_override:task/no_pull=false");
|
common.options.push_back("_override:task/no_pull=false");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (revert_ts_)
|
if (revert_ts_) {
|
||||||
{
|
|
||||||
if (*revert_ts_)
|
if (*revert_ts_)
|
||||||
common.options.push_back("_override:task/revert_ts=true");
|
common.options.push_back("_override:task/revert_ts=true");
|
||||||
else
|
else
|
||||||
@@ -149,12 +148,11 @@ void build_command::convert_cl_to_conf()
|
|||||||
|
|
||||||
if (!tasks_.empty())
|
if (!tasks_.empty())
|
||||||
set_task_enabled_flags(tasks_);
|
set_task_enabled_flags(tasks_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int build_command::do_run()
|
int build_command::do_run()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
create_prefix_ini();
|
create_prefix_ini();
|
||||||
|
|
||||||
task_manager::instance().run_all();
|
task_manager::instance().run_all();
|
||||||
@@ -165,15 +163,14 @@ int build_command::do_run()
|
|||||||
mob::gcx().info(mob::context::generic, "mob done");
|
mob::gcx().info(mob::context::generic, "mob done");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch(bailed&)
|
catch (bailed&) {
|
||||||
{
|
|
||||||
gcx().error(context::generic, "bailing out");
|
gcx().error(context::generic, "bailing out");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void build_command::create_prefix_ini()
|
void build_command::create_prefix_ini()
|
||||||
{
|
{
|
||||||
const auto prefix = conf().path().prefix();
|
const auto prefix = conf().path().prefix();
|
||||||
|
|
||||||
// creating prefix
|
// creating prefix
|
||||||
@@ -181,20 +178,18 @@ void build_command::create_prefix_ini()
|
|||||||
op::create_directories(gcx(), prefix);
|
op::create_directories(gcx(), prefix);
|
||||||
|
|
||||||
const auto ini = prefix / default_ini_filename();
|
const auto ini = prefix / default_ini_filename();
|
||||||
if (!exists(ini))
|
if (!exists(ini)) {
|
||||||
{
|
std::ofstream(ini) << "[paths]\n"
|
||||||
std::ofstream(ini)
|
|
||||||
<< "[paths]\n"
|
|
||||||
<< "prefix = .\n";
|
<< "prefix = .\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void build_command::terminate_msbuild()
|
void build_command::terminate_msbuild()
|
||||||
{
|
{
|
||||||
if (conf().global().dry())
|
if (conf().global().dry())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
system("taskkill /im msbuild.exe /f > NUL 2>&1");
|
system("taskkill /im msbuild.exe /f > NUL 2>&1");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace mob
|
||||||
|
|||||||
+33
-46
@@ -1,61 +1,49 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "commands.h"
|
|
||||||
#include "../tasks/tasks.h"
|
#include "../tasks/tasks.h"
|
||||||
|
#include "commands.h"
|
||||||
|
|
||||||
namespace mob
|
namespace mob {
|
||||||
{
|
|
||||||
|
|
||||||
cmake_command::cmake_command()
|
cmake_command::cmake_command() : command(requires_options) {}
|
||||||
: command(requires_options)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
command::meta_t cmake_command::meta() const
|
command::meta_t cmake_command::meta() const
|
||||||
{
|
|
||||||
return
|
|
||||||
{
|
{
|
||||||
"cmake",
|
return {"cmake", "runs cmake in a directory"};
|
||||||
"runs cmake in a directory"
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
clipp::group cmake_command::do_group()
|
clipp::group cmake_command::do_group()
|
||||||
{
|
{
|
||||||
return clipp::group(
|
return clipp::group(
|
||||||
clipp::command("cmake").set(picked_),
|
clipp::command("cmake").set(picked_),
|
||||||
|
|
||||||
(clipp::option("-h", "--help") >> help_)
|
(clipp::option("-h", "--help") >> help_) % "shows this message",
|
||||||
% "shows this message",
|
|
||||||
|
|
||||||
(clipp::option("-G", "--generator")
|
(clipp::option("-G", "--generator") & clipp::value("GEN") >> gen_) %
|
||||||
& clipp::value("GEN") >> gen_)
|
("sets the -G option for cmake [default: VS]"),
|
||||||
% ("sets the -G option for cmake [default: VS]"),
|
|
||||||
|
|
||||||
(clipp::option("-c", "--cmd")
|
(clipp::option("-c", "--cmd") & clipp::value("CMD") >> cmd_) %
|
||||||
& clipp::value("CMD") >> cmd_)
|
"overrides the cmake command line [default: \"..\"]",
|
||||||
% "overrides the cmake command line [default: \"..\"]",
|
|
||||||
|
|
||||||
(
|
(clipp::option("--x64").set(x64_, true) |
|
||||||
clipp::option("--x64").set(x64_, true) |
|
clipp::option("--x86").set(x64_, false)) %
|
||||||
clipp::option("--x86").set(x64_, false)
|
"whether to use the x64 or x86 vcvars; if -G is not set, "
|
||||||
)
|
|
||||||
% "whether to use the x64 or x86 vcvars; if -G is not set, "
|
|
||||||
"whether to pass \"-A Win32\" or \"-A x64\" for the default "
|
"whether to pass \"-A Win32\" or \"-A x64\" for the default "
|
||||||
"VS generator [default: x64]",
|
"VS generator [default: x64]",
|
||||||
|
|
||||||
(clipp::option("--install-prefix")
|
(clipp::option("--install-prefix") & clipp::value("PATH") >> prefix_) %
|
||||||
& clipp::value("PATH") >> prefix_)
|
"sets CMAKE_INSTALL_PREFIX [default: empty]",
|
||||||
% "sets CMAKE_INSTALL_PREFIX [default: empty]",
|
|
||||||
|
|
||||||
(clipp::value("PATH") >> path_)
|
(clipp::option("-d", "--debug").set(debug_, true)) %
|
||||||
% "path from which to run `cmake`"
|
"whether to configure for debug mode [default: false]",
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cmake_command::do_run()
|
(clipp::value("PATH") >> path_) % "path from which to run `cmake`");
|
||||||
{
|
}
|
||||||
|
|
||||||
|
int cmake_command::do_run()
|
||||||
|
{
|
||||||
auto t = tasks::modorganizer::create_cmake_tool(
|
auto t = tasks::modorganizer::create_cmake_tool(
|
||||||
fs::path(utf8_to_utf16(path_)));
|
fs::path(utf8_to_utf16(path_)), mob::cmake::generate,
|
||||||
|
debug_ ? config::debug : config::relwithdebinfo);
|
||||||
|
|
||||||
t.generator(gen_);
|
t.generator(gen_);
|
||||||
t.cmd(cmd_);
|
t.cmd(cmd_);
|
||||||
@@ -71,13 +59,12 @@ int cmake_command::do_run()
|
|||||||
t.run(cxcopy);
|
t.run(cxcopy);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string cmake_command::do_doc()
|
std::string cmake_command::do_doc()
|
||||||
{
|
{
|
||||||
return
|
return "Runs `cmake ..` in the given directory with the same command line\n"
|
||||||
"Runs `cmake ..` in the given directory with the same command line\n"
|
|
||||||
"as the one used for modorganizer projects.";
|
"as the one used for modorganizer projects.";
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace mob
|
||||||
|
|||||||
+143
-196
@@ -1,138 +1,119 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "../utility.h"
|
|
||||||
#include "../net.h"
|
|
||||||
#include "../core/conf.h"
|
#include "../core/conf.h"
|
||||||
#include "../core/ini.h"
|
#include "../core/ini.h"
|
||||||
|
#include "../net.h"
|
||||||
#include "../tasks/task_manager.h"
|
#include "../tasks/task_manager.h"
|
||||||
#include "../tools/tools.h"
|
#include "../tools/tools.h"
|
||||||
|
#include "../utility.h"
|
||||||
#include "../utility/threading.h"
|
#include "../utility/threading.h"
|
||||||
|
|
||||||
namespace mob
|
namespace mob {
|
||||||
{
|
|
||||||
|
|
||||||
BOOL WINAPI signal_handler(DWORD) noexcept
|
BOOL WINAPI signal_handler(DWORD) noexcept
|
||||||
{
|
{
|
||||||
// don't use u8cout, this would lock the global mutex, but the handler
|
// don't use u8cout, this would lock the global mutex, but the handler
|
||||||
// can be called while stuff is being output and the mutex is locked
|
// can be called while stuff is being output and the mutex is locked
|
||||||
std::wcout << L"sigint, interrupting...\n";
|
std::wcout << L"sigint, interrupting...\n";
|
||||||
task_manager::instance().interrupt_all();
|
task_manager::instance().interrupt_all();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_sigint_handler()
|
void set_sigint_handler()
|
||||||
{
|
{
|
||||||
::SetConsoleCtrlHandler(mob::signal_handler, TRUE);
|
::SetConsoleCtrlHandler(mob::signal_handler, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void help(const clipp::group& g, const std::string& more)
|
||||||
|
{
|
||||||
|
auto usage_df = clipp::doc_formatting().first_column(4).doc_column(30);
|
||||||
|
|
||||||
void help(const clipp::group& g, const std::string& more)
|
auto options_df = clipp::doc_formatting().first_column(4).doc_column(30);
|
||||||
{
|
|
||||||
auto usage_df = clipp::doc_formatting()
|
|
||||||
.first_column(4)
|
|
||||||
.doc_column(30);
|
|
||||||
|
|
||||||
auto options_df = clipp::doc_formatting()
|
u8cout << "Usage:\n"
|
||||||
.first_column(4)
|
<< clipp::usage_lines(g, "mob", usage_df) << "\n\n"
|
||||||
.doc_column(30);
|
|
||||||
|
|
||||||
u8cout
|
|
||||||
<< "Usage:\n" << clipp::usage_lines(g, "mob", usage_df)
|
|
||||||
<< "\n\n"
|
|
||||||
<< "Options:\n"
|
<< "Options:\n"
|
||||||
<< clipp::documentation(g, options_df)
|
<< clipp::documentation(g, options_df) << "\n\n"
|
||||||
<< "\n\n"
|
|
||||||
<< "To use global options with command options, make sure command \n"
|
<< "To use global options with command options, make sure command \n"
|
||||||
<< "options are together, with no global options in the middle.\n";
|
<< "options are together, with no global options in the middle.\n";
|
||||||
|
|
||||||
if (!more.empty())
|
if (!more.empty())
|
||||||
u8cout << "\n" << more << "\n";
|
u8cout << "\n" << more << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
command::common_options command::common;
|
||||||
|
|
||||||
command::common_options command::common;
|
command::command(flags f) : picked_(false), help_(false), flags_(f), code_() {}
|
||||||
|
|
||||||
command::command(flags f)
|
clipp::group command::common_options_group()
|
||||||
: picked_(false), help_(false), flags_(f), code_()
|
{
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
clipp::group command::common_options_group()
|
|
||||||
{
|
|
||||||
auto& o = common;
|
auto& o = common;
|
||||||
const auto master = default_ini_filename();
|
const auto master = default_ini_filename();
|
||||||
|
|
||||||
return
|
return (clipp::repeatable(clipp::option("-i", "--ini") &
|
||||||
(clipp::repeatable(clipp::option("-i", "--ini")
|
clipp::value("FILE") >> o.inis)) %
|
||||||
& clipp::value("FILE") >> o.inis))
|
"path to the ini file",
|
||||||
% "path to the ini file",
|
|
||||||
|
|
||||||
(clipp::option("--dry") >> o.dry)
|
(clipp::option("--dry") >> o.dry) % "simulates filesystem operations",
|
||||||
% "simulates filesystem operations",
|
|
||||||
|
|
||||||
(clipp::option("-l", "--log-level")
|
(clipp::option("-l", "--log-level") &
|
||||||
& clipp::value("LEVEL") >> o.output_log_level)
|
clipp::value("LEVEL") >> o.output_log_level) %
|
||||||
% "0 is silent, 6 is max",
|
"0 is silent, 6 is max",
|
||||||
|
|
||||||
(clipp::option("--file-log-level")
|
(clipp::option("--file-log-level") &
|
||||||
& clipp::value("LEVEL") >> o.file_log_level)
|
clipp::value("LEVEL") >> o.file_log_level) %
|
||||||
% "overrides --log-level for the log file",
|
"overrides --log-level for the log file",
|
||||||
|
|
||||||
(clipp::option("--log-file")
|
(clipp::option("--log-file") & clipp::value("FILE") >> o.log_file) %
|
||||||
& clipp::value("FILE") >> o.log_file)
|
"path to log file",
|
||||||
% "path to log file",
|
|
||||||
|
|
||||||
(clipp::option("-d", "--destination")
|
(clipp::option("-d", "--destination") &
|
||||||
& clipp::value("DIR") >> o.prefix)
|
clipp::value("DIR") >> o.prefix) %
|
||||||
% ("base output directory, will contain build/, install/, etc."),
|
("base output directory, will contain build/, install/, etc."),
|
||||||
|
|
||||||
(clipp::repeatable(clipp::option("-s", "--set")
|
(clipp::repeatable(clipp::option("-s", "--set") &
|
||||||
& clipp::value("OPTION", o.options)))
|
clipp::value("OPTION", o.options))) %
|
||||||
% "sets an option, such as 'versions/openssl=1.2'",
|
"sets an option, such as 'versions/openssl=1.2'",
|
||||||
|
|
||||||
(clipp::option("--no-default-inis") >> o.no_default_inis)
|
(clipp::option("--no-default-inis") >> o.no_default_inis) %
|
||||||
% "disables auto loading of ini files, only uses --ini; the first "
|
"disables auto loading of ini files, only uses --ini; the first "
|
||||||
"--ini must be the master ini file";
|
"--ini must be the master ini file";
|
||||||
}
|
}
|
||||||
|
|
||||||
void command::force_exit_code(int code)
|
void command::force_exit_code(int code)
|
||||||
{
|
{
|
||||||
code_ = code;
|
code_ = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
void command::force_help()
|
void command::force_help()
|
||||||
{
|
{
|
||||||
help_ = true;
|
help_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool command::picked() const
|
bool command::picked() const
|
||||||
{
|
{
|
||||||
return picked_;
|
return picked_;
|
||||||
}
|
}
|
||||||
|
|
||||||
clipp::group command::group()
|
clipp::group command::group()
|
||||||
{
|
{
|
||||||
return do_group();
|
return do_group();
|
||||||
}
|
}
|
||||||
|
|
||||||
void command::convert_cl_to_conf()
|
void command::convert_cl_to_conf()
|
||||||
{
|
{
|
||||||
auto& o = common;
|
auto& o = common;
|
||||||
|
|
||||||
if (o.file_log_level == -1)
|
if (o.file_log_level == -1)
|
||||||
o.file_log_level = o.output_log_level;
|
o.file_log_level = o.output_log_level;
|
||||||
|
|
||||||
if (o.output_log_level >= 0)
|
if (o.output_log_level >= 0) {
|
||||||
{
|
o.options.push_back("global/output_log_level=" +
|
||||||
o.options.push_back(
|
|
||||||
"global/output_log_level=" +
|
|
||||||
std::to_string(o.output_log_level));
|
std::to_string(o.output_log_level));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (o.file_log_level > 0)
|
if (o.file_log_level > 0) {
|
||||||
{
|
o.options.push_back("global/file_log_level=" +
|
||||||
o.options.push_back(
|
|
||||||
"global/file_log_level=" +
|
|
||||||
std::to_string(o.file_log_level));
|
std::to_string(o.file_log_level));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,34 +125,30 @@ void command::convert_cl_to_conf()
|
|||||||
|
|
||||||
if (!o.prefix.empty())
|
if (!o.prefix.empty())
|
||||||
o.options.push_back("paths/prefix=" + o.prefix);
|
o.options.push_back("paths/prefix=" + o.prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
int command::gather_inis(bool verbose)
|
int command::gather_inis(bool verbose)
|
||||||
{
|
{
|
||||||
auto& o = common;
|
auto& o = common;
|
||||||
|
|
||||||
if (o.no_default_inis && o.inis.empty())
|
if (o.no_default_inis && o.inis.empty()) {
|
||||||
{
|
u8cerr << "--no-default-inis requires at least one --ini for the "
|
||||||
u8cerr
|
|
||||||
<< "--no-default-inis requires at least one --ini for the "
|
|
||||||
<< "master ini file\n";
|
<< "master ini file\n";
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
inis_ = find_inis(!o.no_default_inis, o.inis, verbose);
|
inis_ = find_inis(!o.no_default_inis, o.inis, verbose);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch(bailed&)
|
catch (bailed&) {
|
||||||
{
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void command::set_task_enabled_flags(const std::vector<std::string>& names)
|
void command::set_task_enabled_flags(const std::vector<std::string>& names)
|
||||||
{
|
{
|
||||||
common.options.push_back("task/enabled=false");
|
common.options.push_back("task/enabled=false");
|
||||||
|
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
@@ -181,24 +158,22 @@ void command::set_task_enabled_flags(const std::vector<std::string>& names)
|
|||||||
|
|
||||||
if (failed)
|
if (failed)
|
||||||
throw bailed();
|
throw bailed();
|
||||||
}
|
}
|
||||||
|
|
||||||
int command::prepare_options(bool verbose)
|
int command::prepare_options(bool verbose)
|
||||||
{
|
{
|
||||||
convert_cl_to_conf();
|
convert_cl_to_conf();
|
||||||
return gather_inis(verbose);
|
return gather_inis(verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
int command::run()
|
int command::run()
|
||||||
{
|
|
||||||
if (help_)
|
|
||||||
{
|
{
|
||||||
|
if (help_) {
|
||||||
help(group(), do_doc());
|
help(group(), do_doc());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags_ & requires_options)
|
if (flags_ & requires_options) {
|
||||||
{
|
|
||||||
const auto r = load_options();
|
const auto r = load_options();
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return r;
|
return r;
|
||||||
@@ -213,10 +188,10 @@ int command::run()
|
|||||||
return *code_;
|
return *code_;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int command::load_options()
|
int command::load_options()
|
||||||
{
|
{
|
||||||
const int r = prepare_options(false);
|
const int r = prepare_options(false);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return r;
|
return r;
|
||||||
@@ -230,66 +205,53 @@ int command::load_options()
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
command::meta_t version_command::meta() const
|
||||||
command::meta_t version_command::meta() const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
{
|
{
|
||||||
"version",
|
return {"version", "shows the version"};
|
||||||
"shows the version"
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
clipp::group version_command::do_group()
|
clipp::group version_command::do_group()
|
||||||
{
|
{
|
||||||
return clipp::group(
|
return clipp::group(clipp::command("version", "-v", "--version").set(picked_));
|
||||||
clipp::command("version", "-v", "--version").set(picked_));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int version_command::do_run()
|
int version_command::do_run()
|
||||||
{
|
{
|
||||||
u8cout << mob_version() << "\n";
|
u8cout << mob_version() << "\n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
command::meta_t help_command::meta() const
|
||||||
command::meta_t help_command::meta() const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
{
|
{
|
||||||
"help",
|
return {"help", "shows this message"};
|
||||||
"shows this message"
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void help_command::set_commands(const std::vector<std::shared_ptr<command>>& v)
|
void help_command::set_commands(const std::vector<std::shared_ptr<command>>& v)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, std::string>> s;
|
std::vector<std::pair<std::string, std::string>> s;
|
||||||
|
|
||||||
for (auto&& c : v)
|
for (auto&& c : v)
|
||||||
s.push_back({c->meta().name, c->meta().description});
|
s.push_back({c->meta().name, c->meta().description});
|
||||||
|
|
||||||
commands_ = table(s, 4, 3);
|
commands_ = table(s, 4, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
clipp::group help_command::do_group()
|
clipp::group help_command::do_group()
|
||||||
{
|
{
|
||||||
return clipp::group(
|
return clipp::group(clipp::command("-h", "--help").set(picked_));
|
||||||
clipp::command("-h", "--help").set(picked_));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int help_command::do_run()
|
int help_command::do_run()
|
||||||
{
|
{
|
||||||
#pragma warning(suppress: 4548)
|
#pragma warning(suppress : 4548)
|
||||||
auto doc = (command::common_options_group(), (clipp::value("command")));
|
auto doc = (command::common_options_group(), (clipp::value("command")));
|
||||||
|
|
||||||
const auto master = default_ini_filename();
|
const auto master = default_ini_filename();
|
||||||
|
|
||||||
help(doc,
|
help(doc,
|
||||||
"Commands:\n"
|
"Commands:\n" + commands_ +
|
||||||
+ commands_ +
|
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"Invoking `mob -d some/prefix build` builds everything. Do \n"
|
"Invoking `mob -d some/prefix build` builds everything. Do \n"
|
||||||
"`mob build <task name>...` to build specific tasks. See\n"
|
"`mob build <task name>...` to build specific tasks. See\n"
|
||||||
@@ -297,7 +259,9 @@ int help_command::do_run()
|
|||||||
"\n"
|
"\n"
|
||||||
"INI files\n"
|
"INI files\n"
|
||||||
"\n"
|
"\n"
|
||||||
"By default, mob will look for a master INI `" + master + "` in the \n"
|
"By default, mob will look for a master INI `" +
|
||||||
|
master +
|
||||||
|
"` in the \n"
|
||||||
"root directory (typically where mob.exe resides). Once mob has\n"
|
"root directory (typically where mob.exe resides). Once mob has\n"
|
||||||
"found the master INI, it will look for the same filename in the\n"
|
"found the master INI, it will look for the same filename in the\n"
|
||||||
"current directory, if different from the root. If found, both will\n"
|
"current directory, if different from the root. If found, both will\n"
|
||||||
@@ -307,74 +271,57 @@ int help_command::do_run()
|
|||||||
"disable auto detection and only use --ini.");
|
"disable auto detection and only use --ini.");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options_command::options_command() : command(requires_options) {}
|
||||||
|
|
||||||
options_command::options_command()
|
command::meta_t options_command::meta() const
|
||||||
: command(requires_options)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
command::meta_t options_command::meta() const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
{
|
{
|
||||||
"options",
|
return {"options", "lists all options and their values from the inis"};
|
||||||
"lists all options and their values from the inis"
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
clipp::group options_command::do_group()
|
clipp::group options_command::do_group()
|
||||||
{
|
{
|
||||||
return clipp::group(
|
return clipp::group(clipp::command("options").set(picked_),
|
||||||
clipp::command("options").set(picked_),
|
|
||||||
|
|
||||||
(clipp::option("-h", "--help") >> help_)
|
(clipp::option("-h", "--help") >> help_) %
|
||||||
% ("shows this message")
|
("shows this message"));
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int options_command::do_run()
|
int options_command::do_run()
|
||||||
{
|
{
|
||||||
for (auto&& line : format_options())
|
for (auto&& line : format_options())
|
||||||
u8cout << line << "\n";
|
u8cout << line << "\n";
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string options_command::do_doc()
|
std::string options_command::do_doc()
|
||||||
{
|
|
||||||
return "Lists the final value of all options found by loading the INIs.";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
command::meta_t inis_command::meta() const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
{
|
{
|
||||||
"inis",
|
return "Lists the final value of all options found by loading the INIs.";
|
||||||
"lists the INIs used by mob"
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
clipp::group inis_command::do_group()
|
command::meta_t inis_command::meta() const
|
||||||
{
|
{
|
||||||
return clipp::group(
|
return {"inis", "lists the INIs used by mob"};
|
||||||
clipp::command("inis").set(picked_),
|
}
|
||||||
|
|
||||||
(clipp::option("-h", "--help") >> help_)
|
clipp::group inis_command::do_group()
|
||||||
% ("shows this message")
|
{
|
||||||
);
|
return clipp::group(clipp::command("inis").set(picked_),
|
||||||
}
|
|
||||||
|
|
||||||
int inis_command::do_run()
|
(clipp::option("-h", "--help") >> help_) %
|
||||||
{
|
("shows this message"));
|
||||||
|
}
|
||||||
|
|
||||||
|
int inis_command::do_run()
|
||||||
|
{
|
||||||
return prepare_options(true);
|
return prepare_options(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string inis_command::do_doc()
|
std::string inis_command::do_doc()
|
||||||
{
|
{
|
||||||
return "Shows which INIs are found.";
|
return "Shows which INIs are found.";
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace mob
|
||||||
|
|||||||
+105
-160
@@ -2,26 +2,22 @@
|
|||||||
|
|
||||||
#include "../utility/enum.h"
|
#include "../utility/enum.h"
|
||||||
|
|
||||||
namespace mob::tasks
|
namespace mob::tasks {
|
||||||
{
|
|
||||||
class modorganizer;
|
class modorganizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace mob
|
namespace mob {
|
||||||
{
|
|
||||||
|
|
||||||
class task;
|
class task;
|
||||||
class url;
|
class url;
|
||||||
|
|
||||||
// base class for all commands
|
// base class for all commands
|
||||||
//
|
//
|
||||||
class command
|
class command {
|
||||||
{
|
public:
|
||||||
public:
|
|
||||||
// values of options available for all commands
|
// values of options available for all commands
|
||||||
//
|
//
|
||||||
struct common_options
|
struct common_options {
|
||||||
{
|
|
||||||
bool dry = false;
|
bool dry = false;
|
||||||
int output_log_level = -1;
|
int output_log_level = -1;
|
||||||
int file_log_level = -1;
|
int file_log_level = -1;
|
||||||
@@ -35,12 +31,10 @@ public:
|
|||||||
|
|
||||||
// returned by meta() by each command
|
// returned by meta() by each command
|
||||||
//
|
//
|
||||||
struct meta_t
|
struct meta_t {
|
||||||
{
|
|
||||||
std::string name, description;
|
std::string name, description;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static common_options common;
|
static common_options common;
|
||||||
static clipp::group common_options_group();
|
static clipp::group common_options_group();
|
||||||
|
|
||||||
@@ -66,16 +60,14 @@ public:
|
|||||||
//
|
//
|
||||||
int run();
|
int run();
|
||||||
|
|
||||||
|
|
||||||
// returns meta information about this command
|
// returns meta information about this command
|
||||||
//
|
//
|
||||||
virtual meta_t meta() const = 0;
|
virtual meta_t meta() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// passed by derived classes in the constructor
|
// passed by derived classes in the constructor
|
||||||
//
|
//
|
||||||
enum flags
|
enum flags {
|
||||||
{
|
|
||||||
noflags = 0x00,
|
noflags = 0x00,
|
||||||
|
|
||||||
// this command needs the ini loaded before running
|
// this command needs the ini loaded before running
|
||||||
@@ -87,15 +79,13 @@ protected:
|
|||||||
|
|
||||||
MOB_ENUM_FRIEND_OPERATORS(flags);
|
MOB_ENUM_FRIEND_OPERATORS(flags);
|
||||||
|
|
||||||
|
|
||||||
// set to true when this command is entered by the user
|
// set to true when this command is entered by the user
|
||||||
bool picked_;
|
bool picked_;
|
||||||
|
|
||||||
// set to true with --help or by force_help()
|
// set to true with --help or by force_help()
|
||||||
bool help_;
|
bool help_;
|
||||||
|
|
||||||
|
command(flags f = noflags);
|
||||||
command(flags f=noflags);
|
|
||||||
|
|
||||||
// some options have a unique version on the command line because they're
|
// some options have a unique version on the command line because they're
|
||||||
// used often, such as --dry or -l; those are converted to their ini
|
// used often, such as --dry or -l; those are converted to their ini
|
||||||
@@ -130,7 +120,7 @@ protected:
|
|||||||
//
|
//
|
||||||
virtual std::string do_doc() { return {}; }
|
virtual std::string do_doc() { return {}; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// flags requested by this command
|
// flags requested by this command
|
||||||
flags flags_;
|
flags flags_;
|
||||||
|
|
||||||
@@ -140,63 +130,54 @@ private:
|
|||||||
// list of inis found by gather_inis()
|
// list of inis found by gather_inis()
|
||||||
std::vector<fs::path> inis_;
|
std::vector<fs::path> inis_;
|
||||||
|
|
||||||
|
|
||||||
// finds all the inis
|
// finds all the inis
|
||||||
//
|
//
|
||||||
int gather_inis(bool verbose);
|
int gather_inis(bool verbose);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// displays mob's version
|
||||||
// displays mob's version
|
//
|
||||||
//
|
class version_command : public command {
|
||||||
class version_command : public command
|
public:
|
||||||
{
|
|
||||||
public:
|
|
||||||
meta_t meta() const override;
|
meta_t meta() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
clipp::group do_group() override;
|
clipp::group do_group() override;
|
||||||
int do_run() override;
|
int do_run() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// displays the usage, list of commands and some additional text
|
||||||
// displays the usage, list of commands and some additional text
|
//
|
||||||
//
|
class help_command : public command {
|
||||||
class help_command : public command
|
public:
|
||||||
{
|
|
||||||
public:
|
|
||||||
meta_t meta() const override;
|
meta_t meta() const override;
|
||||||
void set_commands(const std::vector<std::shared_ptr<command>>& v);
|
void set_commands(const std::vector<std::shared_ptr<command>>& v);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
clipp::group do_group() override;
|
clipp::group do_group() override;
|
||||||
int do_run() override;
|
int do_run() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string commands_;
|
std::string commands_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// lists all options and their values
|
||||||
// lists all options and their values
|
//
|
||||||
//
|
class options_command : public command {
|
||||||
class options_command : public command
|
public:
|
||||||
{
|
|
||||||
public:
|
|
||||||
options_command();
|
options_command();
|
||||||
meta_t meta() const override;
|
meta_t meta() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
clipp::group do_group() override;
|
clipp::group do_group() override;
|
||||||
int do_run() override;
|
int do_run() override;
|
||||||
std::string do_doc() override;
|
std::string do_doc() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// builds stuff
|
||||||
// builds stuff
|
//
|
||||||
//
|
class build_command : public command {
|
||||||
class build_command : public command
|
public:
|
||||||
{
|
|
||||||
public:
|
|
||||||
build_command();
|
build_command();
|
||||||
|
|
||||||
meta_t meta() const override;
|
meta_t meta() const override;
|
||||||
@@ -205,12 +186,12 @@ public:
|
|||||||
//
|
//
|
||||||
static void terminate_msbuild();
|
static void terminate_msbuild();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void convert_cl_to_conf() override;
|
void convert_cl_to_conf() override;
|
||||||
clipp::group do_group() override;
|
clipp::group do_group() override;
|
||||||
int do_run() override;
|
int do_run() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> tasks_;
|
std::vector<std::string> tasks_;
|
||||||
bool redownload_ = false;
|
bool redownload_ = false;
|
||||||
bool reextract_ = false;
|
bool reextract_ = false;
|
||||||
@@ -225,85 +206,75 @@ private:
|
|||||||
bool keep_msbuild_ = false;
|
bool keep_msbuild_ = false;
|
||||||
std::optional<bool> revert_ts_;
|
std::optional<bool> revert_ts_;
|
||||||
|
|
||||||
|
|
||||||
// creates a bare bones ini file in the prefix so mob can be invoked in any
|
// creates a bare bones ini file in the prefix so mob can be invoked in any
|
||||||
// directory below it
|
// directory below it
|
||||||
//
|
//
|
||||||
void create_prefix_ini();
|
void create_prefix_ini();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// applies a pr
|
||||||
// applies a pr
|
//
|
||||||
//
|
class pr_command : public command {
|
||||||
class pr_command : public command
|
public:
|
||||||
{
|
|
||||||
public:
|
|
||||||
pr_command();
|
pr_command();
|
||||||
|
|
||||||
meta_t meta() const override;
|
meta_t meta() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
clipp::group do_group() override;
|
clipp::group do_group() override;
|
||||||
std::string do_doc() override;
|
std::string do_doc() override;
|
||||||
int do_run() override;
|
int do_run() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct pr_info
|
struct pr_info {
|
||||||
{
|
|
||||||
std::string repo, author, branch, title, number;
|
std::string repo, author, branch, title, number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
std::string op_;
|
std::string op_;
|
||||||
std::string pr_;
|
std::string pr_;
|
||||||
std::string github_token_;
|
std::string github_token_;
|
||||||
|
|
||||||
std::pair<const tasks::modorganizer*, std::string> parse_pr(
|
std::pair<const tasks::modorganizer*, std::string>
|
||||||
const std::string& pr) const;
|
parse_pr(const std::string& pr) const;
|
||||||
|
|
||||||
pr_info get_pr_info(const tasks::modorganizer* task, const std::string& pr);
|
pr_info get_pr_info(const tasks::modorganizer* task, const std::string& pr);
|
||||||
|
|
||||||
std::vector<pr_command::pr_info> get_matching_prs(
|
std::vector<pr_command::pr_info> get_matching_prs(const std::string& repo_pr);
|
||||||
const std::string& repo_pr);
|
|
||||||
|
|
||||||
std::vector<pr_info> search_prs(
|
std::vector<pr_info> search_prs(const std::string& org,
|
||||||
const std::string& org,
|
const std::string& author,
|
||||||
const std::string& author, const std::string& branch);
|
const std::string& branch);
|
||||||
|
|
||||||
std::vector<pr_info> validate_prs(const std::vector<pr_info>& prs);
|
std::vector<pr_info> validate_prs(const std::vector<pr_info>& prs);
|
||||||
|
|
||||||
int pull();
|
int pull();
|
||||||
int find();
|
int find();
|
||||||
int revert();
|
int revert();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// lists available tasks
|
||||||
// lists available tasks
|
//
|
||||||
//
|
class list_command : public command {
|
||||||
class list_command : public command
|
public:
|
||||||
{
|
|
||||||
public:
|
|
||||||
meta_t meta() const override;
|
meta_t meta() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
clipp::group do_group() override;
|
clipp::group do_group() override;
|
||||||
int do_run() override;
|
int do_run() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool all_ = false;
|
bool all_ = false;
|
||||||
bool aliases_ = false;
|
bool aliases_ = false;
|
||||||
std::vector<std::string> tasks_;
|
std::vector<std::string> tasks_;
|
||||||
|
|
||||||
void dump(const std::vector<task*>& v, std::size_t indent) const;
|
void dump(const std::vector<task*>& v, std::size_t indent) const;
|
||||||
void dump_aliases() const;
|
void dump_aliases() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// creates a devbuild or an official release
|
||||||
// creates a devbuild or an official release
|
//
|
||||||
//
|
class release_command : public command {
|
||||||
class release_command : public command
|
public:
|
||||||
{
|
|
||||||
public:
|
|
||||||
release_command();
|
release_command();
|
||||||
meta_t meta() const override;
|
meta_t meta() const override;
|
||||||
|
|
||||||
@@ -313,22 +284,16 @@ public:
|
|||||||
void make_uibase();
|
void make_uibase();
|
||||||
void make_installer();
|
void make_installer();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
clipp::group do_group() override;
|
clipp::group do_group() override;
|
||||||
int do_run() override;
|
int do_run() override;
|
||||||
std::string do_doc() override;
|
std::string do_doc() override;
|
||||||
void convert_cl_to_conf() override;
|
void convert_cl_to_conf() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class modes
|
enum class modes { none = 0, devbuild, official };
|
||||||
{
|
|
||||||
none = 0,
|
|
||||||
devbuild,
|
|
||||||
official
|
|
||||||
};
|
|
||||||
|
|
||||||
|
modes mode_ = modes::none;
|
||||||
modes mode_= modes::none;
|
|
||||||
bool bin_ = true;
|
bool bin_ = true;
|
||||||
bool src_ = true;
|
bool src_ = true;
|
||||||
bool pdbs_ = true;
|
bool pdbs_ = true;
|
||||||
@@ -345,7 +310,6 @@ private:
|
|||||||
std::string suffix_;
|
std::string suffix_;
|
||||||
std::string branch_;
|
std::string branch_;
|
||||||
|
|
||||||
|
|
||||||
int do_devbuild();
|
int do_devbuild();
|
||||||
int do_official();
|
int do_official();
|
||||||
|
|
||||||
@@ -355,37 +319,28 @@ private:
|
|||||||
|
|
||||||
fs::path make_filename(const std::string& what) const;
|
fs::path make_filename(const std::string& what) const;
|
||||||
|
|
||||||
void walk_dir(
|
void walk_dir(const fs::path& dir, std::vector<fs::path>& files,
|
||||||
const fs::path& dir, std::vector<fs::path>& files,
|
const std::vector<std::regex>& ignore_re,
|
||||||
const std::vector<std::regex>& ignore_re, std::size_t& total_size);
|
std::size_t& total_size);
|
||||||
|
|
||||||
std::string version_from_exe() const;
|
std::string version_from_exe() const;
|
||||||
std::string version_from_rc() const;
|
std::string version_from_rc() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// manages git repos
|
||||||
// manages git repos
|
//
|
||||||
//
|
class git_command : public command {
|
||||||
class git_command : public command
|
public:
|
||||||
{
|
|
||||||
public:
|
|
||||||
git_command();
|
git_command();
|
||||||
meta_t meta() const override;
|
meta_t meta() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
clipp::group do_group() override;
|
clipp::group do_group() override;
|
||||||
int do_run() override;
|
int do_run() override;
|
||||||
std::string do_doc() override;
|
std::string do_doc() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class modes
|
enum class modes { none = 0, set_remotes, add_remote, ignore_ts, branches };
|
||||||
{
|
|
||||||
none = 0,
|
|
||||||
set_remotes,
|
|
||||||
add_remote,
|
|
||||||
ignore_ts,
|
|
||||||
branches
|
|
||||||
};
|
|
||||||
|
|
||||||
modes mode_ = modes::none;
|
modes mode_ = modes::none;
|
||||||
std::string username_;
|
std::string username_;
|
||||||
@@ -410,66 +365,56 @@ private:
|
|||||||
void do_branches();
|
void do_branches();
|
||||||
|
|
||||||
std::vector<fs::path> get_repos() const;
|
std::vector<fs::path> get_repos() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// runs cmake in a directory with the same parameters as `build` would
|
||||||
// runs cmake in a directory with the same parameters as `build` would
|
//
|
||||||
//
|
class cmake_command : public command {
|
||||||
class cmake_command : public command
|
public:
|
||||||
{
|
|
||||||
public:
|
|
||||||
cmake_command();
|
cmake_command();
|
||||||
meta_t meta() const override;
|
meta_t meta() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
clipp::group do_group() override;
|
clipp::group do_group() override;
|
||||||
int do_run() override;
|
int do_run() override;
|
||||||
std::string do_doc() override;
|
std::string do_doc() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string gen_;
|
std::string gen_;
|
||||||
std::string cmd_;
|
std::string cmd_;
|
||||||
bool x64_ = true;
|
bool x64_ = true;
|
||||||
|
bool debug_ = false;
|
||||||
std::string prefix_;
|
std::string prefix_;
|
||||||
std::string path_;
|
std::string path_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// lists the inis found by mob
|
||||||
// lists the inis found by mob
|
//
|
||||||
//
|
class inis_command : public command {
|
||||||
class inis_command : public command
|
public:
|
||||||
{
|
|
||||||
public:
|
|
||||||
meta_t meta() const override;
|
meta_t meta() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
clipp::group do_group() override;
|
clipp::group do_group() override;
|
||||||
int do_run() override;
|
int do_run() override;
|
||||||
std::string do_doc() override;
|
std::string do_doc() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// manages transifex
|
||||||
// manages transifex
|
//
|
||||||
//
|
class tx_command : public command {
|
||||||
class tx_command : public command
|
public:
|
||||||
{
|
|
||||||
public:
|
|
||||||
tx_command();
|
tx_command();
|
||||||
meta_t meta() const override;
|
meta_t meta() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
clipp::group do_group() override;
|
clipp::group do_group() override;
|
||||||
void convert_cl_to_conf() override;
|
void convert_cl_to_conf() override;
|
||||||
int do_run() override;
|
int do_run() override;
|
||||||
std::string do_doc() override;
|
std::string do_doc() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class modes
|
enum class modes { none = 0, get, build };
|
||||||
{
|
|
||||||
none = 0,
|
|
||||||
get,
|
|
||||||
build
|
|
||||||
};
|
|
||||||
|
|
||||||
modes mode_ = modes::none;
|
modes mode_ = modes::none;
|
||||||
std::string key_, team_, project_, url_;
|
std::string key_, team_, project_, url_;
|
||||||
@@ -480,6 +425,6 @@ private:
|
|||||||
|
|
||||||
void do_get();
|
void do_get();
|
||||||
void do_build();
|
void do_build();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace mob
|
||||||
|
|||||||
+87
-125
@@ -1,125 +1,98 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "commands.h"
|
|
||||||
#include "../tasks/tasks.h"
|
#include "../tasks/tasks.h"
|
||||||
#include "../tools/tools.h"
|
#include "../tools/tools.h"
|
||||||
|
#include "commands.h"
|
||||||
|
|
||||||
namespace mob
|
namespace mob {
|
||||||
{
|
|
||||||
|
|
||||||
git_command::git_command()
|
git_command::git_command() : command(requires_options) {}
|
||||||
: command(requires_options)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
command::meta_t git_command::meta() const
|
command::meta_t git_command::meta() const
|
||||||
{
|
|
||||||
return
|
|
||||||
{
|
{
|
||||||
"git",
|
return {"git", "manages the git repos"};
|
||||||
"manages the git repos"
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
clipp::group git_command::do_group()
|
clipp::group git_command::do_group()
|
||||||
{
|
{
|
||||||
return clipp::group(
|
return clipp::group(
|
||||||
clipp::command("git").set(picked_),
|
clipp::command("git").set(picked_),
|
||||||
|
|
||||||
(clipp::option("-h", "--help") >> help_)
|
(clipp::option("-h", "--help") >> help_) % ("shows this message"),
|
||||||
% ("shows this message"),
|
|
||||||
|
|
||||||
"set-remotes" %
|
"set-remotes" %
|
||||||
(clipp::command("set-remotes").set(mode_, modes::set_remotes),
|
(clipp::command("set-remotes").set(mode_, modes::set_remotes),
|
||||||
(clipp::required("-u", "--username")
|
(clipp::required("-u", "--username") &
|
||||||
& clipp::value("USERNAME") >> username_)
|
clipp::value("USERNAME") >> username_) %
|
||||||
% "git username",
|
"git username",
|
||||||
|
|
||||||
(clipp::required("-e", "--email")
|
(clipp::required("-e", "--email") &
|
||||||
& clipp::value("EMAIL") >> email_)
|
clipp::value("EMAIL") >> email_) %
|
||||||
% "git email",
|
"git email",
|
||||||
|
|
||||||
(clipp::option("-k", "--key")
|
(clipp::option("-k", "--key") & clipp::value("PATH") >> key_) %
|
||||||
& clipp::value("PATH") >> key_)
|
"path to putty key",
|
||||||
% "path to putty key",
|
|
||||||
|
|
||||||
(clipp::option("-s", "--no-push").set(nopush_)
|
(clipp::option("-s", "--no-push").set(nopush_) %
|
||||||
% "disables pushing to 'upstream' by changing the push url "
|
"disables pushing to 'upstream' by changing the push url "
|
||||||
"to 'nopushurl' to avoid accidental pushes"),
|
"to 'nopushurl' to avoid accidental pushes"),
|
||||||
|
|
||||||
(clipp::option("-p", "--push-origin").set(push_default_)
|
(clipp::option("-p", "--push-origin").set(push_default_) %
|
||||||
% "sets the new 'origin' remote as the default push target"),
|
"sets the new 'origin' remote as the default push target"),
|
||||||
|
|
||||||
(clipp::opt_value("path") >> path_)
|
(clipp::opt_value("path") >> path_) % "only use this repo")
|
||||||
% "only use this repo"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
|
|
||||||
|
|
||||||
"add-remote" %
|
"add-remote" %
|
||||||
(clipp::command("add-remote").set(mode_, modes::add_remote),
|
(clipp::command("add-remote").set(mode_, modes::add_remote),
|
||||||
(clipp::required("-n", "--name")
|
(clipp::required("-n", "--name") &
|
||||||
& clipp::value("NAME") >> remote_)
|
clipp::value("NAME") >> remote_) %
|
||||||
% "name of new remote",
|
"name of new remote",
|
||||||
|
|
||||||
(clipp::required("-u", "--username")
|
(clipp::required("-u", "--username") &
|
||||||
& clipp::value("USERNAME") >> username_)
|
clipp::value("USERNAME") >> username_) %
|
||||||
% "git username",
|
"git username",
|
||||||
|
|
||||||
(clipp::option("-k", "--key")
|
(clipp::option("-k", "--key") & clipp::value("PATH") >> key_) %
|
||||||
& clipp::value("PATH") >> key_)
|
"path to putty key",
|
||||||
% "path to putty key",
|
|
||||||
|
|
||||||
(clipp::option("-p", "--push-origin").set(push_default_)
|
(clipp::option("-p", "--push-origin").set(push_default_) %
|
||||||
% "sets this new remote as the default push target"),
|
"sets this new remote as the default push target"),
|
||||||
|
|
||||||
(clipp::opt_value("path") >> path_)
|
(clipp::opt_value("path") >> path_) % "only use this repo")
|
||||||
% "only use this repo"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
|
|
||||||
|
|
||||||
"ignore-ts" %
|
"ignore-ts" % (clipp::command("ignore-ts").set(mode_, modes::ignore_ts),
|
||||||
(clipp::command("ignore-ts").set(mode_, modes::ignore_ts),
|
(clipp::command("on").set(tson_, true) |
|
||||||
(
|
clipp::command("off").set(tson_, false)))
|
||||||
clipp::command("on").set(tson_, true) |
|
|
||||||
clipp::command("off").set(tson_, false)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
|
|
||||||
|
|
||||||
"branches" %
|
"branches" % (clipp::command("branches").set(mode_, modes::branches),
|
||||||
(clipp::command("branches").set(mode_, modes::branches),
|
clipp::option("-a", "--all").set(all_branches_) %
|
||||||
clipp::option("-a", "--all").set(all_branches_)
|
"shows all branches, including those on master"));
|
||||||
% "shows all branches, including those on master"
|
}
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
int git_command::do_run()
|
int git_command::do_run()
|
||||||
{
|
|
||||||
switch (mode_)
|
|
||||||
{
|
|
||||||
case modes::set_remotes:
|
|
||||||
{
|
{
|
||||||
|
switch (mode_) {
|
||||||
|
case modes::set_remotes: {
|
||||||
do_set_remotes();
|
do_set_remotes();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case modes::add_remote:
|
case modes::add_remote: {
|
||||||
{
|
|
||||||
do_add_remote();
|
do_add_remote();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case modes::ignore_ts:
|
case modes::ignore_ts: {
|
||||||
{
|
|
||||||
do_ignore_ts();
|
do_ignore_ts();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case modes::branches:
|
case modes::branches: {
|
||||||
{
|
|
||||||
do_branches();
|
do_branches();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -131,12 +104,11 @@ int git_command::do_run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string git_command::do_doc()
|
std::string git_command::do_doc()
|
||||||
{
|
{
|
||||||
return
|
return "All the commands will go through all modorganizer repos, plus usvfs\n"
|
||||||
"All the commands will go through all modorganizer repos, plus usvfs\n"
|
|
||||||
"and NCC.\n"
|
"and NCC.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Commands:\n"
|
"Commands:\n"
|
||||||
@@ -156,90 +128,82 @@ std::string git_command::do_doc()
|
|||||||
"branches\n"
|
"branches\n"
|
||||||
" Lists all git repos that are not on master. With -a, show all \n"
|
" Lists all git repos that are not on master. With -a, show all \n"
|
||||||
" repos and their current branch.";
|
" repos and their current branch.";
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_command::do_set_remotes()
|
void git_command::do_set_remotes()
|
||||||
{
|
|
||||||
if (path_.empty())
|
|
||||||
{
|
{
|
||||||
|
if (path_.empty()) {
|
||||||
const auto repos = get_repos();
|
const auto repos = get_repos();
|
||||||
|
|
||||||
for (auto&& r : repos)
|
for (auto&& r : repos)
|
||||||
do_set_remotes(r);
|
do_set_remotes(r);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
do_set_remotes(path_);
|
do_set_remotes(path_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_command::do_set_remotes(const fs::path& r)
|
void git_command::do_set_remotes(const fs::path& r)
|
||||||
{
|
{
|
||||||
u8cout << "setting up " << path_to_utf8(r.filename()) << "\n";
|
u8cout << "setting up " << path_to_utf8(r.filename()) << "\n";
|
||||||
|
|
||||||
git_wrap(r).set_credentials(username_, email_);
|
git_wrap(r).set_credentials(username_, email_);
|
||||||
|
|
||||||
git_wrap(r).set_origin_and_upstream_remotes(
|
git_wrap(r).set_origin_and_upstream_remotes(username_, key_, nopush_,
|
||||||
username_, key_, nopush_, push_default_);
|
push_default_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_command::do_add_remote()
|
void git_command::do_add_remote()
|
||||||
{
|
{
|
||||||
u8cout
|
u8cout << "adding remote '" << remote_ << "' "
|
||||||
<< "adding remote '" << remote_ << "' "
|
|
||||||
<< "from '" << username_ << "' to repos\n";
|
<< "from '" << username_ << "' to repos\n";
|
||||||
|
|
||||||
if (path_.empty())
|
if (path_.empty()) {
|
||||||
{
|
|
||||||
const auto repos = get_repos();
|
const auto repos = get_repos();
|
||||||
|
|
||||||
for (auto&& r : repos)
|
for (auto&& r : repos)
|
||||||
do_add_remote(r);
|
do_add_remote(r);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
do_add_remote(path_);
|
do_add_remote(path_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_command::do_add_remote(const fs::path& r)
|
void git_command::do_add_remote(const fs::path& r)
|
||||||
{
|
{
|
||||||
u8cout << path_to_utf8(r.filename()) << "\n";
|
u8cout << path_to_utf8(r.filename()) << "\n";
|
||||||
git_wrap(r).add_remote(remote_, username_, key_, push_default_);
|
git_wrap(r).add_remote(remote_, username_, key_, push_default_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_command::do_ignore_ts()
|
void git_command::do_ignore_ts()
|
||||||
{
|
{
|
||||||
if (tson_)
|
if (tson_)
|
||||||
u8cout << "ignoring .ts files\n";
|
u8cout << "ignoring .ts files\n";
|
||||||
else
|
else
|
||||||
u8cout << "un-ignoring .ts files\n";
|
u8cout << "un-ignoring .ts files\n";
|
||||||
|
|
||||||
if (path_.empty())
|
if (path_.empty()) {
|
||||||
{
|
|
||||||
const auto repos = get_repos();
|
const auto repos = get_repos();
|
||||||
|
|
||||||
for (auto&& r : repos)
|
for (auto&& r : repos)
|
||||||
do_ignore_ts(r);
|
do_ignore_ts(r);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
do_ignore_ts(path_);
|
do_ignore_ts(path_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_command::do_ignore_ts(const fs::path& r)
|
void git_command::do_ignore_ts(const fs::path& r)
|
||||||
{
|
{
|
||||||
u8cout << path_to_utf8(r.filename()) << "\n";
|
u8cout << path_to_utf8(r.filename()) << "\n";
|
||||||
git_wrap(r).ignore_ts(tson_);
|
git_wrap(r).ignore_ts(tson_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_command::do_branches()
|
void git_command::do_branches()
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, std::string>> v;
|
std::vector<std::pair<std::string, std::string>> v;
|
||||||
|
|
||||||
for (auto&& r : get_repos())
|
for (auto&& r : get_repos()) {
|
||||||
{
|
|
||||||
const auto b = git_wrap(r).current_branch();
|
const auto b = git_wrap(r).current_branch();
|
||||||
if (b == "master" && !all_branches_)
|
if (b == "master" && !all_branches_)
|
||||||
continue;
|
continue;
|
||||||
@@ -251,10 +215,10 @@ void git_command::do_branches()
|
|||||||
}
|
}
|
||||||
|
|
||||||
u8cout << table(v, 0, 3) << "\n";
|
u8cout << table(v, 0, 3) << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<fs::path> git_command::get_repos() const
|
std::vector<fs::path> git_command::get_repos() const
|
||||||
{
|
{
|
||||||
std::vector<fs::path> v;
|
std::vector<fs::path> v;
|
||||||
|
|
||||||
// usvfs
|
// usvfs
|
||||||
@@ -264,10 +228,8 @@ std::vector<fs::path> git_command::get_repos() const
|
|||||||
const auto super = tasks::modorganizer::super_path();
|
const auto super = tasks::modorganizer::super_path();
|
||||||
|
|
||||||
// all directories in super except for those starting with a dot
|
// all directories in super except for those starting with a dot
|
||||||
if (fs::exists(super))
|
if (fs::exists(super)) {
|
||||||
{
|
for (auto e : fs::directory_iterator(super)) {
|
||||||
for (auto e : fs::directory_iterator(super))
|
|
||||||
{
|
|
||||||
if (!e.is_directory())
|
if (!e.is_directory())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -280,6 +242,6 @@ std::vector<fs::path> git_command::get_repos() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace mob
|
||||||
|
|||||||
+32
-49
@@ -1,55 +1,43 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "commands.h"
|
|
||||||
#include "../tasks/task_manager.h"
|
|
||||||
#include "../tasks/task.h"
|
#include "../tasks/task.h"
|
||||||
|
#include "../tasks/task_manager.h"
|
||||||
#include "../utility/io.h"
|
#include "../utility/io.h"
|
||||||
|
#include "commands.h"
|
||||||
|
|
||||||
namespace mob
|
namespace mob {
|
||||||
{
|
|
||||||
|
|
||||||
command::meta_t list_command::meta() const
|
command::meta_t list_command::meta() const
|
||||||
{
|
|
||||||
return
|
|
||||||
{
|
{
|
||||||
"list",
|
return {"list", "lists available tasks"};
|
||||||
"lists available tasks"
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
clipp::group list_command::do_group()
|
clipp::group list_command::do_group()
|
||||||
{
|
{
|
||||||
return clipp::group(
|
return clipp::group(
|
||||||
clipp::command("list").set(picked_),
|
clipp::command("list").set(picked_),
|
||||||
|
|
||||||
(clipp::option("-h", "--help") >> help_)
|
(clipp::option("-h", "--help") >> help_) % "shows this message",
|
||||||
% "shows this message",
|
|
||||||
|
|
||||||
(clipp::option("-a", "--all") >> all_)
|
(clipp::option("-a", "--all") >> all_) %
|
||||||
% "shows all the tasks, including pseudo parallel tasks",
|
"shows all the tasks, including pseudo parallel tasks",
|
||||||
|
|
||||||
(clipp::option("-i", "--aliases") >> aliases_)
|
(clipp::option("-i", "--aliases") >> aliases_) % "shows only aliases",
|
||||||
% "shows only aliases",
|
|
||||||
|
|
||||||
(clipp::opt_values(
|
(clipp::opt_values(clipp::match::prefix_not("-"), "task", tasks_)) %
|
||||||
clipp::match::prefix_not("-"), "task", tasks_))
|
"with -a; when given, acts like the tasks given to `build` and "
|
||||||
% "with -a; when given, acts like the tasks given to `build` and "
|
"shows only the tasks that would run");
|
||||||
"shows only the tasks that would run"
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
int list_command::do_run()
|
int list_command::do_run()
|
||||||
{
|
{
|
||||||
auto& tm = task_manager::instance();
|
auto& tm = task_manager::instance();
|
||||||
|
|
||||||
if (aliases_)
|
if (aliases_) {
|
||||||
{
|
|
||||||
load_options();
|
load_options();
|
||||||
dump_aliases();
|
dump_aliases();
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
if (all_) {
|
||||||
if (all_)
|
|
||||||
{
|
|
||||||
if (!tasks_.empty())
|
if (!tasks_.empty())
|
||||||
set_task_enabled_flags(tasks_);
|
set_task_enabled_flags(tasks_);
|
||||||
|
|
||||||
@@ -59,42 +47,37 @@ int list_command::do_run()
|
|||||||
u8cout << "\n\naliases:\n";
|
u8cout << "\n\naliases:\n";
|
||||||
dump_aliases();
|
dump_aliases();
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
for (auto&& t : tm.all())
|
for (auto&& t : tm.all())
|
||||||
u8cout << " - " << join(t->names(), ", ") << "\n";
|
u8cout << " - " << join(t->names(), ", ") << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_command::dump(const std::vector<task*>& v, std::size_t indent) const
|
void list_command::dump(const std::vector<task*>& v, std::size_t indent) const
|
||||||
{
|
|
||||||
for (auto&& t : v)
|
|
||||||
{
|
{
|
||||||
|
for (auto&& t : v) {
|
||||||
if (!t->enabled())
|
if (!t->enabled())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
u8cout
|
u8cout << std::string(indent * 4, ' ') << " - " << join(t->names(), ",")
|
||||||
<< std::string(indent*4, ' ')
|
|
||||||
<< " - " << join(t->names(), ",")
|
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
if (auto* pt=dynamic_cast<parallel_tasks*>(t))
|
if (auto* pt = dynamic_cast<parallel_tasks*>(t))
|
||||||
dump(pt->children(), indent + 1);
|
dump(pt->children(), indent + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_command::dump_aliases() const
|
void list_command::dump_aliases() const
|
||||||
{
|
{
|
||||||
const auto v = task_manager::instance().aliases();
|
const auto v = task_manager::instance().aliases();
|
||||||
if (v.empty())
|
if (v.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (auto&& [k, patterns] : v)
|
for (auto&& [k, patterns] : v)
|
||||||
u8cout << " - " << k << ": " << join(patterns, ", ") << "\n";
|
u8cout << " - " << k << ": " << join(patterns, ", ") << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace mob
|
||||||
|
|||||||
+105
-153
@@ -1,38 +1,28 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "commands.h"
|
|
||||||
#include "../core/conf.h"
|
#include "../core/conf.h"
|
||||||
#include "../tasks/task_manager.h"
|
#include "../tasks/task_manager.h"
|
||||||
#include "../tasks/tasks.h"
|
#include "../tasks/tasks.h"
|
||||||
#include "../utility.h"
|
#include "../utility.h"
|
||||||
|
#include "commands.h"
|
||||||
|
|
||||||
namespace mob
|
namespace mob {
|
||||||
{
|
|
||||||
|
|
||||||
std::string read_file(const fs::path& p)
|
std::string read_file(const fs::path& p)
|
||||||
{
|
{
|
||||||
std::ifstream t(p);
|
std::ifstream t(p);
|
||||||
return {std::istreambuf_iterator<char>(t), std::istreambuf_iterator<char>()};
|
return {std::istreambuf_iterator<char>(t), std::istreambuf_iterator<char>()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pr_command::pr_command() : command(requires_options | handle_sigint) {}
|
||||||
|
|
||||||
pr_command::pr_command()
|
command::meta_t pr_command::meta() const
|
||||||
: command(requires_options | handle_sigint)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
command::meta_t pr_command::meta() const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
{
|
{
|
||||||
"pr",
|
return {"pr", "applies changes from PRs"};
|
||||||
"applies changes from PRs"
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string pr_command::do_doc()
|
std::string pr_command::do_doc()
|
||||||
{
|
{
|
||||||
return
|
return "Operations:\n"
|
||||||
"Operations:\n"
|
|
||||||
" - find: lists all the repos that would affected by `pull` or\n"
|
" - find: lists all the repos that would affected by `pull` or\n"
|
||||||
" `revert`\n"
|
" `revert`\n"
|
||||||
" - pull: fetches the pr's branch and checks it out; all repos\n"
|
" - pull: fetches the pr's branch and checks it out; all repos\n"
|
||||||
@@ -44,29 +34,27 @@ std::string pr_command::do_doc()
|
|||||||
" - umbrella\n"
|
" - umbrella\n"
|
||||||
" - any repo that's not in modorganizer_super\n"
|
" - any repo that's not in modorganizer_super\n"
|
||||||
" - modorganizer_installer";
|
" - modorganizer_installer";
|
||||||
}
|
}
|
||||||
|
|
||||||
clipp::group pr_command::do_group()
|
clipp::group pr_command::do_group()
|
||||||
{
|
{
|
||||||
return
|
return (clipp::command("pr")).set(picked_),
|
||||||
(clipp::command("pr")).set(picked_),
|
|
||||||
|
|
||||||
(clipp::option("-h", "--help") >> help_)
|
(clipp::option("-h", "--help") >> help_) % ("shows this message"),
|
||||||
% ("shows this message"),
|
|
||||||
|
|
||||||
(clipp::option("--github-token")
|
(clipp::option("--github-token") &
|
||||||
& clipp::value("TOKEN") >> github_token_)
|
clipp::value("TOKEN") >> github_token_) %
|
||||||
% "github api key",
|
"github api key",
|
||||||
|
|
||||||
(clipp::value("OP") >> op_)
|
(clipp::value("OP") >> op_) %
|
||||||
% "one of `find`, `pull` or `revert`; see below",
|
"one of `find`, `pull` or `revert`; see below",
|
||||||
|
|
||||||
(clipp::value("PR") >> pr_)
|
(clipp::value("PR") >> pr_) %
|
||||||
% "PR to apply, must be `task/pr`, such as `modorganizer/123`";
|
"PR to apply, must be `task/pr`, such as `modorganizer/123`";
|
||||||
}
|
}
|
||||||
|
|
||||||
int pr_command::do_run()
|
int pr_command::do_run()
|
||||||
{
|
{
|
||||||
if (github_token_.empty())
|
if (github_token_.empty())
|
||||||
github_token_ = conf().global().get("github_key");
|
github_token_ = conf().global().get("github_key");
|
||||||
|
|
||||||
@@ -80,17 +68,16 @@ int pr_command::do_run()
|
|||||||
u8cerr << "bad operation '" << op_ << "'\n";
|
u8cerr << "bad operation '" << op_ << "'\n";
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<const tasks::modorganizer*, std::string> pr_command::parse_pr(
|
std::pair<const tasks::modorganizer*, std::string>
|
||||||
const std::string& pr) const
|
pr_command::parse_pr(const std::string& pr) const
|
||||||
{
|
{
|
||||||
if (pr.empty())
|
if (pr.empty())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
const auto cs = split(pr, "/");
|
const auto cs = split(pr, "/");
|
||||||
if (cs.size() != 2)
|
if (cs.size() != 2) {
|
||||||
{
|
|
||||||
u8cerr << "--pr must be task/pr, such as modorganizer/123\n";
|
u8cerr << "--pr must be task/pr, such as modorganizer/123\n";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -103,17 +90,16 @@ std::pair<const tasks::modorganizer*, std::string> pr_command::parse_pr(
|
|||||||
return {};
|
return {};
|
||||||
|
|
||||||
const auto* mo_task = dynamic_cast<const tasks::modorganizer*>(task);
|
const auto* mo_task = dynamic_cast<const tasks::modorganizer*>(task);
|
||||||
if (!mo_task)
|
if (!mo_task) {
|
||||||
{
|
|
||||||
u8cerr << "only modorganizer tasks are supported\n";
|
u8cerr << "only modorganizer tasks are supported\n";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {mo_task, pr_number};
|
return {mo_task, pr_number};
|
||||||
}
|
}
|
||||||
|
|
||||||
int pr_command::pull()
|
int pr_command::pull()
|
||||||
{
|
{
|
||||||
const auto prs = get_matching_prs(pr_);
|
const auto prs = get_matching_prs(pr_);
|
||||||
if (prs.empty())
|
if (prs.empty())
|
||||||
return 1;
|
return 1;
|
||||||
@@ -122,25 +108,21 @@ int pr_command::pull()
|
|||||||
if (okay_prs.empty())
|
if (okay_prs.empty())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
for (auto&& pr : okay_prs) {
|
||||||
for (auto&& pr : okay_prs)
|
|
||||||
{
|
|
||||||
const auto* task = dynamic_cast<const tasks::modorganizer*>(
|
const auto* task = dynamic_cast<const tasks::modorganizer*>(
|
||||||
task_manager::instance().find_one(pr.repo));
|
task_manager::instance().find_one(pr.repo));
|
||||||
|
|
||||||
if (!task)
|
if (!task)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
u8cout
|
u8cout << "checking out pr " << pr.number << " "
|
||||||
<< "checking out pr " << pr.number << " "
|
|
||||||
<< "in " << task->name() << "\n";
|
<< "in " << task->name() << "\n";
|
||||||
|
|
||||||
git_wrap g(task->source_path());
|
git_wrap g(task->source_path());
|
||||||
|
|
||||||
g.fetch(
|
g.fetch(task->git_url().string(),
|
||||||
task->git_url().string(),
|
std::format("pull/{}/head", pr.number));
|
||||||
fmt::format("pull/{}/head", pr.number));
|
|
||||||
|
|
||||||
g.checkout("FETCH_HEAD");
|
g.checkout("FETCH_HEAD");
|
||||||
}
|
}
|
||||||
@@ -149,20 +131,19 @@ int pr_command::pull()
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch(std::exception& e)
|
catch (std::exception& e) {
|
||||||
{
|
|
||||||
u8cerr << e.what() << "\n";
|
u8cerr << e.what() << "\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pr_command::find()
|
int pr_command::find()
|
||||||
{
|
{
|
||||||
return !get_matching_prs(pr_).empty();
|
return !get_matching_prs(pr_).empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
int pr_command::revert()
|
int pr_command::revert()
|
||||||
{
|
{
|
||||||
const auto prs = get_matching_prs(pr_);
|
const auto prs = get_matching_prs(pr_);
|
||||||
if (prs.empty())
|
if (prs.empty())
|
||||||
return 1;
|
return 1;
|
||||||
@@ -171,10 +152,8 @@ int pr_command::revert()
|
|||||||
if (okay_prs.empty())
|
if (okay_prs.empty())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
for (auto&& pr : okay_prs) {
|
||||||
for (auto&& pr : okay_prs)
|
|
||||||
{
|
|
||||||
const auto* task = dynamic_cast<const tasks::modorganizer*>(
|
const auto* task = dynamic_cast<const tasks::modorganizer*>(
|
||||||
task_manager::instance().find_one(pr.repo));
|
task_manager::instance().find_one(pr.repo));
|
||||||
|
|
||||||
@@ -188,16 +167,15 @@ int pr_command::revert()
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch(std::exception& e)
|
catch (std::exception& e) {
|
||||||
{
|
|
||||||
u8cerr << e.what() << "\n";
|
u8cerr << e.what() << "\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<pr_command::pr_info> pr_command::get_matching_prs(
|
std::vector<pr_command::pr_info>
|
||||||
const std::string& repo_pr)
|
pr_command::get_matching_prs(const std::string& repo_pr)
|
||||||
{
|
{
|
||||||
auto&& [task, src_pr] = parse_pr(repo_pr);
|
auto&& [task, src_pr] = parse_pr(repo_pr);
|
||||||
if (!task)
|
if (!task)
|
||||||
return {};
|
return {};
|
||||||
@@ -214,30 +192,26 @@ std::vector<pr_command::pr_info> pr_command::get_matching_prs(
|
|||||||
|
|
||||||
u8cout << "found matching prs in " << prs.size() << " repos:\n";
|
u8cout << "found matching prs in " << prs.size() << " repos:\n";
|
||||||
|
|
||||||
u8cout
|
u8cout << table(map(prs,
|
||||||
<< table(map(prs, [&](auto&& pr)
|
[&](auto&& pr) {
|
||||||
{
|
|
||||||
return std::pair(pr.repo + "/" + pr.number, pr.title);
|
return std::pair(pr.repo + "/" + pr.number, pr.title);
|
||||||
}), 2, 5)
|
}),
|
||||||
|
2, 5)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
return prs;
|
return prs;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<pr_command::pr_info> pr_command::search_prs(
|
std::vector<pr_command::pr_info> pr_command::search_prs(const std::string& org,
|
||||||
const std::string& org, const std::string& author, const std::string& branch)
|
const std::string& author,
|
||||||
{
|
const std::string& branch)
|
||||||
|
{
|
||||||
nlohmann::json json;
|
nlohmann::json json;
|
||||||
|
|
||||||
constexpr auto* pattern =
|
constexpr auto* pattern = "https://api.github.com/search/issues?per_page=100&q="
|
||||||
"https://api.github.com/search/issues?per_page=100&q="
|
"is:pr+org:{0:}+author:{1:}+is:open+head:{2:}";
|
||||||
"is:pr+org:{org:}+author:{author:}+is:open+head:{branch:}";
|
|
||||||
|
|
||||||
const auto search_url = fmt::format(
|
const auto search_url = std::format(pattern, org, author, branch);
|
||||||
pattern,
|
|
||||||
fmt::arg("org", org),
|
|
||||||
fmt::arg("author", author),
|
|
||||||
fmt::arg("branch", branch));
|
|
||||||
|
|
||||||
u8cout << "search url is " << search_url << "\n";
|
u8cout << "search url is " << search_url << "\n";
|
||||||
|
|
||||||
@@ -245,14 +219,12 @@ std::vector<pr_command::pr_info> pr_command::search_prs(
|
|||||||
|
|
||||||
curl_downloader dl;
|
curl_downloader dl;
|
||||||
|
|
||||||
dl
|
dl.url(search_url)
|
||||||
.url(search_url)
|
|
||||||
.header("Authorization", "token " + github_token_)
|
.header("Authorization", "token " + github_token_)
|
||||||
.start()
|
.start()
|
||||||
.join();
|
.join();
|
||||||
|
|
||||||
if (!dl.ok())
|
if (!dl.ok()) {
|
||||||
{
|
|
||||||
u8cerr << "failed to search github\n";
|
u8cerr << "failed to search github\n";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -260,66 +232,54 @@ std::vector<pr_command::pr_info> pr_command::search_prs(
|
|||||||
const auto output = dl.steal_output();
|
const auto output = dl.steal_output();
|
||||||
json = nlohmann::json::parse(output);
|
json = nlohmann::json::parse(output);
|
||||||
|
|
||||||
|
|
||||||
std::map<std::string, pr_info> repos;
|
std::map<std::string, pr_info> repos;
|
||||||
|
|
||||||
for (auto&& item : json["items"])
|
for (auto&& item : json["items"]) {
|
||||||
{
|
|
||||||
// ex: https://api.github.com/repos/ModOrganizer2/modorganizer-Installer
|
// ex: https://api.github.com/repos/ModOrganizer2/modorganizer-Installer
|
||||||
const std::string url = item["repository_url"];
|
const std::string url = item["repository_url"];
|
||||||
|
|
||||||
const auto last_slash = url.find_last_of("/");
|
const auto last_slash = url.find_last_of("/");
|
||||||
if (last_slash == std::string::npos)
|
if (last_slash == std::string::npos) {
|
||||||
{
|
|
||||||
u8cerr << "bad repo url in search: '" << url << "'\n";
|
u8cerr << "bad repo url in search: '" << url << "'\n";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto repo = url.substr(last_slash + 1);
|
const auto repo = url.substr(last_slash + 1);
|
||||||
|
|
||||||
pr_info info = {
|
pr_info info = {repo, author, branch, item["title"],
|
||||||
repo, author, branch, item["title"],
|
std::to_string(item["number"].get<int>())};
|
||||||
std::to_string(item["number"].get<int>())
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!repos.emplace(repo, info).second)
|
if (!repos.emplace(repo, info).second) {
|
||||||
{
|
u8cerr << "multiple prs found in repo " << repo << ", "
|
||||||
u8cerr
|
|
||||||
<< "multiple prs found in repo " << repo << ", "
|
|
||||||
<< "not supported\n";
|
<< "not supported\n";
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return map(repos, [&](auto&& pair){ return pair.second; });
|
return map(repos, [&](auto&& pair) {
|
||||||
}
|
return pair.second;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pr_command::pr_info pr_command::get_pr_info(
|
pr_command::pr_info pr_command::get_pr_info(const tasks::modorganizer* task,
|
||||||
const tasks::modorganizer* task, const std::string& pr)
|
const std::string& pr)
|
||||||
{
|
{
|
||||||
nlohmann::json json;
|
nlohmann::json json;
|
||||||
|
|
||||||
if (github_token_.empty())
|
if (github_token_.empty()) {
|
||||||
{
|
|
||||||
u8cerr << "missing --github-token\n";
|
u8cerr << "missing --github-token\n";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const url u(fmt::format(
|
const url u(std::format("https://api.github.com/repos/{}/{}/pulls/{}",
|
||||||
"https://api.github.com/repos/{}/{}/pulls/{}",
|
|
||||||
task->org(), task->repo(), pr));
|
task->org(), task->repo(), pr));
|
||||||
|
|
||||||
curl_downloader dl;
|
curl_downloader dl;
|
||||||
|
|
||||||
dl
|
dl.url(u).header("Authorization", "token " + github_token_).start().join();
|
||||||
.url(u)
|
|
||||||
.header("Authorization", "token " + github_token_)
|
|
||||||
.start()
|
|
||||||
.join();
|
|
||||||
|
|
||||||
if (!dl.ok())
|
if (!dl.ok()) {
|
||||||
{
|
|
||||||
u8cerr << "failed to get pr info from github\n";
|
u8cerr << "failed to get pr info from github\n";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -332,44 +292,37 @@ pr_command::pr_info pr_command::get_pr_info(
|
|||||||
const std::string branch = json["head"]["ref"];
|
const std::string branch = json["head"]["ref"];
|
||||||
|
|
||||||
return {repo, author, branch};
|
return {repo, author, branch};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<pr_command::pr_info> pr_command::validate_prs(
|
std::vector<pr_command::pr_info>
|
||||||
const std::vector<pr_info>& prs)
|
pr_command::validate_prs(const std::vector<pr_info>& prs)
|
||||||
{
|
{
|
||||||
std::vector<std::string> problems;
|
std::vector<std::string> problems;
|
||||||
std::vector<pr_info> okay_prs;
|
std::vector<pr_info> okay_prs;
|
||||||
|
|
||||||
for (auto&& pr : prs)
|
for (auto&& pr : prs) {
|
||||||
{
|
if (pr.repo == "mob") {
|
||||||
if (pr.repo == "mob")
|
|
||||||
{
|
|
||||||
problems.push_back("there's a pr for mob itself");
|
problems.push_back("there's a pr for mob itself");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
const auto tasks = task_manager::instance().find(pr.repo);
|
const auto tasks = task_manager::instance().find(pr.repo);
|
||||||
|
|
||||||
if (tasks.empty())
|
if (tasks.empty()) {
|
||||||
{
|
|
||||||
problems.push_back("task " + pr.repo + " does not exist");
|
problems.push_back("task " + pr.repo + " does not exist");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (tasks.size() > 1)
|
else if (tasks.size() > 1) {
|
||||||
{
|
|
||||||
problems.push_back("found more than one task for repo " + pr.repo);
|
problems.push_back("found more than one task for repo " + pr.repo);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
const auto* mo_task =
|
const auto* mo_task =
|
||||||
dynamic_cast<const tasks::modorganizer*>(tasks[0]);
|
dynamic_cast<const tasks::modorganizer*>(tasks[0]);
|
||||||
|
|
||||||
if (!mo_task)
|
if (!mo_task) {
|
||||||
{
|
problems.push_back("task " + pr.repo +
|
||||||
problems.push_back(
|
" is not a modorganizer repo");
|
||||||
"task " + pr.repo + " is not a modorganizer repo");
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -379,8 +332,7 @@ std::vector<pr_command::pr_info> pr_command::validate_prs(
|
|||||||
okay_prs.push_back(pr);
|
okay_prs.push_back(pr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!problems.empty())
|
if (!problems.empty()) {
|
||||||
{
|
|
||||||
{
|
{
|
||||||
console_color cc(console_color::yellow);
|
console_color cc(console_color::yellow);
|
||||||
|
|
||||||
@@ -391,19 +343,19 @@ std::vector<pr_command::pr_info> pr_command::validate_prs(
|
|||||||
|
|
||||||
u8cout << "\n";
|
u8cout << "\n";
|
||||||
|
|
||||||
if (okay_prs.empty())
|
if (okay_prs.empty()) {
|
||||||
{
|
|
||||||
u8cout << "all prs would be ignored, bailing out\n";
|
u8cout << "all prs would be ignored, bailing out\n";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ask_yes_no("these prs will be ignored; proceed anyway?", yn::no) != yn::yes)
|
if (ask_yes_no("these prs will be ignored; proceed anyway?", yn::no) !=
|
||||||
|
yn::yes)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
u8cout << "\n";
|
u8cout << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return okay_prs;
|
return okay_prs;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace mob
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user