mirror of
https://github.com/ModOrganizer2/mob.git
synced 2026-07-27 14:07:05 -07:00
Compare commits
59
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4227ed97ca | ||
|
|
9f1b33f3bd | ||
|
|
ec429c01d6 | ||
|
|
eba5bf49bd | ||
|
|
a308e75cf8 | ||
|
|
f99e777433 | ||
|
|
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
|
||||
if (!$root) {
|
||||
$root = "."
|
||||
}
|
||||
|
||||
cmake -B build $root | Out-Null
|
||||
cmake --build $root/build --config Release -- `
|
||||
"-p:UseMultiToolTask=true" `
|
||||
"-noLogo" `
|
||||
"-p:EnforceProcessCountAcrossBuilds=true" `
|
||||
"-clp:ErrorsOnly;Verbosity=minimal"
|
||||
$output = if ($Verbose) { "Out-Default" } else { "Out-Null" }
|
||||
|
||||
cmake -B $root/build $root | & $output
|
||||
|
||||
$installationPath = & $root\third-party\bin\vswhere.exe -products * -nologo -prerelease -latest -property installationPath
|
||||
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 (! $?) {
|
||||
Write-Error "Build failed"
|
||||
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"
|
||||
|
||||
@@ -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
|
||||
the OpenSSL License and the original SSLeay license apply to the toolkit.
|
||||
See below for the actual license texts.
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
OpenSSL License
|
||||
---------------
|
||||
1. Definitions.
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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).
|
||||
*
|
||||
*/
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
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)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* 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.]
|
||||
*/
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"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
|
||||
ignore_ts = false
|
||||
revert_ts = false
|
||||
configuration = RelWithDebInfo
|
||||
|
||||
git_url_prefix = https://github.com/
|
||||
git_shallow = true
|
||||
@@ -87,47 +88,52 @@ pull = true
|
||||
boost = true
|
||||
lz4 = true
|
||||
openssl = true
|
||||
pyqt = true
|
||||
pyqt = false
|
||||
python = true
|
||||
usvfs = false
|
||||
|
||||
[versions]
|
||||
vs = 17
|
||||
vs_year = 2022
|
||||
vs_toolset = 14.3
|
||||
sdk = 10.0.22621.0
|
||||
sevenz = 23.01
|
||||
boost = 1.82.0
|
||||
sevenz = 24.05
|
||||
boost = 1.85.0
|
||||
boost_vs = 14.3
|
||||
fmt = 8.1.1
|
||||
fmt = 10.2.1
|
||||
gtest = main
|
||||
libloot = 0.19.4
|
||||
directxtex = main
|
||||
libloot = 0.23.0
|
||||
lz4 = v1.9.4
|
||||
nmm = 0.71.2
|
||||
openssl = 1.1.1u
|
||||
pyqt = 6.5.1
|
||||
pyqt_builder = 1.15.1
|
||||
pyqt_sip = 13.5.1
|
||||
python = v3.10.12
|
||||
pybind11 = v2.10.4
|
||||
openssl = 3.3.0
|
||||
pyqt = 6.7.1.dev2407071716
|
||||
pyqt_builder = 1.16.4.dev2+g2802761
|
||||
pyqt_sip = 13.8.0
|
||||
python = v3.12.3
|
||||
pybind11 = v2.12.0
|
||||
bzip2 = 1.0.8
|
||||
sip = 6.7.1
|
||||
spdlog = v1.10.0
|
||||
qt = 6.5.1
|
||||
sip = 6.8.6.dev4+gf624736c
|
||||
spdlog = v1.14.1
|
||||
qt = 6.7.1
|
||||
qt_vs = 2019
|
||||
zlib = v1.2.13
|
||||
libbsarch = 0.0.9
|
||||
usvfs = qt6
|
||||
explorerpp = 1.3.5
|
||||
|
||||
ss_paper_lad_6788 = 7.0
|
||||
ss_paper_automata_6788 = 3.0
|
||||
ss_paper_mono_6788 = 2.2
|
||||
zlib = v1.3.1
|
||||
libbsarch = 0.0.12
|
||||
usvfs = master
|
||||
explorerpp = 1.4.0
|
||||
ss_paper_lad_6788 = 7.2
|
||||
ss_paper_automata_6788 = 3.2
|
||||
ss_paper_mono_6788 = 3.2
|
||||
ss_dark_mode_1809_6788 = 3.0
|
||||
ss_morrowind_trosski = 1.1
|
||||
ss_skyrim_trosski = v1.1
|
||||
ss_fallout3_trosski = v1.1
|
||||
ss_fallout4_trosski = v1.1
|
||||
ss_starfield_trosski = V1.11
|
||||
ss_fallout3_trosski = v1.11
|
||||
ss_fallout4_trosski = v1.11
|
||||
|
||||
[build-types]
|
||||
libbsarch = release
|
||||
pyqt = release
|
||||
python = release
|
||||
|
||||
[paths]
|
||||
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 (date 1575994670797)
|
||||
@@ -13,6 +13,7 @@
|
||||
<_DLLSuffix>-1_1</_DLLSuffix>
|
||||
<_DLLSuffix>-3</_DLLSuffix>
|
||||
<_DLLSuffix Condition="$(Platform) == 'ARM'">$(_DLLSuffix)-arm</_DLLSuffix>
|
||||
<_DLLSuffix Condition="$(Platform) == 'ARM64'">$(_DLLSuffix)-arm64</_DLLSuffix>
|
||||
+ <_DLLSuffix Condition="$(Platform) == 'x64'">$(_DLLSuffix)-x64</_DLLSuffix>
|
||||
<OpenSSLDLLSuffix Condition="$(OpenSSLDLLSuffix) == ''">$(_DLLSuffix)</OpenSSLDLLSuffix>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<_SSLDLL Include="$(opensslOutDir)\libcrypto$(_DLLSuffix).dll" />
|
||||
|
||||
@@ -25,26 +25,51 @@
|
||||
|
||||
|
||||
## Quick start
|
||||
```
|
||||
```powershell
|
||||
> git clone https://github.com/ModOrganizer2/mob
|
||||
> cd mob
|
||||
> bootstrap
|
||||
> mob -d c:\somewhere build
|
||||
```
|
||||
|
||||
## Slow 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:
|
||||
## Extended start
|
||||
|
||||
### 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
|
||||
- Additional Libraries:
|
||||
- Qt WebEngine (display nexus pages)
|
||||
- Qt Image Formats (display images in image tab and preview)
|
||||
- Qt Positioning (required by QtWebEngine)
|
||||
- Qt Serial Port (required by Qt Core)
|
||||
- Qt Web Channel (required by QtWebEngine)
|
||||
- Qt WebChannel (required by QtWebEngine)
|
||||
- Qt WebSockets (Nexus api/download)
|
||||
- Optional:
|
||||
- Qt Source 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))
|
||||
- Desktop development with C++
|
||||
- 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)
|
||||
- Windows 11 SDK (get latest)
|
||||
- C++ Build Tools core features
|
||||
- Optional:
|
||||
- Git for Windows (if you don't have git already installed)
|
||||
- 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`.
|
||||
- Git for Windows (Skip if you have this already installed outside of the VS installer)
|
||||
- CMake tools for Windows (Skip if you have this already installed outside of the VS installer)
|
||||
|
||||
## 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
|
||||
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 |
|
||||
| --- | --- | --- |
|
||||
| `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
|
||||
Unless otherwise stated, applies to any task that is a git repo.
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
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)
|
||||
|
||||
target_compile_definitions(mob PUBLIC NOMINMAX)
|
||||
|
||||
+84
-89
@@ -1,95 +1,99 @@
|
||||
#include "pch.h"
|
||||
#include "commands.h"
|
||||
#include "../core/ini.h"
|
||||
#include "../core/conf.h"
|
||||
#include "../core/context.h"
|
||||
#include "../core/ini.h"
|
||||
#include "../core/op.h"
|
||||
#include "../tasks/task_manager.h"
|
||||
#include "commands.h"
|
||||
|
||||
namespace mob
|
||||
{
|
||||
namespace mob {
|
||||
|
||||
build_command::build_command()
|
||||
: command(requires_options | handle_sigint)
|
||||
{
|
||||
}
|
||||
build_command::build_command() : command(requires_options | handle_sigint) {}
|
||||
|
||||
command::meta_t build_command::meta() const
|
||||
{
|
||||
return
|
||||
command::meta_t build_command::meta() const
|
||||
{
|
||||
"build",
|
||||
"builds tasks"
|
||||
};
|
||||
}
|
||||
return {"build", "builds tasks"};
|
||||
}
|
||||
|
||||
clipp::group build_command::do_group()
|
||||
{
|
||||
return
|
||||
(clipp::command("build")).set(picked_),
|
||||
clipp::group build_command::do_group()
|
||||
{
|
||||
return (clipp::command("build")).set(picked_),
|
||||
|
||||
(clipp::option("-h", "--help") >> help_)
|
||||
% ("shows this message"),
|
||||
(clipp::option("-h", "--help") >> help_) % ("shows this message"),
|
||||
|
||||
(clipp::option("-g", "--redownload") >> redownload_)
|
||||
% "redownloads archives, see --reextract",
|
||||
(clipp::option("-g", "--redownload") >> redownload_) %
|
||||
"redownloads archives, see --reextract",
|
||||
|
||||
(clipp::option("-e", "--reextract") >> reextract_)
|
||||
% "deletes source directories and re-extracts archives",
|
||||
(clipp::option("-e", "--reextract") >> reextract_) %
|
||||
"deletes source directories and re-extracts archives",
|
||||
|
||||
(clipp::option("-c", "--reconfigure") >> reconfigure_)
|
||||
% "reconfigures the task by running cmake, configure scripts, "
|
||||
(clipp::option("-c", "--reconfigure") >> reconfigure_) %
|
||||
"reconfigures the task by running cmake, configure scripts, "
|
||||
"etc.; some tasks might have to delete the whole source "
|
||||
"directory",
|
||||
|
||||
(clipp::option("-b", "--rebuild") >> rebuild_)
|
||||
% "cleans and rebuilds projects; some tasks might have to "
|
||||
(clipp::option("-b", "--rebuild") >> rebuild_) %
|
||||
"cleans and rebuilds projects; some tasks might have to "
|
||||
"delete the whole source directory",
|
||||
|
||||
(clipp::option("-n", "--new") >> new_)
|
||||
% "deletes everything and starts from scratch",
|
||||
(clipp::option("-n", "--new") >> new_) %
|
||||
"deletes everything and starts from scratch",
|
||||
|
||||
(
|
||||
clipp::option("--clean-task").call([&]{ clean_ = true; }) |
|
||||
clipp::option("--no-clean-task").call([&]{ clean_ = false; })
|
||||
) % "sets whether tasks are cleaned",
|
||||
(clipp::option("--clean-task").call([&] {
|
||||
clean_ = true;
|
||||
}) |
|
||||
clipp::option("--no-clean-task").call([&] {
|
||||
clean_ = false;
|
||||
})) %
|
||||
"sets whether tasks are cleaned",
|
||||
|
||||
(
|
||||
clipp::option("--fetch-task").call([&]{ fetch_ = true; }) |
|
||||
clipp::option("--no-fetch-task").call([&]{ fetch_ = false; })
|
||||
) % "sets whether tasks are fetched",
|
||||
(clipp::option("--fetch-task").call([&] {
|
||||
fetch_ = true;
|
||||
}) |
|
||||
clipp::option("--no-fetch-task").call([&] {
|
||||
fetch_ = false;
|
||||
})) %
|
||||
"sets whether tasks are fetched",
|
||||
|
||||
(
|
||||
clipp::option("--build-task").call([&]{ build_ = true; }) |
|
||||
clipp::option("--no-build-task").call([&]{ build_ = false; })
|
||||
) % "sets whether tasks are built",
|
||||
(clipp::option("--build-task").call([&] {
|
||||
build_ = true;
|
||||
}) |
|
||||
clipp::option("--no-build-task").call([&] {
|
||||
build_ = false;
|
||||
})) %
|
||||
"sets whether tasks are built",
|
||||
|
||||
(
|
||||
clipp::option("--pull").call([&]{ nopull_ = false; }) |
|
||||
clipp::option("--no-pull").call([&]{ nopull_ = true; })
|
||||
) % "whether to pull repos that are already cloned; global override",
|
||||
(clipp::option("--pull").call([&] {
|
||||
nopull_ = false;
|
||||
}) |
|
||||
clipp::option("--no-pull").call([&] {
|
||||
nopull_ = true;
|
||||
})) %
|
||||
"whether to pull repos that are already cloned; global override",
|
||||
|
||||
(
|
||||
clipp::option("--revert-ts").call([&]{ 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("--revert-ts").call([&] {
|
||||
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 "
|
||||
"avoid merge errors; global override",
|
||||
|
||||
(clipp::option("--ignore-uncommitted-changes") >> ignore_uncommitted_)
|
||||
% "when --reextract is given, directories controlled by git will "
|
||||
(clipp::option("--ignore-uncommitted-changes") >> ignore_uncommitted_) %
|
||||
"when --reextract is given, directories controlled by git will "
|
||||
"be deleted even if they contain uncommitted changes",
|
||||
|
||||
(clipp::option("--keep-msbuild") >> keep_msbuild_)
|
||||
% "don't terminate msbuild.exe instances after building",
|
||||
(clipp::option("--keep-msbuild") >> keep_msbuild_) %
|
||||
"don't terminate msbuild.exe instances after building",
|
||||
|
||||
(clipp::opt_values(
|
||||
clipp::match::prefix_not("-"), "task", tasks_))
|
||||
% "tasks to run; specify 'super' to only build modorganizer "
|
||||
(clipp::opt_values(clipp::match::prefix_not("-"), "task", tasks_)) %
|
||||
"tasks to run; specify 'super' to only build modorganizer "
|
||||
"projects";
|
||||
}
|
||||
}
|
||||
|
||||
void build_command::convert_cl_to_conf()
|
||||
{
|
||||
void build_command::convert_cl_to_conf()
|
||||
{
|
||||
command::convert_cl_to_conf();
|
||||
|
||||
if (redownload_ || new_)
|
||||
@@ -107,40 +111,35 @@ void build_command::convert_cl_to_conf()
|
||||
if (ignore_uncommitted_)
|
||||
common.options.push_back("global/ignore_uncommitted=true");
|
||||
|
||||
if (clean_)
|
||||
{
|
||||
if (clean_) {
|
||||
if (*clean_)
|
||||
common.options.push_back("global/clean_task=true");
|
||||
else
|
||||
common.options.push_back("global/clean_task=false");
|
||||
}
|
||||
|
||||
if (fetch_)
|
||||
{
|
||||
if (fetch_) {
|
||||
if (*fetch_)
|
||||
common.options.push_back("global/fetch_task=true");
|
||||
else
|
||||
common.options.push_back("global/fetch_task=false");
|
||||
}
|
||||
|
||||
if (build_)
|
||||
{
|
||||
if (build_) {
|
||||
if (*build_)
|
||||
common.options.push_back("global/build_task=true");
|
||||
else
|
||||
common.options.push_back("global/build_task=false");
|
||||
}
|
||||
|
||||
if (nopull_)
|
||||
{
|
||||
if (nopull_) {
|
||||
if (*nopull_)
|
||||
common.options.push_back("_override:task/no_pull=true");
|
||||
else
|
||||
common.options.push_back("_override:task/no_pull=false");
|
||||
}
|
||||
|
||||
if (revert_ts_)
|
||||
{
|
||||
if (revert_ts_) {
|
||||
if (*revert_ts_)
|
||||
common.options.push_back("_override:task/revert_ts=true");
|
||||
else
|
||||
@@ -149,12 +148,11 @@ void build_command::convert_cl_to_conf()
|
||||
|
||||
if (!tasks_.empty())
|
||||
set_task_enabled_flags(tasks_);
|
||||
}
|
||||
}
|
||||
|
||||
int build_command::do_run()
|
||||
{
|
||||
try
|
||||
int build_command::do_run()
|
||||
{
|
||||
try {
|
||||
create_prefix_ini();
|
||||
|
||||
task_manager::instance().run_all();
|
||||
@@ -165,15 +163,14 @@ int build_command::do_run()
|
||||
mob::gcx().info(mob::context::generic, "mob done");
|
||||
return 0;
|
||||
}
|
||||
catch(bailed&)
|
||||
{
|
||||
catch (bailed&) {
|
||||
gcx().error(context::generic, "bailing out");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void build_command::create_prefix_ini()
|
||||
{
|
||||
void build_command::create_prefix_ini()
|
||||
{
|
||||
const auto prefix = conf().path().prefix();
|
||||
|
||||
// creating prefix
|
||||
@@ -181,20 +178,18 @@ void build_command::create_prefix_ini()
|
||||
op::create_directories(gcx(), prefix);
|
||||
|
||||
const auto ini = prefix / default_ini_filename();
|
||||
if (!exists(ini))
|
||||
{
|
||||
std::ofstream(ini)
|
||||
<< "[paths]\n"
|
||||
if (!exists(ini)) {
|
||||
std::ofstream(ini) << "[paths]\n"
|
||||
<< "prefix = .\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void build_command::terminate_msbuild()
|
||||
{
|
||||
void build_command::terminate_msbuild()
|
||||
{
|
||||
if (conf().global().dry())
|
||||
return;
|
||||
|
||||
system("taskkill /im msbuild.exe /f > NUL 2>&1");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace mob
|
||||
|
||||
+33
-46
@@ -1,61 +1,49 @@
|
||||
#include "pch.h"
|
||||
#include "commands.h"
|
||||
#include "../tasks/tasks.h"
|
||||
#include "commands.h"
|
||||
|
||||
namespace mob
|
||||
{
|
||||
namespace mob {
|
||||
|
||||
cmake_command::cmake_command()
|
||||
: command(requires_options)
|
||||
{
|
||||
}
|
||||
cmake_command::cmake_command() : command(requires_options) {}
|
||||
|
||||
command::meta_t cmake_command::meta() const
|
||||
{
|
||||
return
|
||||
command::meta_t cmake_command::meta() const
|
||||
{
|
||||
"cmake",
|
||||
"runs cmake in a directory"
|
||||
};
|
||||
}
|
||||
return {"cmake", "runs cmake in a directory"};
|
||||
}
|
||||
|
||||
clipp::group cmake_command::do_group()
|
||||
{
|
||||
clipp::group cmake_command::do_group()
|
||||
{
|
||||
return clipp::group(
|
||||
clipp::command("cmake").set(picked_),
|
||||
|
||||
(clipp::option("-h", "--help") >> help_)
|
||||
% "shows this message",
|
||||
(clipp::option("-h", "--help") >> help_) % "shows this message",
|
||||
|
||||
(clipp::option("-G", "--generator")
|
||||
& clipp::value("GEN") >> gen_)
|
||||
% ("sets the -G option for cmake [default: VS]"),
|
||||
(clipp::option("-G", "--generator") & clipp::value("GEN") >> gen_) %
|
||||
("sets the -G option for cmake [default: VS]"),
|
||||
|
||||
(clipp::option("-c", "--cmd")
|
||||
& clipp::value("CMD") >> cmd_)
|
||||
% "overrides the cmake command line [default: \"..\"]",
|
||||
(clipp::option("-c", "--cmd") & clipp::value("CMD") >> cmd_) %
|
||||
"overrides the cmake command line [default: \"..\"]",
|
||||
|
||||
(
|
||||
clipp::option("--x64").set(x64_, true) |
|
||||
clipp::option("--x86").set(x64_, false)
|
||||
)
|
||||
% "whether to use the x64 or x86 vcvars; if -G is not set, "
|
||||
(clipp::option("--x64").set(x64_, true) |
|
||||
clipp::option("--x86").set(x64_, false)) %
|
||||
"whether to use the x64 or x86 vcvars; if -G is not set, "
|
||||
"whether to pass \"-A Win32\" or \"-A x64\" for the default "
|
||||
"VS generator [default: x64]",
|
||||
|
||||
(clipp::option("--install-prefix")
|
||||
& clipp::value("PATH") >> prefix_)
|
||||
% "sets CMAKE_INSTALL_PREFIX [default: empty]",
|
||||
(clipp::option("--install-prefix") & clipp::value("PATH") >> prefix_) %
|
||||
"sets CMAKE_INSTALL_PREFIX [default: empty]",
|
||||
|
||||
(clipp::value("PATH") >> path_)
|
||||
% "path from which to run `cmake`"
|
||||
);
|
||||
}
|
||||
(clipp::option("-d", "--debug").set(debug_, true)) %
|
||||
"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(
|
||||
fs::path(utf8_to_utf16(path_)));
|
||||
fs::path(utf8_to_utf16(path_)), mob::cmake::generate,
|
||||
debug_ ? config::debug : config::relwithdebinfo);
|
||||
|
||||
t.generator(gen_);
|
||||
t.cmd(cmd_);
|
||||
@@ -71,13 +59,12 @@ int cmake_command::do_run()
|
||||
t.run(cxcopy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::string cmake_command::do_doc()
|
||||
{
|
||||
return
|
||||
"Runs `cmake ..` in the given directory with the same command line\n"
|
||||
std::string cmake_command::do_doc()
|
||||
{
|
||||
return "Runs `cmake ..` in the given directory with the same command line\n"
|
||||
"as the one used for modorganizer projects.";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace mob
|
||||
|
||||
+143
-196
@@ -1,138 +1,119 @@
|
||||
#include "pch.h"
|
||||
#include "commands.h"
|
||||
#include "../utility.h"
|
||||
#include "../net.h"
|
||||
#include "../core/conf.h"
|
||||
#include "../core/ini.h"
|
||||
#include "../net.h"
|
||||
#include "../tasks/task_manager.h"
|
||||
#include "../tools/tools.h"
|
||||
#include "../utility.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
|
||||
// can be called while stuff is being output and the mutex is locked
|
||||
std::wcout << L"sigint, interrupting...\n";
|
||||
task_manager::instance().interrupt_all();
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void set_sigint_handler()
|
||||
{
|
||||
void set_sigint_handler()
|
||||
{
|
||||
::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 usage_df = clipp::doc_formatting()
|
||||
.first_column(4)
|
||||
.doc_column(30);
|
||||
auto options_df = clipp::doc_formatting().first_column(4).doc_column(30);
|
||||
|
||||
auto options_df = clipp::doc_formatting()
|
||||
.first_column(4)
|
||||
.doc_column(30);
|
||||
|
||||
u8cout
|
||||
<< "Usage:\n" << clipp::usage_lines(g, "mob", usage_df)
|
||||
<< "\n\n"
|
||||
u8cout << "Usage:\n"
|
||||
<< clipp::usage_lines(g, "mob", usage_df) << "\n\n"
|
||||
<< "Options:\n"
|
||||
<< clipp::documentation(g, options_df)
|
||||
<< "\n\n"
|
||||
<< clipp::documentation(g, options_df) << "\n\n"
|
||||
<< "To use global options with command options, make sure command \n"
|
||||
<< "options are together, with no global options in the middle.\n";
|
||||
|
||||
if (!more.empty())
|
||||
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)
|
||||
: picked_(false), help_(false), flags_(f), code_()
|
||||
{
|
||||
}
|
||||
|
||||
clipp::group command::common_options_group()
|
||||
{
|
||||
clipp::group command::common_options_group()
|
||||
{
|
||||
auto& o = common;
|
||||
const auto master = default_ini_filename();
|
||||
|
||||
return
|
||||
(clipp::repeatable(clipp::option("-i", "--ini")
|
||||
& clipp::value("FILE") >> o.inis))
|
||||
% "path to the ini file",
|
||||
return (clipp::repeatable(clipp::option("-i", "--ini") &
|
||||
clipp::value("FILE") >> o.inis)) %
|
||||
"path to the ini file",
|
||||
|
||||
(clipp::option("--dry") >> o.dry)
|
||||
% "simulates filesystem operations",
|
||||
(clipp::option("--dry") >> o.dry) % "simulates filesystem operations",
|
||||
|
||||
(clipp::option("-l", "--log-level")
|
||||
& clipp::value("LEVEL") >> o.output_log_level)
|
||||
% "0 is silent, 6 is max",
|
||||
(clipp::option("-l", "--log-level") &
|
||||
clipp::value("LEVEL") >> o.output_log_level) %
|
||||
"0 is silent, 6 is max",
|
||||
|
||||
(clipp::option("--file-log-level")
|
||||
& clipp::value("LEVEL") >> o.file_log_level)
|
||||
% "overrides --log-level for the log file",
|
||||
(clipp::option("--file-log-level") &
|
||||
clipp::value("LEVEL") >> o.file_log_level) %
|
||||
"overrides --log-level for the log file",
|
||||
|
||||
(clipp::option("--log-file")
|
||||
& clipp::value("FILE") >> o.log_file)
|
||||
% "path to log file",
|
||||
(clipp::option("--log-file") & clipp::value("FILE") >> o.log_file) %
|
||||
"path to log file",
|
||||
|
||||
(clipp::option("-d", "--destination")
|
||||
& clipp::value("DIR") >> o.prefix)
|
||||
% ("base output directory, will contain build/, install/, etc."),
|
||||
(clipp::option("-d", "--destination") &
|
||||
clipp::value("DIR") >> o.prefix) %
|
||||
("base output directory, will contain build/, install/, etc."),
|
||||
|
||||
(clipp::repeatable(clipp::option("-s", "--set")
|
||||
& clipp::value("OPTION", o.options)))
|
||||
% "sets an option, such as 'versions/openssl=1.2'",
|
||||
(clipp::repeatable(clipp::option("-s", "--set") &
|
||||
clipp::value("OPTION", o.options))) %
|
||||
"sets an option, such as 'versions/openssl=1.2'",
|
||||
|
||||
(clipp::option("--no-default-inis") >> o.no_default_inis)
|
||||
% "disables auto loading of ini files, only uses --ini; the first "
|
||||
(clipp::option("--no-default-inis") >> o.no_default_inis) %
|
||||
"disables auto loading of ini files, only uses --ini; the first "
|
||||
"--ini must be the master ini file";
|
||||
}
|
||||
}
|
||||
|
||||
void command::force_exit_code(int code)
|
||||
{
|
||||
void command::force_exit_code(int code)
|
||||
{
|
||||
code_ = code;
|
||||
}
|
||||
}
|
||||
|
||||
void command::force_help()
|
||||
{
|
||||
void command::force_help()
|
||||
{
|
||||
help_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool command::picked() const
|
||||
{
|
||||
bool command::picked() const
|
||||
{
|
||||
return picked_;
|
||||
}
|
||||
}
|
||||
|
||||
clipp::group command::group()
|
||||
{
|
||||
clipp::group command::group()
|
||||
{
|
||||
return do_group();
|
||||
}
|
||||
}
|
||||
|
||||
void command::convert_cl_to_conf()
|
||||
{
|
||||
void command::convert_cl_to_conf()
|
||||
{
|
||||
auto& o = common;
|
||||
|
||||
if (o.file_log_level == -1)
|
||||
o.file_log_level = o.output_log_level;
|
||||
|
||||
if (o.output_log_level >= 0)
|
||||
{
|
||||
o.options.push_back(
|
||||
"global/output_log_level=" +
|
||||
if (o.output_log_level >= 0) {
|
||||
o.options.push_back("global/output_log_level=" +
|
||||
std::to_string(o.output_log_level));
|
||||
}
|
||||
|
||||
if (o.file_log_level > 0)
|
||||
{
|
||||
o.options.push_back(
|
||||
"global/file_log_level=" +
|
||||
if (o.file_log_level > 0) {
|
||||
o.options.push_back("global/file_log_level=" +
|
||||
std::to_string(o.file_log_level));
|
||||
}
|
||||
|
||||
@@ -144,34 +125,30 @@ void command::convert_cl_to_conf()
|
||||
|
||||
if (!o.prefix.empty())
|
||||
o.options.push_back("paths/prefix=" + o.prefix);
|
||||
}
|
||||
}
|
||||
|
||||
int command::gather_inis(bool verbose)
|
||||
{
|
||||
int command::gather_inis(bool verbose)
|
||||
{
|
||||
auto& o = common;
|
||||
|
||||
if (o.no_default_inis && o.inis.empty())
|
||||
{
|
||||
u8cerr
|
||||
<< "--no-default-inis requires at least one --ini for the "
|
||||
if (o.no_default_inis && o.inis.empty()) {
|
||||
u8cerr << "--no-default-inis requires at least one --ini for the "
|
||||
<< "master ini file\n";
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
inis_ = find_inis(!o.no_default_inis, o.inis, verbose);
|
||||
return 0;
|
||||
}
|
||||
catch(bailed&)
|
||||
{
|
||||
catch (bailed&) {
|
||||
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");
|
||||
|
||||
bool failed = false;
|
||||
@@ -181,24 +158,22 @@ void command::set_task_enabled_flags(const std::vector<std::string>& names)
|
||||
|
||||
if (failed)
|
||||
throw bailed();
|
||||
}
|
||||
}
|
||||
|
||||
int command::prepare_options(bool verbose)
|
||||
{
|
||||
int command::prepare_options(bool verbose)
|
||||
{
|
||||
convert_cl_to_conf();
|
||||
return gather_inis(verbose);
|
||||
}
|
||||
}
|
||||
|
||||
int command::run()
|
||||
{
|
||||
if (help_)
|
||||
int command::run()
|
||||
{
|
||||
if (help_) {
|
||||
help(group(), do_doc());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (flags_ & requires_options)
|
||||
{
|
||||
if (flags_ & requires_options) {
|
||||
const auto r = load_options();
|
||||
if (r != 0)
|
||||
return r;
|
||||
@@ -213,10 +188,10 @@ int command::run()
|
||||
return *code_;
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
int command::load_options()
|
||||
{
|
||||
int command::load_options()
|
||||
{
|
||||
const int r = prepare_options(false);
|
||||
if (r != 0)
|
||||
return r;
|
||||
@@ -230,66 +205,53 @@ int command::load_options()
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
command::meta_t version_command::meta() const
|
||||
{
|
||||
return
|
||||
command::meta_t version_command::meta() const
|
||||
{
|
||||
"version",
|
||||
"shows the version"
|
||||
};
|
||||
}
|
||||
return {"version", "shows the version"};
|
||||
}
|
||||
|
||||
clipp::group version_command::do_group()
|
||||
{
|
||||
return clipp::group(
|
||||
clipp::command("version", "-v", "--version").set(picked_));
|
||||
}
|
||||
clipp::group version_command::do_group()
|
||||
{
|
||||
return clipp::group(clipp::command("version", "-v", "--version").set(picked_));
|
||||
}
|
||||
|
||||
int version_command::do_run()
|
||||
{
|
||||
int version_command::do_run()
|
||||
{
|
||||
u8cout << mob_version() << "\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
command::meta_t help_command::meta() const
|
||||
{
|
||||
return
|
||||
command::meta_t help_command::meta() const
|
||||
{
|
||||
"help",
|
||||
"shows this message"
|
||||
};
|
||||
}
|
||||
return {"help", "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;
|
||||
|
||||
for (auto&& c : v)
|
||||
s.push_back({c->meta().name, c->meta().description});
|
||||
|
||||
commands_ = table(s, 4, 3);
|
||||
}
|
||||
}
|
||||
|
||||
clipp::group help_command::do_group()
|
||||
{
|
||||
return clipp::group(
|
||||
clipp::command("-h", "--help").set(picked_));
|
||||
}
|
||||
clipp::group help_command::do_group()
|
||||
{
|
||||
return clipp::group(clipp::command("-h", "--help").set(picked_));
|
||||
}
|
||||
|
||||
int help_command::do_run()
|
||||
{
|
||||
#pragma warning(suppress: 4548)
|
||||
int help_command::do_run()
|
||||
{
|
||||
#pragma warning(suppress : 4548)
|
||||
auto doc = (command::common_options_group(), (clipp::value("command")));
|
||||
|
||||
const auto master = default_ini_filename();
|
||||
|
||||
help(doc,
|
||||
"Commands:\n"
|
||||
+ commands_ +
|
||||
"Commands:\n" + commands_ +
|
||||
"\n\n"
|
||||
"Invoking `mob -d some/prefix build` builds everything. Do \n"
|
||||
"`mob build <task name>...` to build specific tasks. See\n"
|
||||
@@ -297,7 +259,9 @@ int help_command::do_run()
|
||||
"\n"
|
||||
"INI files\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"
|
||||
"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"
|
||||
@@ -307,74 +271,57 @@ int help_command::do_run()
|
||||
"disable auto detection and only use --ini.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
options_command::options_command() : command(requires_options) {}
|
||||
|
||||
options_command::options_command()
|
||||
: command(requires_options)
|
||||
{
|
||||
}
|
||||
|
||||
command::meta_t options_command::meta() const
|
||||
{
|
||||
return
|
||||
command::meta_t options_command::meta() const
|
||||
{
|
||||
"options",
|
||||
"lists all options and their values from the inis"
|
||||
};
|
||||
}
|
||||
return {"options", "lists all options and their values from the inis"};
|
||||
}
|
||||
|
||||
clipp::group options_command::do_group()
|
||||
{
|
||||
return clipp::group(
|
||||
clipp::command("options").set(picked_),
|
||||
clipp::group options_command::do_group()
|
||||
{
|
||||
return clipp::group(clipp::command("options").set(picked_),
|
||||
|
||||
(clipp::option("-h", "--help") >> help_)
|
||||
% ("shows this message")
|
||||
);
|
||||
}
|
||||
(clipp::option("-h", "--help") >> help_) %
|
||||
("shows this message"));
|
||||
}
|
||||
|
||||
int options_command::do_run()
|
||||
{
|
||||
int options_command::do_run()
|
||||
{
|
||||
for (auto&& line : format_options())
|
||||
u8cout << line << "\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
std::string options_command::do_doc()
|
||||
{
|
||||
"inis",
|
||||
"lists the INIs used by mob"
|
||||
};
|
||||
}
|
||||
return "Lists the final value of all options found by loading the INIs.";
|
||||
}
|
||||
|
||||
clipp::group inis_command::do_group()
|
||||
{
|
||||
return clipp::group(
|
||||
clipp::command("inis").set(picked_),
|
||||
command::meta_t inis_command::meta() const
|
||||
{
|
||||
return {"inis", "lists the INIs used by mob"};
|
||||
}
|
||||
|
||||
(clipp::option("-h", "--help") >> help_)
|
||||
% ("shows this message")
|
||||
);
|
||||
}
|
||||
clipp::group inis_command::do_group()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
std::string inis_command::do_doc()
|
||||
{
|
||||
std::string inis_command::do_doc()
|
||||
{
|
||||
return "Shows which INIs are found.";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace mob
|
||||
|
||||
+105
-160
@@ -2,26 +2,22 @@
|
||||
|
||||
#include "../utility/enum.h"
|
||||
|
||||
namespace mob::tasks
|
||||
{
|
||||
namespace mob::tasks {
|
||||
class modorganizer;
|
||||
}
|
||||
|
||||
namespace mob
|
||||
{
|
||||
namespace mob {
|
||||
|
||||
class task;
|
||||
class url;
|
||||
class task;
|
||||
class url;
|
||||
|
||||
// base class for all commands
|
||||
//
|
||||
class command
|
||||
{
|
||||
public:
|
||||
// base class for all commands
|
||||
//
|
||||
class command {
|
||||
public:
|
||||
// values of options available for all commands
|
||||
//
|
||||
struct common_options
|
||||
{
|
||||
struct common_options {
|
||||
bool dry = false;
|
||||
int output_log_level = -1;
|
||||
int file_log_level = -1;
|
||||
@@ -35,12 +31,10 @@ public:
|
||||
|
||||
// returned by meta() by each command
|
||||
//
|
||||
struct meta_t
|
||||
{
|
||||
struct meta_t {
|
||||
std::string name, description;
|
||||
};
|
||||
|
||||
|
||||
static common_options common;
|
||||
static clipp::group common_options_group();
|
||||
|
||||
@@ -66,16 +60,14 @@ public:
|
||||
//
|
||||
int run();
|
||||
|
||||
|
||||
// returns meta information about this command
|
||||
//
|
||||
virtual meta_t meta() const = 0;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
// passed by derived classes in the constructor
|
||||
//
|
||||
enum flags
|
||||
{
|
||||
enum flags {
|
||||
noflags = 0x00,
|
||||
|
||||
// this command needs the ini loaded before running
|
||||
@@ -87,15 +79,13 @@ protected:
|
||||
|
||||
MOB_ENUM_FRIEND_OPERATORS(flags);
|
||||
|
||||
|
||||
// set to true when this command is entered by the user
|
||||
bool picked_;
|
||||
|
||||
// set to true with --help or by force_help()
|
||||
bool help_;
|
||||
|
||||
|
||||
command(flags f=noflags);
|
||||
command(flags f = noflags);
|
||||
|
||||
// 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
|
||||
@@ -130,7 +120,7 @@ protected:
|
||||
//
|
||||
virtual std::string do_doc() { return {}; }
|
||||
|
||||
private:
|
||||
private:
|
||||
// flags requested by this command
|
||||
flags flags_;
|
||||
|
||||
@@ -140,63 +130,54 @@ private:
|
||||
// list of inis found by gather_inis()
|
||||
std::vector<fs::path> inis_;
|
||||
|
||||
|
||||
// finds all the inis
|
||||
//
|
||||
int gather_inis(bool verbose);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// displays mob's version
|
||||
//
|
||||
class version_command : public command
|
||||
{
|
||||
public:
|
||||
// displays mob's version
|
||||
//
|
||||
class version_command : public command {
|
||||
public:
|
||||
meta_t meta() const override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
int do_run() override;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// displays the usage, list of commands and some additional text
|
||||
//
|
||||
class help_command : public command
|
||||
{
|
||||
public:
|
||||
// displays the usage, list of commands and some additional text
|
||||
//
|
||||
class help_command : public command {
|
||||
public:
|
||||
meta_t meta() const override;
|
||||
void set_commands(const std::vector<std::shared_ptr<command>>& v);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
int do_run() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
std::string commands_;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// lists all options and their values
|
||||
//
|
||||
class options_command : public command
|
||||
{
|
||||
public:
|
||||
// lists all options and their values
|
||||
//
|
||||
class options_command : public command {
|
||||
public:
|
||||
options_command();
|
||||
meta_t meta() const override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
int do_run() override;
|
||||
std::string do_doc() override;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// builds stuff
|
||||
//
|
||||
class build_command : public command
|
||||
{
|
||||
public:
|
||||
// builds stuff
|
||||
//
|
||||
class build_command : public command {
|
||||
public:
|
||||
build_command();
|
||||
|
||||
meta_t meta() const override;
|
||||
@@ -205,12 +186,12 @@ public:
|
||||
//
|
||||
static void terminate_msbuild();
|
||||
|
||||
protected:
|
||||
protected:
|
||||
void convert_cl_to_conf() override;
|
||||
clipp::group do_group() override;
|
||||
int do_run() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
std::vector<std::string> tasks_;
|
||||
bool redownload_ = false;
|
||||
bool reextract_ = false;
|
||||
@@ -225,85 +206,75 @@ private:
|
||||
bool keep_msbuild_ = false;
|
||||
std::optional<bool> revert_ts_;
|
||||
|
||||
|
||||
// creates a bare bones ini file in the prefix so mob can be invoked in any
|
||||
// directory below it
|
||||
//
|
||||
void create_prefix_ini();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// applies a pr
|
||||
//
|
||||
class pr_command : public command
|
||||
{
|
||||
public:
|
||||
// applies a pr
|
||||
//
|
||||
class pr_command : public command {
|
||||
public:
|
||||
pr_command();
|
||||
|
||||
meta_t meta() const override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
std::string do_doc() override;
|
||||
int do_run() override;
|
||||
|
||||
private:
|
||||
struct pr_info
|
||||
{
|
||||
private:
|
||||
struct pr_info {
|
||||
std::string repo, author, branch, title, number;
|
||||
};
|
||||
|
||||
|
||||
std::string op_;
|
||||
std::string pr_;
|
||||
std::string github_token_;
|
||||
|
||||
std::pair<const tasks::modorganizer*, std::string> parse_pr(
|
||||
const std::string& pr) const;
|
||||
std::pair<const tasks::modorganizer*, std::string>
|
||||
parse_pr(const std::string& pr) const;
|
||||
|
||||
pr_info get_pr_info(const tasks::modorganizer* task, const std::string& pr);
|
||||
|
||||
std::vector<pr_command::pr_info> get_matching_prs(
|
||||
const std::string& repo_pr);
|
||||
std::vector<pr_command::pr_info> get_matching_prs(const std::string& repo_pr);
|
||||
|
||||
std::vector<pr_info> search_prs(
|
||||
const std::string& org,
|
||||
const std::string& author, const std::string& branch);
|
||||
std::vector<pr_info> search_prs(const std::string& org,
|
||||
const std::string& author,
|
||||
const std::string& branch);
|
||||
|
||||
std::vector<pr_info> validate_prs(const std::vector<pr_info>& prs);
|
||||
|
||||
int pull();
|
||||
int find();
|
||||
int revert();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// lists available tasks
|
||||
//
|
||||
class list_command : public command
|
||||
{
|
||||
public:
|
||||
// lists available tasks
|
||||
//
|
||||
class list_command : public command {
|
||||
public:
|
||||
meta_t meta() const override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
int do_run() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
bool all_ = false;
|
||||
bool aliases_ = false;
|
||||
std::vector<std::string> tasks_;
|
||||
|
||||
void dump(const std::vector<task*>& v, std::size_t indent) const;
|
||||
void dump_aliases() const;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// creates a devbuild or an official release
|
||||
//
|
||||
class release_command : public command
|
||||
{
|
||||
public:
|
||||
// creates a devbuild or an official release
|
||||
//
|
||||
class release_command : public command {
|
||||
public:
|
||||
release_command();
|
||||
meta_t meta() const override;
|
||||
|
||||
@@ -313,22 +284,16 @@ public:
|
||||
void make_uibase();
|
||||
void make_installer();
|
||||
|
||||
protected:
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
int do_run() override;
|
||||
std::string do_doc() override;
|
||||
void convert_cl_to_conf() override;
|
||||
|
||||
private:
|
||||
enum class modes
|
||||
{
|
||||
none = 0,
|
||||
devbuild,
|
||||
official
|
||||
};
|
||||
private:
|
||||
enum class modes { none = 0, devbuild, official };
|
||||
|
||||
|
||||
modes mode_= modes::none;
|
||||
modes mode_ = modes::none;
|
||||
bool bin_ = true;
|
||||
bool src_ = true;
|
||||
bool pdbs_ = true;
|
||||
@@ -345,7 +310,6 @@ private:
|
||||
std::string suffix_;
|
||||
std::string branch_;
|
||||
|
||||
|
||||
int do_devbuild();
|
||||
int do_official();
|
||||
|
||||
@@ -355,37 +319,28 @@ private:
|
||||
|
||||
fs::path make_filename(const std::string& what) const;
|
||||
|
||||
void walk_dir(
|
||||
const fs::path& dir, std::vector<fs::path>& files,
|
||||
const std::vector<std::regex>& ignore_re, std::size_t& total_size);
|
||||
void walk_dir(const fs::path& dir, std::vector<fs::path>& files,
|
||||
const std::vector<std::regex>& ignore_re,
|
||||
std::size_t& total_size);
|
||||
|
||||
std::string version_from_exe() const;
|
||||
std::string version_from_rc() const;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// manages git repos
|
||||
//
|
||||
class git_command : public command
|
||||
{
|
||||
public:
|
||||
// manages git repos
|
||||
//
|
||||
class git_command : public command {
|
||||
public:
|
||||
git_command();
|
||||
meta_t meta() const override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
int do_run() override;
|
||||
std::string do_doc() override;
|
||||
|
||||
private:
|
||||
enum class modes
|
||||
{
|
||||
none = 0,
|
||||
set_remotes,
|
||||
add_remote,
|
||||
ignore_ts,
|
||||
branches
|
||||
};
|
||||
private:
|
||||
enum class modes { none = 0, set_remotes, add_remote, ignore_ts, branches };
|
||||
|
||||
modes mode_ = modes::none;
|
||||
std::string username_;
|
||||
@@ -410,66 +365,56 @@ private:
|
||||
void do_branches();
|
||||
|
||||
std::vector<fs::path> get_repos() const;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// runs cmake in a directory with the same parameters as `build` would
|
||||
//
|
||||
class cmake_command : public command
|
||||
{
|
||||
public:
|
||||
// runs cmake in a directory with the same parameters as `build` would
|
||||
//
|
||||
class cmake_command : public command {
|
||||
public:
|
||||
cmake_command();
|
||||
meta_t meta() const override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
int do_run() override;
|
||||
std::string do_doc() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
std::string gen_;
|
||||
std::string cmd_;
|
||||
bool x64_ = true;
|
||||
bool debug_ = false;
|
||||
std::string prefix_;
|
||||
std::string path_;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// lists the inis found by mob
|
||||
//
|
||||
class inis_command : public command
|
||||
{
|
||||
public:
|
||||
// lists the inis found by mob
|
||||
//
|
||||
class inis_command : public command {
|
||||
public:
|
||||
meta_t meta() const override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
int do_run() override;
|
||||
std::string do_doc() override;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// manages transifex
|
||||
//
|
||||
class tx_command : public command
|
||||
{
|
||||
public:
|
||||
// manages transifex
|
||||
//
|
||||
class tx_command : public command {
|
||||
public:
|
||||
tx_command();
|
||||
meta_t meta() const override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
void convert_cl_to_conf() override;
|
||||
int do_run() override;
|
||||
std::string do_doc() override;
|
||||
|
||||
private:
|
||||
enum class modes
|
||||
{
|
||||
none = 0,
|
||||
get,
|
||||
build
|
||||
};
|
||||
private:
|
||||
enum class modes { none = 0, get, build };
|
||||
|
||||
modes mode_ = modes::none;
|
||||
std::string key_, team_, project_, url_;
|
||||
@@ -480,6 +425,6 @@ private:
|
||||
|
||||
void do_get();
|
||||
void do_build();
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace mob
|
||||
|
||||
+87
-125
@@ -1,125 +1,98 @@
|
||||
#include "pch.h"
|
||||
#include "commands.h"
|
||||
#include "../tasks/tasks.h"
|
||||
#include "../tools/tools.h"
|
||||
#include "commands.h"
|
||||
|
||||
namespace mob
|
||||
{
|
||||
namespace mob {
|
||||
|
||||
git_command::git_command()
|
||||
: command(requires_options)
|
||||
{
|
||||
}
|
||||
git_command::git_command() : command(requires_options) {}
|
||||
|
||||
command::meta_t git_command::meta() const
|
||||
{
|
||||
return
|
||||
command::meta_t git_command::meta() const
|
||||
{
|
||||
"git",
|
||||
"manages the git repos"
|
||||
};
|
||||
}
|
||||
return {"git", "manages the git repos"};
|
||||
}
|
||||
|
||||
clipp::group git_command::do_group()
|
||||
{
|
||||
clipp::group git_command::do_group()
|
||||
{
|
||||
return clipp::group(
|
||||
clipp::command("git").set(picked_),
|
||||
|
||||
(clipp::option("-h", "--help") >> help_)
|
||||
% ("shows this message"),
|
||||
(clipp::option("-h", "--help") >> help_) % ("shows this message"),
|
||||
|
||||
"set-remotes" %
|
||||
(clipp::command("set-remotes").set(mode_, modes::set_remotes),
|
||||
(clipp::required("-u", "--username")
|
||||
& clipp::value("USERNAME") >> username_)
|
||||
% "git username",
|
||||
(clipp::required("-u", "--username") &
|
||||
clipp::value("USERNAME") >> username_) %
|
||||
"git username",
|
||||
|
||||
(clipp::required("-e", "--email")
|
||||
& clipp::value("EMAIL") >> email_)
|
||||
% "git email",
|
||||
(clipp::required("-e", "--email") &
|
||||
clipp::value("EMAIL") >> email_) %
|
||||
"git email",
|
||||
|
||||
(clipp::option("-k", "--key")
|
||||
& clipp::value("PATH") >> key_)
|
||||
% "path to putty key",
|
||||
(clipp::option("-k", "--key") & clipp::value("PATH") >> key_) %
|
||||
"path to putty key",
|
||||
|
||||
(clipp::option("-s", "--no-push").set(nopush_)
|
||||
% "disables pushing to 'upstream' by changing the push url "
|
||||
(clipp::option("-s", "--no-push").set(nopush_) %
|
||||
"disables pushing to 'upstream' by changing the push url "
|
||||
"to 'nopushurl' to avoid accidental pushes"),
|
||||
|
||||
(clipp::option("-p", "--push-origin").set(push_default_)
|
||||
% "sets the new 'origin' remote as the default push target"),
|
||||
(clipp::option("-p", "--push-origin").set(push_default_) %
|
||||
"sets the new 'origin' remote as the default push target"),
|
||||
|
||||
(clipp::opt_value("path") >> path_)
|
||||
% "only use this repo"
|
||||
)
|
||||
(clipp::opt_value("path") >> path_) % "only use this repo")
|
||||
|
||||
|
|
||||
|
||||
"add-remote" %
|
||||
(clipp::command("add-remote").set(mode_, modes::add_remote),
|
||||
(clipp::required("-n", "--name")
|
||||
& clipp::value("NAME") >> remote_)
|
||||
% "name of new remote",
|
||||
(clipp::required("-n", "--name") &
|
||||
clipp::value("NAME") >> remote_) %
|
||||
"name of new remote",
|
||||
|
||||
(clipp::required("-u", "--username")
|
||||
& clipp::value("USERNAME") >> username_)
|
||||
% "git username",
|
||||
(clipp::required("-u", "--username") &
|
||||
clipp::value("USERNAME") >> username_) %
|
||||
"git username",
|
||||
|
||||
(clipp::option("-k", "--key")
|
||||
& clipp::value("PATH") >> key_)
|
||||
% "path to putty key",
|
||||
(clipp::option("-k", "--key") & clipp::value("PATH") >> key_) %
|
||||
"path to putty key",
|
||||
|
||||
(clipp::option("-p", "--push-origin").set(push_default_)
|
||||
% "sets this new remote as the default push target"),
|
||||
(clipp::option("-p", "--push-origin").set(push_default_) %
|
||||
"sets this new remote as the default push target"),
|
||||
|
||||
(clipp::opt_value("path") >> path_)
|
||||
% "only use this repo"
|
||||
)
|
||||
(clipp::opt_value("path") >> path_) % "only use this repo")
|
||||
|
||||
|
|
||||
|
||||
"ignore-ts" %
|
||||
(clipp::command("ignore-ts").set(mode_, modes::ignore_ts),
|
||||
(
|
||||
clipp::command("on").set(tson_, true) |
|
||||
clipp::command("off").set(tson_, false)
|
||||
)
|
||||
)
|
||||
"ignore-ts" % (clipp::command("ignore-ts").set(mode_, modes::ignore_ts),
|
||||
(clipp::command("on").set(tson_, true) |
|
||||
clipp::command("off").set(tson_, false)))
|
||||
|
||||
|
|
||||
|
||||
"branches" %
|
||||
(clipp::command("branches").set(mode_, modes::branches),
|
||||
clipp::option("-a", "--all").set(all_branches_)
|
||||
% "shows all branches, including those on master"
|
||||
)
|
||||
);
|
||||
}
|
||||
"branches" % (clipp::command("branches").set(mode_, modes::branches),
|
||||
clipp::option("-a", "--all").set(all_branches_) %
|
||||
"shows all branches, including those on master"));
|
||||
}
|
||||
|
||||
int git_command::do_run()
|
||||
{
|
||||
switch (mode_)
|
||||
{
|
||||
case modes::set_remotes:
|
||||
int git_command::do_run()
|
||||
{
|
||||
switch (mode_) {
|
||||
case modes::set_remotes: {
|
||||
do_set_remotes();
|
||||
break;
|
||||
}
|
||||
|
||||
case modes::add_remote:
|
||||
{
|
||||
case modes::add_remote: {
|
||||
do_add_remote();
|
||||
break;
|
||||
}
|
||||
|
||||
case modes::ignore_ts:
|
||||
{
|
||||
case modes::ignore_ts: {
|
||||
do_ignore_ts();
|
||||
break;
|
||||
}
|
||||
|
||||
case modes::branches:
|
||||
{
|
||||
case modes::branches: {
|
||||
do_branches();
|
||||
break;
|
||||
}
|
||||
@@ -131,12 +104,11 @@ int git_command::do_run()
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::string git_command::do_doc()
|
||||
{
|
||||
return
|
||||
"All the commands will go through all modorganizer repos, plus usvfs\n"
|
||||
std::string git_command::do_doc()
|
||||
{
|
||||
return "All the commands will go through all modorganizer repos, plus usvfs\n"
|
||||
"and NCC.\n"
|
||||
"\n"
|
||||
"Commands:\n"
|
||||
@@ -156,90 +128,82 @@ std::string git_command::do_doc()
|
||||
"branches\n"
|
||||
" Lists all git repos that are not on master. With -a, show all \n"
|
||||
" repos and their current branch.";
|
||||
}
|
||||
}
|
||||
|
||||
void git_command::do_set_remotes()
|
||||
{
|
||||
if (path_.empty())
|
||||
void git_command::do_set_remotes()
|
||||
{
|
||||
if (path_.empty()) {
|
||||
const auto repos = get_repos();
|
||||
|
||||
for (auto&& r : repos)
|
||||
do_set_remotes(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
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";
|
||||
|
||||
git_wrap(r).set_credentials(username_, email_);
|
||||
|
||||
git_wrap(r).set_origin_and_upstream_remotes(
|
||||
username_, key_, nopush_, push_default_);
|
||||
}
|
||||
git_wrap(r).set_origin_and_upstream_remotes(username_, key_, nopush_,
|
||||
push_default_);
|
||||
}
|
||||
|
||||
void git_command::do_add_remote()
|
||||
{
|
||||
u8cout
|
||||
<< "adding remote '" << remote_ << "' "
|
||||
void git_command::do_add_remote()
|
||||
{
|
||||
u8cout << "adding remote '" << remote_ << "' "
|
||||
<< "from '" << username_ << "' to repos\n";
|
||||
|
||||
if (path_.empty())
|
||||
{
|
||||
if (path_.empty()) {
|
||||
const auto repos = get_repos();
|
||||
|
||||
for (auto&& r : repos)
|
||||
do_add_remote(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
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";
|
||||
git_wrap(r).add_remote(remote_, username_, key_, push_default_);
|
||||
}
|
||||
}
|
||||
|
||||
void git_command::do_ignore_ts()
|
||||
{
|
||||
void git_command::do_ignore_ts()
|
||||
{
|
||||
if (tson_)
|
||||
u8cout << "ignoring .ts files\n";
|
||||
else
|
||||
u8cout << "un-ignoring .ts files\n";
|
||||
|
||||
if (path_.empty())
|
||||
{
|
||||
if (path_.empty()) {
|
||||
const auto repos = get_repos();
|
||||
|
||||
for (auto&& r : repos)
|
||||
do_ignore_ts(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
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";
|
||||
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;
|
||||
|
||||
for (auto&& r : get_repos())
|
||||
{
|
||||
for (auto&& r : get_repos()) {
|
||||
const auto b = git_wrap(r).current_branch();
|
||||
if (b == "master" && !all_branches_)
|
||||
continue;
|
||||
@@ -251,10 +215,10 @@ void git_command::do_branches()
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// usvfs
|
||||
@@ -264,10 +228,8 @@ std::vector<fs::path> git_command::get_repos() const
|
||||
const auto super = tasks::modorganizer::super_path();
|
||||
|
||||
// all directories in super except for those starting with a dot
|
||||
if (fs::exists(super))
|
||||
{
|
||||
for (auto e : fs::directory_iterator(super))
|
||||
{
|
||||
if (fs::exists(super)) {
|
||||
for (auto e : fs::directory_iterator(super)) {
|
||||
if (!e.is_directory())
|
||||
continue;
|
||||
|
||||
@@ -280,6 +242,6 @@ std::vector<fs::path> git_command::get_repos() const
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace mob
|
||||
|
||||
+32
-49
@@ -1,55 +1,43 @@
|
||||
#include "pch.h"
|
||||
#include "commands.h"
|
||||
#include "../tasks/task_manager.h"
|
||||
#include "../tasks/task.h"
|
||||
#include "../tasks/task_manager.h"
|
||||
#include "../utility/io.h"
|
||||
#include "commands.h"
|
||||
|
||||
namespace mob
|
||||
{
|
||||
namespace mob {
|
||||
|
||||
command::meta_t list_command::meta() const
|
||||
{
|
||||
return
|
||||
command::meta_t list_command::meta() const
|
||||
{
|
||||
"list",
|
||||
"lists available tasks"
|
||||
};
|
||||
}
|
||||
return {"list", "lists available tasks"};
|
||||
}
|
||||
|
||||
clipp::group list_command::do_group()
|
||||
{
|
||||
clipp::group list_command::do_group()
|
||||
{
|
||||
return clipp::group(
|
||||
clipp::command("list").set(picked_),
|
||||
|
||||
(clipp::option("-h", "--help") >> help_)
|
||||
% "shows this message",
|
||||
(clipp::option("-h", "--help") >> help_) % "shows this message",
|
||||
|
||||
(clipp::option("-a", "--all") >> all_)
|
||||
% "shows all the tasks, including pseudo parallel tasks",
|
||||
(clipp::option("-a", "--all") >> all_) %
|
||||
"shows all the tasks, including pseudo parallel tasks",
|
||||
|
||||
(clipp::option("-i", "--aliases") >> aliases_)
|
||||
% "shows only aliases",
|
||||
(clipp::option("-i", "--aliases") >> aliases_) % "shows only aliases",
|
||||
|
||||
(clipp::opt_values(
|
||||
clipp::match::prefix_not("-"), "task", tasks_))
|
||||
% "with -a; when given, acts like the tasks given to `build` and "
|
||||
"shows only the tasks that would run"
|
||||
);
|
||||
}
|
||||
(clipp::opt_values(clipp::match::prefix_not("-"), "task", tasks_)) %
|
||||
"with -a; when given, acts like the tasks given to `build` and "
|
||||
"shows only the tasks that would run");
|
||||
}
|
||||
|
||||
int list_command::do_run()
|
||||
{
|
||||
int list_command::do_run()
|
||||
{
|
||||
auto& tm = task_manager::instance();
|
||||
|
||||
if (aliases_)
|
||||
{
|
||||
if (aliases_) {
|
||||
load_options();
|
||||
dump_aliases();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (all_)
|
||||
{
|
||||
else {
|
||||
if (all_) {
|
||||
if (!tasks_.empty())
|
||||
set_task_enabled_flags(tasks_);
|
||||
|
||||
@@ -59,42 +47,37 @@ int list_command::do_run()
|
||||
u8cout << "\n\naliases:\n";
|
||||
dump_aliases();
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
for (auto&& t : tm.all())
|
||||
u8cout << " - " << join(t->names(), ", ") << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void list_command::dump(const std::vector<task*>& v, std::size_t indent) const
|
||||
{
|
||||
for (auto&& t : v)
|
||||
void list_command::dump(const std::vector<task*>& v, std::size_t indent) const
|
||||
{
|
||||
for (auto&& t : v) {
|
||||
if (!t->enabled())
|
||||
continue;
|
||||
|
||||
u8cout
|
||||
<< std::string(indent*4, ' ')
|
||||
<< " - " << join(t->names(), ",")
|
||||
u8cout << std::string(indent * 4, ' ') << " - " << join(t->names(), ",")
|
||||
<< "\n";
|
||||
|
||||
if (auto* pt=dynamic_cast<parallel_tasks*>(t))
|
||||
if (auto* pt = dynamic_cast<parallel_tasks*>(t))
|
||||
dump(pt->children(), indent + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void list_command::dump_aliases() const
|
||||
{
|
||||
void list_command::dump_aliases() const
|
||||
{
|
||||
const auto v = task_manager::instance().aliases();
|
||||
if (v.empty())
|
||||
return;
|
||||
|
||||
for (auto&& [k, patterns] : v)
|
||||
u8cout << " - " << k << ": " << join(patterns, ", ") << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace mob
|
||||
|
||||
+105
-153
@@ -1,38 +1,28 @@
|
||||
#include "pch.h"
|
||||
#include "commands.h"
|
||||
#include "../core/conf.h"
|
||||
#include "../tasks/task_manager.h"
|
||||
#include "../tasks/tasks.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);
|
||||
return {std::istreambuf_iterator<char>(t), std::istreambuf_iterator<char>()};
|
||||
}
|
||||
}
|
||||
|
||||
pr_command::pr_command() : command(requires_options | handle_sigint) {}
|
||||
|
||||
pr_command::pr_command()
|
||||
: command(requires_options | handle_sigint)
|
||||
{
|
||||
}
|
||||
|
||||
command::meta_t pr_command::meta() const
|
||||
{
|
||||
return
|
||||
command::meta_t pr_command::meta() const
|
||||
{
|
||||
"pr",
|
||||
"applies changes from PRs"
|
||||
};
|
||||
}
|
||||
return {"pr", "applies changes from PRs"};
|
||||
}
|
||||
|
||||
std::string pr_command::do_doc()
|
||||
{
|
||||
return
|
||||
"Operations:\n"
|
||||
std::string pr_command::do_doc()
|
||||
{
|
||||
return "Operations:\n"
|
||||
" - find: lists all the repos that would affected by `pull` or\n"
|
||||
" `revert`\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"
|
||||
" - any repo that's not in modorganizer_super\n"
|
||||
" - modorganizer_installer";
|
||||
}
|
||||
}
|
||||
|
||||
clipp::group pr_command::do_group()
|
||||
{
|
||||
return
|
||||
(clipp::command("pr")).set(picked_),
|
||||
clipp::group pr_command::do_group()
|
||||
{
|
||||
return (clipp::command("pr")).set(picked_),
|
||||
|
||||
(clipp::option("-h", "--help") >> help_)
|
||||
% ("shows this message"),
|
||||
(clipp::option("-h", "--help") >> help_) % ("shows this message"),
|
||||
|
||||
(clipp::option("--github-token")
|
||||
& clipp::value("TOKEN") >> github_token_)
|
||||
% "github api key",
|
||||
(clipp::option("--github-token") &
|
||||
clipp::value("TOKEN") >> github_token_) %
|
||||
"github api key",
|
||||
|
||||
(clipp::value("OP") >> op_)
|
||||
% "one of `find`, `pull` or `revert`; see below",
|
||||
(clipp::value("OP") >> op_) %
|
||||
"one of `find`, `pull` or `revert`; see below",
|
||||
|
||||
(clipp::value("PR") >> pr_)
|
||||
% "PR to apply, must be `task/pr`, such as `modorganizer/123`";
|
||||
}
|
||||
(clipp::value("PR") >> pr_) %
|
||||
"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())
|
||||
github_token_ = conf().global().get("github_key");
|
||||
|
||||
@@ -80,17 +68,16 @@ int pr_command::do_run()
|
||||
u8cerr << "bad operation '" << op_ << "'\n";
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<const tasks::modorganizer*, std::string> pr_command::parse_pr(
|
||||
const std::string& pr) const
|
||||
{
|
||||
std::pair<const tasks::modorganizer*, std::string>
|
||||
pr_command::parse_pr(const std::string& pr) const
|
||||
{
|
||||
if (pr.empty())
|
||||
return {};
|
||||
|
||||
const auto cs = split(pr, "/");
|
||||
if (cs.size() != 2)
|
||||
{
|
||||
if (cs.size() != 2) {
|
||||
u8cerr << "--pr must be task/pr, such as modorganizer/123\n";
|
||||
return {};
|
||||
}
|
||||
@@ -103,17 +90,16 @@ std::pair<const tasks::modorganizer*, std::string> pr_command::parse_pr(
|
||||
return {};
|
||||
|
||||
const auto* mo_task = dynamic_cast<const tasks::modorganizer*>(task);
|
||||
if (!mo_task)
|
||||
{
|
||||
if (!mo_task) {
|
||||
u8cerr << "only modorganizer tasks are supported\n";
|
||||
return {};
|
||||
}
|
||||
|
||||
return {mo_task, pr_number};
|
||||
}
|
||||
}
|
||||
|
||||
int pr_command::pull()
|
||||
{
|
||||
int pr_command::pull()
|
||||
{
|
||||
const auto prs = get_matching_prs(pr_);
|
||||
if (prs.empty())
|
||||
return 1;
|
||||
@@ -122,25 +108,21 @@ int pr_command::pull()
|
||||
if (okay_prs.empty())
|
||||
return 1;
|
||||
|
||||
try
|
||||
{
|
||||
for (auto&& pr : okay_prs)
|
||||
{
|
||||
try {
|
||||
for (auto&& pr : okay_prs) {
|
||||
const auto* task = dynamic_cast<const tasks::modorganizer*>(
|
||||
task_manager::instance().find_one(pr.repo));
|
||||
|
||||
if (!task)
|
||||
return 1;
|
||||
|
||||
u8cout
|
||||
<< "checking out pr " << pr.number << " "
|
||||
u8cout << "checking out pr " << pr.number << " "
|
||||
<< "in " << task->name() << "\n";
|
||||
|
||||
git_wrap g(task->source_path());
|
||||
|
||||
g.fetch(
|
||||
task->git_url().string(),
|
||||
fmt::format("pull/{}/head", pr.number));
|
||||
g.fetch(task->git_url().string(),
|
||||
std::format("pull/{}/head", pr.number));
|
||||
|
||||
g.checkout("FETCH_HEAD");
|
||||
}
|
||||
@@ -149,20 +131,19 @@ int pr_command::pull()
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
catch (std::exception& e) {
|
||||
u8cerr << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int pr_command::find()
|
||||
{
|
||||
int pr_command::find()
|
||||
{
|
||||
return !get_matching_prs(pr_).empty();
|
||||
}
|
||||
}
|
||||
|
||||
int pr_command::revert()
|
||||
{
|
||||
int pr_command::revert()
|
||||
{
|
||||
const auto prs = get_matching_prs(pr_);
|
||||
if (prs.empty())
|
||||
return 1;
|
||||
@@ -171,10 +152,8 @@ int pr_command::revert()
|
||||
if (okay_prs.empty())
|
||||
return 1;
|
||||
|
||||
try
|
||||
{
|
||||
for (auto&& pr : okay_prs)
|
||||
{
|
||||
try {
|
||||
for (auto&& pr : okay_prs) {
|
||||
const auto* task = dynamic_cast<const tasks::modorganizer*>(
|
||||
task_manager::instance().find_one(pr.repo));
|
||||
|
||||
@@ -188,16 +167,15 @@ int pr_command::revert()
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
catch (std::exception& e) {
|
||||
u8cerr << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<pr_command::pr_info> pr_command::get_matching_prs(
|
||||
const std::string& repo_pr)
|
||||
{
|
||||
std::vector<pr_command::pr_info>
|
||||
pr_command::get_matching_prs(const std::string& repo_pr)
|
||||
{
|
||||
auto&& [task, src_pr] = parse_pr(repo_pr);
|
||||
if (!task)
|
||||
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
|
||||
<< table(map(prs, [&](auto&& pr)
|
||||
{
|
||||
u8cout << table(map(prs,
|
||||
[&](auto&& pr) {
|
||||
return std::pair(pr.repo + "/" + pr.number, pr.title);
|
||||
}), 2, 5)
|
||||
}),
|
||||
2, 5)
|
||||
<< "\n";
|
||||
|
||||
return prs;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<pr_command::pr_info> pr_command::search_prs(
|
||||
const std::string& org, const std::string& author, const std::string& branch)
|
||||
{
|
||||
std::vector<pr_command::pr_info> pr_command::search_prs(const std::string& org,
|
||||
const std::string& author,
|
||||
const std::string& branch)
|
||||
{
|
||||
nlohmann::json json;
|
||||
|
||||
constexpr auto* pattern =
|
||||
"https://api.github.com/search/issues?per_page=100&q="
|
||||
"is:pr+org:{org:}+author:{author:}+is:open+head:{branch:}";
|
||||
constexpr auto* pattern = "https://api.github.com/search/issues?per_page=100&q="
|
||||
"is:pr+org:{0:}+author:{1:}+is:open+head:{2:}";
|
||||
|
||||
const auto search_url = fmt::format(
|
||||
pattern,
|
||||
fmt::arg("org", org),
|
||||
fmt::arg("author", author),
|
||||
fmt::arg("branch", branch));
|
||||
const auto search_url = std::format(pattern, org, author, branch);
|
||||
|
||||
u8cout << "search url is " << search_url << "\n";
|
||||
|
||||
@@ -245,14 +219,12 @@ std::vector<pr_command::pr_info> pr_command::search_prs(
|
||||
|
||||
curl_downloader dl;
|
||||
|
||||
dl
|
||||
.url(search_url)
|
||||
dl.url(search_url)
|
||||
.header("Authorization", "token " + github_token_)
|
||||
.start()
|
||||
.join();
|
||||
|
||||
if (!dl.ok())
|
||||
{
|
||||
if (!dl.ok()) {
|
||||
u8cerr << "failed to search github\n";
|
||||
return {};
|
||||
}
|
||||
@@ -260,66 +232,54 @@ std::vector<pr_command::pr_info> pr_command::search_prs(
|
||||
const auto output = dl.steal_output();
|
||||
json = nlohmann::json::parse(output);
|
||||
|
||||
|
||||
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
|
||||
const std::string url = item["repository_url"];
|
||||
|
||||
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";
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto repo = url.substr(last_slash + 1);
|
||||
|
||||
pr_info info = {
|
||||
repo, author, branch, item["title"],
|
||||
std::to_string(item["number"].get<int>())
|
||||
};
|
||||
pr_info info = {repo, author, branch, item["title"],
|
||||
std::to_string(item["number"].get<int>())};
|
||||
|
||||
if (!repos.emplace(repo, info).second)
|
||||
{
|
||||
u8cerr
|
||||
<< "multiple prs found in repo " << repo << ", "
|
||||
if (!repos.emplace(repo, info).second) {
|
||||
u8cerr << "multiple prs found in repo " << repo << ", "
|
||||
<< "not supported\n";
|
||||
|
||||
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(
|
||||
const tasks::modorganizer* task, const std::string& pr)
|
||||
{
|
||||
pr_command::pr_info pr_command::get_pr_info(const tasks::modorganizer* task,
|
||||
const std::string& pr)
|
||||
{
|
||||
nlohmann::json json;
|
||||
|
||||
if (github_token_.empty())
|
||||
{
|
||||
if (github_token_.empty()) {
|
||||
u8cerr << "missing --github-token\n";
|
||||
return {};
|
||||
}
|
||||
|
||||
const url u(fmt::format(
|
||||
"https://api.github.com/repos/{}/{}/pulls/{}",
|
||||
const url u(std::format("https://api.github.com/repos/{}/{}/pulls/{}",
|
||||
task->org(), task->repo(), pr));
|
||||
|
||||
curl_downloader dl;
|
||||
|
||||
dl
|
||||
.url(u)
|
||||
.header("Authorization", "token " + github_token_)
|
||||
.start()
|
||||
.join();
|
||||
dl.url(u).header("Authorization", "token " + github_token_).start().join();
|
||||
|
||||
if (!dl.ok())
|
||||
{
|
||||
if (!dl.ok()) {
|
||||
u8cerr << "failed to get pr info from github\n";
|
||||
return {};
|
||||
}
|
||||
@@ -332,44 +292,37 @@ pr_command::pr_info pr_command::get_pr_info(
|
||||
const std::string branch = json["head"]["ref"];
|
||||
|
||||
return {repo, author, branch};
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<pr_command::pr_info> pr_command::validate_prs(
|
||||
const std::vector<pr_info>& prs)
|
||||
{
|
||||
std::vector<pr_command::pr_info>
|
||||
pr_command::validate_prs(const std::vector<pr_info>& prs)
|
||||
{
|
||||
std::vector<std::string> problems;
|
||||
std::vector<pr_info> okay_prs;
|
||||
|
||||
for (auto&& pr : prs)
|
||||
{
|
||||
if (pr.repo == "mob")
|
||||
{
|
||||
for (auto&& pr : prs) {
|
||||
if (pr.repo == "mob") {
|
||||
problems.push_back("there's a pr for mob itself");
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
const auto tasks = task_manager::instance().find(pr.repo);
|
||||
|
||||
if (tasks.empty())
|
||||
{
|
||||
if (tasks.empty()) {
|
||||
problems.push_back("task " + pr.repo + " does not exist");
|
||||
continue;
|
||||
}
|
||||
else if (tasks.size() > 1)
|
||||
{
|
||||
else if (tasks.size() > 1) {
|
||||
problems.push_back("found more than one task for repo " + pr.repo);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
const auto* mo_task =
|
||||
dynamic_cast<const tasks::modorganizer*>(tasks[0]);
|
||||
|
||||
if (!mo_task)
|
||||
{
|
||||
problems.push_back(
|
||||
"task " + pr.repo + " is not a modorganizer repo");
|
||||
if (!mo_task) {
|
||||
problems.push_back("task " + pr.repo +
|
||||
" is not a modorganizer repo");
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -379,8 +332,7 @@ std::vector<pr_command::pr_info> pr_command::validate_prs(
|
||||
okay_prs.push_back(pr);
|
||||
}
|
||||
|
||||
if (!problems.empty())
|
||||
{
|
||||
if (!problems.empty()) {
|
||||
{
|
||||
console_color cc(console_color::yellow);
|
||||
|
||||
@@ -391,19 +343,19 @@ std::vector<pr_command::pr_info> pr_command::validate_prs(
|
||||
|
||||
u8cout << "\n";
|
||||
|
||||
if (okay_prs.empty())
|
||||
{
|
||||
if (okay_prs.empty()) {
|
||||
u8cout << "all prs would be ignored, bailing out\n";
|
||||
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 {};
|
||||
|
||||
u8cout << "\n";
|
||||
}
|
||||
|
||||
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