Merge branch 'master' into briefcase-squashed
# Conflicts: # .gitignore
This commit is contained in:
commit
e917431053
9
.gitignore
vendored
9
.gitignore
vendored
@ -20,8 +20,8 @@ pip-wheel-metadata
|
||||
# Coverage
|
||||
.coverage
|
||||
|
||||
# Tox
|
||||
.tox
|
||||
# Editors
|
||||
.idea
|
||||
|
||||
# Flatpak
|
||||
flatpak/build
|
||||
@ -34,4 +34,7 @@ macOS/
|
||||
windows/
|
||||
android/
|
||||
linux/
|
||||
django/
|
||||
django/
|
||||
|
||||
# Windows Install
|
||||
win-installer/_build_root
|
7
.readthedocs.yml
Normal file
7
.readthedocs.yml
Normal file
@ -0,0 +1,7 @@
|
||||
version: 2
|
||||
formats: all
|
||||
sphinx:
|
||||
configuration: docs/conf.py
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
154
CONTRIBUTING.md
154
CONTRIBUTING.md
@ -1,49 +1,131 @@
|
||||
Feel free to hack Gaphor. Patches are welcome.
|
||||
# Contributing
|
||||
|
||||
Fetching Development Dependencies
|
||||
=================================
|
||||
### We :heart: our Contributors!
|
||||
|
||||
Gaphor uses pip to manage in easy way its dependencies.
|
||||
First off, thank you for considering contributing to Gaphor. It's people like
|
||||
you that make Gaphor such a great modeling tool.
|
||||
|
||||
To fetch and install dependencies as non-root user:
|
||||
In Linux recommend using a virtual environment for installation. Since pyGTK doesn't work well with a virtualenv,
|
||||
install it outside the virtual environment and then start your the virtualenv using the --system-site-packages option:
|
||||
$ virtualenv --system-site-packages venv
|
||||
$ source venv/bin/activate
|
||||
$ pip install gaphor
|
||||
### Why a Guideline?
|
||||
|
||||
Running Tests
|
||||
=============
|
||||
To run tests on Unix machine
|
||||
Following these guidelines helps to communicate that you respect the time of
|
||||
the developers managing and developing this open source project. In return,
|
||||
they should reciprocate that respect in addressing your issue, assessing
|
||||
changes, and helping you finalize your pull requests.
|
||||
|
||||
Xvfb :2.0 &
|
||||
DISPLAY=:2.0 nosetests gaphor/ 2>&1 | tee tests.log
|
||||
### What we are Looking For
|
||||
|
||||
Gaphor is an open source project and we love to receive contributions from our
|
||||
community — you! There are many ways to contribute, from writing tutorials or
|
||||
blog posts, improving the documentation, submitting bug reports and feature
|
||||
requests or writing code which can be incorporated into Gaphor itself.
|
||||
|
||||
### What we are not Looking For
|
||||
|
||||
Please, don't use the issue tracker for support questions. Check whether the
|
||||
your question can be answered on the
|
||||
[Gaphor Gitter Channel](https://gitter.im/gaphor/Lobby).
|
||||
|
||||
# Ground Rules
|
||||
### Responsibilities
|
||||
|
||||
* Ensure cross-platform compatibility for every change that's accepted.
|
||||
Windows, Mac, Debian & Ubuntu Linux.
|
||||
* Ensure that code that goes into core meets all requirements in this
|
||||
[PR Review Checklist](https://gist.github.com/audreyr/4feef90445b9680475f2).
|
||||
* Create issues for any major changes and enhancements that you wish to make.
|
||||
* Discuss things transparently and get community feedback.
|
||||
* Don't add any classes to the codebase unless absolutely needed. Err on the side of using
|
||||
functions.
|
||||
* Keep feature versions as small as possible, preferably one new feature per
|
||||
version.
|
||||
* Be welcoming to newcomers and encourage diverse new contributors from all
|
||||
backgrounds. See the
|
||||
[Python Community Code of Conduct](https://www.python.org/psf/codeofconduct/).
|
||||
|
||||
# Your First Contribution
|
||||
|
||||
Unsure where to begin contributing to Gaphor? You can start by looking through
|
||||
these `first-timers-only` and `up-for-grabs` issues:
|
||||
|
||||
* [First-timers-only issues](https://github.com/gaphor/gaphor/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3Afirst-timers-only) -
|
||||
issues which should only require a few lines of code, and a test or two.
|
||||
* [Up-for-grabs issues](https://github.com/gaphor/gaphor/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3Aup-for-grabs) -
|
||||
issues which should be a bit more involved than `first-timers-only` issues.
|
||||
|
||||
### Is This Your First Open Source Contribution?
|
||||
|
||||
Working on your first Pull Request? You can learn how from this *free* series,
|
||||
[How to Contribute to an Open Source Project on
|
||||
GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github).
|
||||
|
||||
At this point, you're ready to make your changes! Feel free to ask for help;
|
||||
everyone is a beginner at first :smile_cat:
|
||||
|
||||
If a maintainer asks you to "rebase" your PR, they're saying that a lot of code
|
||||
has changed, and that you need to update your branch so it's easier to merge.
|
||||
|
||||
# Getting Started
|
||||
|
||||
For something that is bigger than a one or two line fix:
|
||||
|
||||
1. Create your own fork of the code
|
||||
2. Install all development dependencies using:
|
||||
`$ poetry install`
|
||||
`$ pre-commit install`
|
||||
If you haven't used poetry before, just run `pip install poetry`, and then run the commands above, it will do the correct thing.
|
||||
3. Add tests for your changes, run the tests with `pytest`.
|
||||
4. Do the changes in your fork.
|
||||
5. If you like the change and think the project could use it:
|
||||
* Be sure you have the pre-commit hook installed above, it will ensure that
|
||||
[Black](https://github.com/ambv/black) is automatically run on any changes for
|
||||
consistent code formatting.
|
||||
* [Sign](https://help.github.com/articles/signing-commits/) your commits.
|
||||
* Note the Gaphor Code of Conduct.
|
||||
* Create a pull request.
|
||||
|
||||
|
||||
Structure
|
||||
=========
|
||||
Small contributions such as fixing spelling errors, where the content is small
|
||||
enough to not be considered intellectual property, can be submitted by a
|
||||
contributor as a patch, without signing your commit.
|
||||
|
||||
Gaphor contains the following modules:
|
||||
As a rule of thumb, changes are obvious fixes if they do not introduce any new
|
||||
functionality or creative thinking. As long as the change does not affect
|
||||
functionality, some likely examples include the following:
|
||||
* Spelling / grammar fixes
|
||||
* Typo correction, white space and formatting changes
|
||||
* Comment clean up
|
||||
* Bug fixes that change default return values or error codes stored in constants
|
||||
* Adding logging messages or debugging output
|
||||
* Changes to ‘metadata’ files like pyproject.toml, .gitignore, build scripts, etc.
|
||||
* Moving source files from one directory or package to another
|
||||
|
||||
UML
|
||||
---
|
||||
The UML module contains the UML 2.0 data model. This part is
|
||||
quite stable and it is unlikely that code has to be changed
|
||||
here.
|
||||
# How to Report a Bug
|
||||
If you find a security vulnerability, do NOT open an issue. Email dan@yeaw.me instead.
|
||||
|
||||
NOTE: The code is generated from a Gaphor model: uml2.gaphor. This
|
||||
file can be loaded in gaphor.
|
||||
When filing an issue, make sure to answer the questions in the issue template.
|
||||
|
||||
diagram
|
||||
-------
|
||||
The diagram module contains items that can be placed in diagrams.
|
||||
In most cases the classes NamedItem and Relationship can serve
|
||||
as bases for your class.
|
||||
1. What version are you using?
|
||||
2. What operating system are you using?
|
||||
3. What did you do?
|
||||
4. What did you expect to see?
|
||||
5. What did you see instead?
|
||||
|
||||
ui
|
||||
--
|
||||
The user interface. This is where most of the work is to be done.
|
||||
# How to Suggest a Feature or Enhancement
|
||||
If you find yourself wishing for a feature that doesn't exist in Gaphor,
|
||||
you are probably not alone. There are bound to be others out there with similar
|
||||
needs. Many of the features that Gaphor has today have been added
|
||||
because our users saw the need. Open an issue on our issues list on GitHub
|
||||
which describes the feature you would like to see, why you need it, and how it
|
||||
should work.
|
||||
|
||||
# Code review process
|
||||
|
||||
The core team looks at Pull Requests on a regular basis, you should expect a
|
||||
response within a week. After feedback has been given we expect responses
|
||||
within two weeks. After two weeks we may close the pull request if it isn't
|
||||
showing any activity.
|
||||
|
||||
|
||||
# Community
|
||||
You can chat with the Gaphor community on gitter: https://gitter.im/Gaphor/Lobby.
|
||||
|
||||
misc
|
||||
----
|
||||
Some utility stuff, such as Actions and aspects are put in here.
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
[![Build state](https://travis-ci.com/gaphor/gaphor.svg?branch=master)](https://travis-ci.com/gaphor/gaphor)
|
||||
![Docs build state](https://readthedocs.org/projects/gaphor/badge/?version=latest)
|
||||
[![Coverage](https://coveralls.io/repos/github/gaphor/gaphor/badge.svg?branch=master)](https://coveralls.io/github/gaphor/gaphor?branch=master)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/gaphor/gaphor/badge.svg?branch=master)](https://coveralls.io/github/gaphor/gaphor?branch=master)
|
||||
[![PyPI](https://img.shields.io/pypi/v/gaphor.svg)](https://pypi.org/project/gaphor)
|
||||
[![Downloads](https://pepy.tech/badge/gaphor)](https://pepy.tech/project/gaphor)
|
||||
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
|
||||
|
@ -1,5 +1,6 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
Python ?= python3
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
|
273
docs/conf.py
273
docs/conf.py
@ -1,222 +1,187 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
# This file does only contain a selection of the most common options. For a
|
||||
# full list see the documentation:
|
||||
# http://www.sphinx-doc.org/en/master/config
|
||||
|
||||
import sys, os
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
# import os
|
||||
# import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
from pathlib import Path
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
from tomlkit import parse
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = "Gaphor"
|
||||
copyright = "2019, Arjan J. Molenaar"
|
||||
author = "Arjan J. Molenaar"
|
||||
|
||||
# The short X.Y version
|
||||
version = ""
|
||||
project_dir = Path(__file__).resolve().parent.parent
|
||||
f = project_dir.joinpath("pyproject.toml")
|
||||
release = parse(f.read_text())["tool"]["poetry"]["version"]
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
"sphinx.ext.autodoc",
|
||||
"sphinx.ext.doctest",
|
||||
"sphinx.ext.todo",
|
||||
"sphinx.ext.intersphinx",
|
||||
"sphinx.ext.coverage",
|
||||
"sphinx.ext.viewcode",
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ["_templates"]
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = ".txt"
|
||||
|
||||
# The encoding of source files.
|
||||
# source_encoding = 'utf-8-sig'
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
#
|
||||
# source_suffix = ['.rst', '.md']
|
||||
source_suffix = ".rst"
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = "contents"
|
||||
|
||||
# General information about the project.
|
||||
project = u"Gaphor"
|
||||
copyright = u"2012, Gaphor development team"
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = "0.17.1"
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = "0.17.1"
|
||||
master_doc = "index"
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
# language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
# today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
# today_fmt = '%B %d, %Y'
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ["_build"]
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
# default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
# add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
# add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
# show_authors = False
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = "sphinx"
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
# modindex_common_prefix = []
|
||||
pygments_style = None
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = "default"
|
||||
#
|
||||
html_theme = "sphinx_rtd_theme"
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#
|
||||
# html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
# html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
# html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
# html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
# html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
# html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ["_static"]
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at the bottom of every page,
|
||||
# using the given strftime format.
|
||||
# html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
# html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
# Custom sidebar templates, must be a dictionary that maps document names
|
||||
# to template names.
|
||||
#
|
||||
# The default sidebars (for documents that don't match any pattern) are
|
||||
# defined by theme itself. Builtin themes are using these templates by
|
||||
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
|
||||
# 'searchbox.html']``.
|
||||
#
|
||||
# html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
# html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
# html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
# html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
# html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
# html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
# html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
# html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
# html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
# html_file_suffix = None
|
||||
# -- Options for HTMLHelp output ---------------------------------------------
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = "Gaphordoc"
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
# -- Options for LaTeX output ------------------------------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
# latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
# latex_font_size = '10pt'
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(
|
||||
"contents",
|
||||
"Gaphor.tex",
|
||||
u"Gaphor Documentation",
|
||||
u"Gaphor development team",
|
||||
"manual",
|
||||
)
|
||||
(master_doc, "Gaphor.tex", "Gaphor Documentation", "Arjan J. Molenaar", "manual")
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
# latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
# latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
# latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
# latex_show_urls = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
# latex_preamble = ''
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
# latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
# latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------------
|
||||
# -- Options for manual page output ------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
("contents", "gaphor", u"Gaphor Documentation", [u"Gaphor development team"], 1)
|
||||
man_pages = [(master_doc, "gaphor", "Gaphor Documentation", [author], 1)]
|
||||
|
||||
|
||||
# -- Options for Texinfo output ----------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(
|
||||
master_doc,
|
||||
"Gaphor",
|
||||
"Gaphor Documentation",
|
||||
author,
|
||||
"Gaphor",
|
||||
"One line description of project.",
|
||||
"Miscellaneous",
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
# -- Options for Epub output -------------------------------------------------
|
||||
|
||||
# Bibliographic Dublin Core info.
|
||||
epub_title = project
|
||||
|
||||
# The unique identifier of the text. This can be a ISBN number
|
||||
# or the project homepage.
|
||||
#
|
||||
# epub_identifier = ''
|
||||
|
||||
# A unique identification for the text.
|
||||
#
|
||||
# epub_uid = ''
|
||||
|
||||
# A list of files that should not be packed into the epub file.
|
||||
epub_exclude_files = ["search.html"]
|
||||
|
||||
|
||||
# -- Extension configuration -------------------------------------------------
|
||||
|
||||
# -- Options for intersphinx extension ---------------------------------------
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {"https://docs.python.org/": None}
|
||||
|
@ -1,17 +1,14 @@
|
||||
######################
|
||||
Documentation contents
|
||||
######################
|
||||
Welcome to Gaphor's documentation!
|
||||
==================================
|
||||
|
||||
*The source is the documentation.*
|
||||
|
||||
Well, not for us.
|
||||
|
||||
Currently, there's not a lot of documentation though. For those of you interested in Gaphor there's:
|
||||
Some highlights of the documentation:
|
||||
|
||||
* A :doc:`manual <manual/index>`. It outlines some of the ideas in and behind Gaphor.
|
||||
* The :ref:`tech-section` contains some interesting articles about the technology that drives Gaphor and Gaphas, Gaphor's canvas widget.
|
||||
|
||||
If you're into writing plug-ins for Gaphor you should have a look at our fabulous `Hello world <http://github.com/amolenaar/gaphor.plugins.helloworld>`_ plug-in.
|
||||
If you're into writing plug-ins for Gaphor you should have a look at our
|
||||
fabulous `Hello world <http://github.com/amolenaar/gaphor.plugins.helloworld>`_
|
||||
plug-in.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
@ -23,8 +20,9 @@ Running Gaphor on different platforms:
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
windows
|
||||
linux
|
||||
win32
|
||||
macos
|
||||
custominstall
|
||||
|
||||
|
||||
@ -62,5 +60,3 @@ External links
|
||||
* The `official UML metamodel specification <http://www.omg.org/technology/documents/modeling_spec_catalog.htm#UML>`_. This ''is'' our data model.
|
||||
|
||||
|
||||
..
|
||||
# vim:syntax=rst
|
3
docs/macos.rst
Normal file
3
docs/macos.rst
Normal file
@ -0,0 +1,3 @@
|
||||
Gaphor on macOS
|
||||
===============
|
||||
|
@ -12,11 +12,11 @@ highly complex models.
|
||||
Gaphor is designed around the following principles:
|
||||
|
||||
- Simplicity
|
||||
The application should be easy to use. Only some basic knowledge of UML is required.
|
||||
The application should be easy to use. Only some basic knowledge of UML is required.
|
||||
- Consistency
|
||||
UML is a graphical modeling language, so all modeling is done in a diagram [#f1]_ .
|
||||
UML is a graphical modeling language, so all modeling is done in a diagram [#f1]_ .
|
||||
- Workability
|
||||
The application should not bother the user every time they do something non-UML-ish.
|
||||
The application should not bother the user every time they do something non-UML-ish.
|
||||
|
||||
This manual serves as a reference for all Gaphor has to offer. So, you may read it from start to finish, or jump to a section that interests you.
|
||||
|
5
docs/requirements.txt
Normal file
5
docs/requirements.txt
Normal file
@ -0,0 +1,5 @@
|
||||
docutils==0.14
|
||||
Pygments==2.3.1
|
||||
sphinx-rtd-theme==0.4.3
|
||||
sphinxcontrib-websupport==1.1.0
|
||||
tomlkit==0.5.3
|
@ -53,5 +53,5 @@ information along with its service definition.
|
||||
|
||||
.. seealso::
|
||||
|
||||
Writing plugins :ref:`<manual/plugins>`
|
||||
:doc:`Writing plugins <manual/plugins>`
|
||||
|
@ -30,14 +30,14 @@ All elements inside a canvas have a tag ``Item``.
|
||||
<ref refid="1"/>
|
||||
</namespace>
|
||||
<canvas extents="(9.0, 9.0, 189.0, 247.0)" grid_bg="0xFFFFFFFF"
|
||||
grid_color="0x80ff" grid_int_x="10.0" grid_int_y="10.0"
|
||||
grid_ofs_x="0.0" grid_ofs_y="0.0" snap_to_grid="0"
|
||||
static_extents="0" affine="(1.0, 0.0, 0.0, 1.0, 0.0, 0.0)"
|
||||
id="DCE:xxxx">
|
||||
grid_color="0x80ff" grid_int_x="10.0" grid_int_y="10.0"
|
||||
grid_ofs_x="0.0" grid_ofs_y="0.0" snap_to_grid="0"
|
||||
static_extents="0" affine="(1.0, 0.0, 0.0, 1.0, 0.0, 0.0)"
|
||||
id="DCE:xxxx">
|
||||
<item affine="(1.0, 0.0, 0.0, 1.0, 150.0, 50.0)" cid="0x8293e74"
|
||||
height="78.0" subject="3" type="ActorItem" width="38.0"/>
|
||||
height="78.0" subject="3" type="ActorItem" width="38.0"/>
|
||||
<item affine="(1.0, 0.0, 0.0, 1.0, 10.0, 10.0)" cid="0x82e7d74"
|
||||
height="26.0" subject="5" type="CommentItem" width="100.0"/>
|
||||
height="26.0" subject="5" type="CommentItem" width="100.0"/>
|
||||
</canvas>
|
||||
</Diagram>
|
||||
<Actor id="3">
|
||||
@ -46,7 +46,7 @@ All elements inside a canvas have a tag ``Item``.
|
||||
</name>
|
||||
<namespace>
|
||||
<ref refid="1"/>
|
||||
</namespace
|
||||
</namespace>
|
||||
</Actor>
|
||||
<UseCase id="4">
|
||||
<namespace>
|
3
docs/windows.rst
Normal file
3
docs/windows.rst
Normal file
@ -0,0 +1,3 @@
|
||||
Gaphor on Windows
|
||||
=================
|
||||
|
@ -105,7 +105,7 @@ class Element(object):
|
||||
|
||||
def isKindOf(self, class_):
|
||||
"""
|
||||
Returns true if the object is an instance of class_.
|
||||
Returns true if the object is an instance of `class_`.
|
||||
"""
|
||||
return isinstance(self, class_)
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
# vim: sw=4
|
||||
"""
|
||||
Factory for and registration of model elements.
|
||||
"""
|
||||
"""Factory for and registration of model elements."""
|
||||
|
||||
import uuid
|
||||
from zope import component
|
||||
@ -27,13 +24,12 @@ class ElementFactory(object):
|
||||
The ElementFactory is used to create elements and do lookups to
|
||||
elements.
|
||||
|
||||
Notifications are send with as arguments (name, element, *user_data).
|
||||
Notifications are sent as arguments (name, element, `*user_data`).
|
||||
The following names are used:
|
||||
create - a new model element is created (element is newly created element)
|
||||
remove - a model element is removed (element is to be removed element)
|
||||
model - a new model has been loaded (element is None)
|
||||
flush - model is flushed: all element are removed from the factory
|
||||
(element is None)
|
||||
model - a new model has been loaded (element is None) flush - model is
|
||||
flushed: all element are removed from the factory (element is None)
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
|
@ -1,4 +1,5 @@
|
||||
[pytest]
|
||||
testpaths = gaphor tests docs
|
||||
doctest-extension=.txt
|
||||
doctest-extension=.rst
|
||||
python_files = test_*.py
|
||||
addopts = --doctest-modules
|
||||
|
1
setup.py
1
setup.py
@ -94,6 +94,7 @@ setup(
|
||||
"PyGObject >= 3.30.0",
|
||||
"gaphas >= 0.7.2",
|
||||
"zope.component >= 3.4.0",
|
||||
"zope.interface >= 4.6.0",
|
||||
],
|
||||
zip_safe=False,
|
||||
entry_points={
|
||||
|
45
win-installer/README.md
Normal file
45
win-installer/README.md
Normal file
@ -0,0 +1,45 @@
|
||||
# Windows Installer Build Scripts
|
||||
We use msys2 for creating the Windows installer and development on Windows
|
||||
because that is what PyGObject currently supports.
|
||||
|
||||
## Development
|
||||
For developing on Windows you have two choices.
|
||||
|
||||
#### 1. Use an Existing Gaphor Installation Plus a Git Checkout:
|
||||
- Clone the git repo with some git client
|
||||
- Download and install the latest [installer
|
||||
build](https://github.com/gaphor/gaphor/releases/download/latest/gaphor-latest-installer.exe)
|
||||
- Go to setup.py in the git checkout and run C:\Program
|
||||
Files\Gaphor\bin\python.exe setup.py run.
|
||||
|
||||
#### 2. Use a Full MSYS2 Environment
|
||||
- Download msys2 64-bit from https://msys2.org
|
||||
- Follow instructions on https://msys2.org
|
||||
- Execute C:\msys64\mingw64.exe
|
||||
- Run `pacman -Syu` to update packages
|
||||
- Run `pacman -S git` to install git
|
||||
- Run git clone https://github.com/gaphor/gaphor.git
|
||||
- Run cd gaphor/win_installer to end up where this README exists.
|
||||
- Execute `./bootstrap.sh` to install all the needed dependencies.
|
||||
- Now go to the source code `cd ../`
|
||||
- To run Gaphor execute `python3 setup.py run`
|
||||
|
||||
## Creating an Installer
|
||||
Simply run `./build.sh` and both the installer and the portable
|
||||
installer should appear in this directory.
|
||||
|
||||
You can also run the build using a specific git version:
|
||||
1. Pass a git tag with: `./build.sh release-1.0.0`
|
||||
1. Pass a git commit hash with: `./build.sh a5d3e53406fadd1fe089aa995b650949256d4981`
|
||||
1. Pass nothing to build master
|
||||
|
||||
Note: `build.sh` clones from the local repository and not from GitHub so any
|
||||
commits present locally will be cloned as well.
|
||||
|
||||
## Updating an Existing Installer
|
||||
We directly follow msys2 upstream so building the installer two weeks later
|
||||
might result in newer versions of dependencies being used. To reduce the risk of
|
||||
stable release breakage you can use an existing installer and just install a
|
||||
newer Gaphor version into it and then repack it:
|
||||
|
||||
`./rebuild.sh gaphor-1.0.0-installer.exe [git tag / commit]`
|
318
win-installer/_base.sh
Normal file
318
win-installer/_base.sh
Normal file
@ -0,0 +1,318 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2016 Christoph Reiter, 2019 Dan Yeaw
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
set -e
|
||||
DIR="$( cd "$( dirname "$0" )" && pwd )"
|
||||
cd "${DIR}"
|
||||
|
||||
# CONFIG START
|
||||
|
||||
ARCH="x86_64"
|
||||
BUILD_VERSION="0"
|
||||
|
||||
# CONFIG END
|
||||
|
||||
MISC="${DIR}"/misc
|
||||
if [ "${ARCH}" = "x86_64" ]; then
|
||||
MINGW="mingw64"
|
||||
else
|
||||
MINGW="mingw32"
|
||||
fi
|
||||
|
||||
VERSION="0.0.0"
|
||||
VERSION_DESC="UNKNOWN"
|
||||
|
||||
function set_build_root {
|
||||
BUILD_ROOT="$1"
|
||||
REPO_CLONE="${BUILD_ROOT}"/gaphor
|
||||
MINGW_ROOT="${BUILD_ROOT}/${MINGW}"
|
||||
}
|
||||
|
||||
set_build_root "${DIR}/_build_root"
|
||||
|
||||
function build_pacman {
|
||||
pacman --cachedir "/var/cache/pacman/pkg" --root "${BUILD_ROOT}" "$@"
|
||||
}
|
||||
|
||||
function build_pip {
|
||||
"${BUILD_ROOT}"/"${MINGW}"/bin/pip3.exe "$@"
|
||||
}
|
||||
|
||||
function build_python {
|
||||
"${BUILD_ROOT}"/"${MINGW}"/bin/python3.exe "$@"
|
||||
}
|
||||
|
||||
function build_compileall_pyconly {
|
||||
MSYSTEM= build_python -m compileall --invalidation-mode unchecked-hash -b "$@"
|
||||
}
|
||||
|
||||
function build_compileall {
|
||||
MSYSTEM= build_python -m compileall --invalidation-mode unchecked-hash "$@"
|
||||
}
|
||||
|
||||
function install_pre_deps {
|
||||
pacman -S --needed --noconfirm p7zip git dos2unix \
|
||||
mingw-w64-"${ARCH}"-nsis mingw-w64-"${ARCH}"-wget mingw-w64-"${ARCH}"-toolchain
|
||||
}
|
||||
|
||||
function create_root {
|
||||
mkdir -p "${BUILD_ROOT}"
|
||||
|
||||
mkdir -p "${BUILD_ROOT}"/var/lib/pacman
|
||||
mkdir -p "${BUILD_ROOT}"/var/log
|
||||
mkdir -p "${BUILD_ROOT}"/tmp
|
||||
|
||||
build_pacman --noconfirm -Syu
|
||||
build_pacman --noconfirm -S base
|
||||
}
|
||||
|
||||
function extract_installer {
|
||||
[ -z "$1" ] && (echo "Missing arg"; exit 1)
|
||||
|
||||
mkdir -p "$BUILD_ROOT"
|
||||
7z x -o"$BUILD_ROOT"/"$MINGW" "$1"
|
||||
rm -rf "$MINGW_ROOT"/'$PLUGINSDIR' "$MINGW_ROOT"/*.txt "$MINGW_ROOT"/*.nsi
|
||||
}
|
||||
|
||||
function install_deps {
|
||||
build_pacman --noconfirm -S \
|
||||
mingw-w64-"${ARCH}"-gtk3 \
|
||||
mingw-w64-"${ARCH}"-python3 \
|
||||
mingw-w64-"${ARCH}"-python3-gobject \
|
||||
mingw-w64-"${ARCH}"-python3-cairo \
|
||||
mingw-w64-"${ARCH}"-python3-pip \
|
||||
mingw-w64-"${ARCH}"-python3-setuptools \
|
||||
mingw-w64-"${ARCH}"-python3-zope.interface
|
||||
|
||||
# First time installing pip has post-install errors, reinstall to fix
|
||||
# sed: can't read mingw64/bin/pip3-script.py: No such file or directory
|
||||
# sed: can't read mingw64/bin/pip3.7-script.py: No such file or directory
|
||||
# error: command (/usr/bin/bash /usr/bin/bash -c . /tmp/alpm_omSbWr/.INSTALL; post_install 19.0.1-1 ) failed to execute correctly
|
||||
build_pacman --noconfirm -S mingw-w64-"${ARCH}"-python3-pip
|
||||
|
||||
PIP_REQUIREMENTS="\
|
||||
pycairo==1.18.0
|
||||
PyGObject==3.30.4
|
||||
gaphas==1.0.0
|
||||
zope.component==4.5
|
||||
tomlkit==0.5.3
|
||||
"
|
||||
|
||||
build_pip install $(echo "$PIP_REQUIREMENTS" | tr ["\\n"] [" "])
|
||||
|
||||
}
|
||||
|
||||
function get_version {
|
||||
python3 - <<END
|
||||
from tomlkit import parse
|
||||
with open('../pyproject.toml', 'r') as f:
|
||||
parsed_toml = parse(f.read())
|
||||
print(parsed_toml["tool"]["poetry"]["version"])
|
||||
END
|
||||
}
|
||||
|
||||
function install_gaphor {
|
||||
[ -z "$1" ] && (echo "Missing arg"; exit 1)
|
||||
|
||||
rm -Rf "${REPO_CLONE}"
|
||||
git clone "${DIR}"/.. "${REPO_CLONE}"
|
||||
|
||||
cd "${REPO_CLONE}"
|
||||
git checkout "$1"
|
||||
build_python setup.py install
|
||||
|
||||
cd "${DIR}"
|
||||
|
||||
# Create launchers
|
||||
python3 "${MISC}"/create-launcher.py \
|
||||
"${VERSION}" "${MINGW_ROOT}"/bin
|
||||
|
||||
VERSION=$(get_version)
|
||||
VERSION_DESC="$VERSION"
|
||||
if [ "$1" = "master" ]
|
||||
then
|
||||
local GIT_REV=$(git rev-list --count HEAD)
|
||||
local GIT_HASH=$(git rev-parse --short HEAD)
|
||||
VERSION_DESC="$VERSION-rev$GIT_REV-$GIT_HASH"
|
||||
fi
|
||||
|
||||
build_compileall -d "" -f -q "$(cygpath -w "${MINGW_ROOT}")"
|
||||
}
|
||||
|
||||
function cleanup_before {
|
||||
# these all have svg variants
|
||||
find "${MINGW_ROOT}"/share/icons -name "*.symbolic.png" -exec rm -f {} \;
|
||||
|
||||
# remove some larger ones
|
||||
rm -Rf "${MINGW_ROOT}/share/icons/Adwaita/512x512"
|
||||
rm -Rf "${MINGW_ROOT}/share/icons/Adwaita/256x256"
|
||||
rm -Rf "${MINGW_ROOT}/share/icons/Adwaita/96x96"
|
||||
rm -Rf "${MINGW_ROOT}/share/icons/Adwaita/48x48"
|
||||
"${MINGW_ROOT}"/bin/gtk-update-icon-cache-3.0.exe \
|
||||
"${MINGW_ROOT}"/share/icons/Adwaita
|
||||
|
||||
# python related, before installing gaphor
|
||||
rm -Rf "${MINGW_ROOT}"/lib/python3.*/test
|
||||
rm -f "${MINGW_ROOT}"/lib/python3.*/lib-dynload/_tkinter*
|
||||
find "${MINGW_ROOT}"/lib/python3.* -type d -name "test*" \
|
||||
-prune -exec rm -rf {} \;
|
||||
find "${MINGW_ROOT}"/lib/python3.* -type d -name "*_test*" \
|
||||
-prune -exec rm -rf {} \;
|
||||
|
||||
find "${MINGW_ROOT}"/bin -name "*.pyo" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}"/bin -name "*.pyc" -exec rm -f {} \;
|
||||
|
||||
build_compileall_pyconly -d "" -f -q "$(cygpath -w "${MINGW_ROOT}")"
|
||||
find "${MINGW_ROOT}" -name "*.py" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}" -type d -name "__pycache__" -prune -exec rm -rf {} \;
|
||||
}
|
||||
|
||||
function cleanup_after {
|
||||
# delete translations we don't support
|
||||
for d in "${MINGW_ROOT}"/share/locale/*/LC_MESSAGES; do
|
||||
if [ ! -f "${d}"/gaphor.mo ]; then
|
||||
rm -Rf "${d}"
|
||||
fi
|
||||
done
|
||||
|
||||
find "${MINGW_ROOT}" -regextype "posix-extended" -name "*.exe" -a ! \
|
||||
-iregex ".*/(gaphor|exfalso|operon|python|gspawn-)[^/]*\\.exe" \
|
||||
-exec rm -f {} \;
|
||||
|
||||
rm -Rf "${MINGW_ROOT}"/libexec
|
||||
rm -Rf "${MINGW_ROOT}"/share/gtk-doc
|
||||
rm -Rf "${MINGW_ROOT}"/include
|
||||
rm -Rf "${MINGW_ROOT}"/var
|
||||
rm -Rf "${MINGW_ROOT}"/etc/config.site
|
||||
rm -Rf "${MINGW_ROOT}"/etc/pki
|
||||
rm -Rf "${MINGW_ROOT}"/etc/pkcs11
|
||||
rm -Rf "${MINGW_ROOT}"/etc/gtk-3.0/im-multipress.conf
|
||||
rm -Rf "${MINGW_ROOT}"/share/zsh
|
||||
rm -Rf "${MINGW_ROOT}"/share/pixmaps
|
||||
rm -Rf "${MINGW_ROOT}"/share/gnome-shell
|
||||
rm -Rf "${MINGW_ROOT}"/share/dbus-1
|
||||
rm -Rf "${MINGW_ROOT}"/share/gir-1.0
|
||||
rm -Rf "${MINGW_ROOT}"/share/doc
|
||||
rm -Rf "${MINGW_ROOT}"/share/man
|
||||
rm -Rf "${MINGW_ROOT}"/share/info
|
||||
rm -Rf "${MINGW_ROOT}"/share/mime
|
||||
rm -Rf "${MINGW_ROOT}"/share/gettext
|
||||
rm -Rf "${MINGW_ROOT}"/share/libtool
|
||||
rm -Rf "${MINGW_ROOT}"/share/licenses
|
||||
rm -Rf "${MINGW_ROOT}"/share/appdata
|
||||
rm -Rf "${MINGW_ROOT}"/share/aclocal
|
||||
rm -Rf "${MINGW_ROOT}"/share/ffmpeg
|
||||
rm -Rf "${MINGW_ROOT}"/share/vala
|
||||
rm -Rf "${MINGW_ROOT}"/share/readline
|
||||
rm -Rf "${MINGW_ROOT}"/share/xml
|
||||
rm -Rf "${MINGW_ROOT}"/share/bash-completion
|
||||
rm -Rf "${MINGW_ROOT}"/share/common-lisp
|
||||
rm -Rf "${MINGW_ROOT}"/share/emacs
|
||||
rm -Rf "${MINGW_ROOT}"/share/gdb
|
||||
rm -Rf "${MINGW_ROOT}"/share/libcaca
|
||||
rm -Rf "${MINGW_ROOT}"/share/gettext
|
||||
rm -Rf "${MINGW_ROOT}"/share/gst-plugins-base
|
||||
rm -Rf "${MINGW_ROOT}"/share/gst-plugins-bad
|
||||
rm -Rf "${MINGW_ROOT}"/share/libgpg-error
|
||||
rm -Rf "${MINGW_ROOT}"/share/p11-kit
|
||||
rm -Rf "${MINGW_ROOT}"/share/pki
|
||||
rm -Rf "${MINGW_ROOT}"/share/thumbnailers
|
||||
rm -Rf "${MINGW_ROOT}"/share/gtk-3.0
|
||||
rm -Rf "${MINGW_ROOT}"/share/nghttp2
|
||||
rm -Rf "${MINGW_ROOT}"/share/themes
|
||||
rm -Rf "${MINGW_ROOT}"/share/fontconfig
|
||||
rm -Rf "${MINGW_ROOT}"/share/gettext-*
|
||||
rm -Rf "${MINGW_ROOT}"/share/installed-tests
|
||||
|
||||
find "${MINGW_ROOT}"/share/glib-2.0 -type f ! \
|
||||
-name "*.compiled" -exec rm -f {} \;
|
||||
|
||||
rm -Rf "${MINGW_ROOT}"/lib/cmake
|
||||
rm -Rf "${MINGW_ROOT}"/lib/gettext
|
||||
rm -Rf "${MINGW_ROOT}"/lib/gtk-3.0
|
||||
rm -Rf "${MINGW_ROOT}"/lib/mpg123
|
||||
rm -Rf "${MINGW_ROOT}"/lib/p11-kit
|
||||
rm -Rf "${MINGW_ROOT}"/lib/pkcs11
|
||||
rm -Rf "${MINGW_ROOT}"/lib/ruby
|
||||
rm -Rf "${MINGW_ROOT}"/lib/engines
|
||||
|
||||
find "${MINGW_ROOT}" -name "*.a" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}" -name "*.whl" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}" -name "*.h" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}" -name "*.la" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}" -name "*.sh" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}" -name "*.jar" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}" -name "*.def" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}" -name "*.cmd" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}" -name "*.cmake" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}" -name "*.pc" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}" -name "*.desktop" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}" -name "*.manifest" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}" -name "*.pyo" -exec rm -f {} \;
|
||||
|
||||
find "${MINGW_ROOT}"/bin -name "*-config" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}"/bin -name "easy_install*" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}" -regex ".*/bin/[^.]+" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}" -regex ".*/bin/[^.]+\\.[0-9]+" -exec rm -f {} \;
|
||||
|
||||
find "${MINGW_ROOT}" -name "gtk30-properties.mo" -exec rm -rf {} \;
|
||||
find "${MINGW_ROOT}" -name "gettext-tools.mo" -exec rm -rf {} \;
|
||||
find "${MINGW_ROOT}" -name "libexif-12.mo" -exec rm -rf {} \;
|
||||
find "${MINGW_ROOT}" -name "xz.mo" -exec rm -rf {} \;
|
||||
find "${MINGW_ROOT}" -name "libgpg-error.mo" -exec rm -rf {} \;
|
||||
|
||||
find "${MINGW_ROOT}" -name "old_root.pem" -exec rm -rf {} \;
|
||||
find "${MINGW_ROOT}" -name "weak.pem" -exec rm -rf {} \;
|
||||
|
||||
find "${MINGW_ROOT}"/bin -name "*.pyo" -exec rm -f {} \;
|
||||
find "${MINGW_ROOT}"/bin -name "*.pyc" -exec rm -f {} \;
|
||||
|
||||
build_python "${MISC}/depcheck.py" --delete
|
||||
|
||||
find "${MINGW_ROOT}" -type d -empty -delete
|
||||
}
|
||||
|
||||
function build_installer {
|
||||
BUILDPY=$(echo "${MINGW_ROOT}"/lib/python3.*/site-packages/gaphor*egg/gaphor)/build.py
|
||||
cp "${REPO_CLONE}"/win-installer/build.py "$BUILDPY"
|
||||
echo 'BUILD_TYPE = u"windows"' >> "$BUILDPY"
|
||||
echo "BUILD_VERSION = $BUILD_VERSION" >> "$BUILDPY"
|
||||
(cd "$REPO_CLONE" && echo "BUILD_INFO = u\"$(git rev-parse --short HEAD)\"" >> "$BUILDPY")
|
||||
build_compileall -d "" -q -f "$BUILDPY"
|
||||
|
||||
cp misc/gaphor.ico "${BUILD_ROOT}"
|
||||
(cd "${MINGW_ROOT}" && makensis -NOCD -DVERSION="$VERSION_DESC" "${MISC}"/win_installer.nsi)
|
||||
|
||||
mv "${MINGW_ROOT}/gaphor-LATEST.exe" "$DIR/gaphor-$VERSION_DESC-installer.exe"
|
||||
}
|
||||
|
||||
function build_portable_installer {
|
||||
cp "${REPO_CLONE}"/win-installer/build.py "$BUILDPY"
|
||||
echo 'BUILD_TYPE = u"windows-portable"' >> "$BUILDPY"
|
||||
echo "BUILD_VERSION = $BUILD_VERSION" >> "$BUILDPY"
|
||||
(cd "$REPO_CLONE" && echo "BUILD_INFO = u\"$(git rev-parse --short HEAD)\"" >> "$BUILDPY")
|
||||
build_compileall -d "" -q -f "$BUILDPY"
|
||||
|
||||
local PORTABLE="$DIR/gaphor-$VERSION_DESC-portable"
|
||||
|
||||
rm -rf "$PORTABLE"
|
||||
mkdir "$PORTABLE"
|
||||
cp "$MISC"/gaphor.lnk "$PORTABLE"
|
||||
cp "$MISC"/README-PORTABLE.txt "$PORTABLE"/README.txt
|
||||
unix2dos "$PORTABLE"/README.txt
|
||||
mkdir "$PORTABLE"/config
|
||||
cp -RT "${MINGW_ROOT}" "$PORTABLE"/data
|
||||
|
||||
rm -Rf 7zout 7z1900-x64.exe
|
||||
7z a payload.7z "$PORTABLE"
|
||||
wget.exe -P "$DIR" -c https://www.7-zip.org/a/7z1900-x64.exe
|
||||
7z x -o7zout 7z1900-x64.exe
|
||||
cat 7zout/7z.sfx payload.7z > "$PORTABLE".exe
|
||||
rm -Rf 7zout 7z1900-x64.exe payload.7z "$PORTABLE"
|
||||
}
|
21
win-installer/bootstrap.py
Normal file
21
win-installer/bootstrap.py
Normal file
@ -0,0 +1,21 @@
|
||||
import subprocess
|
||||
|
||||
|
||||
# Update pacman packages
|
||||
subprocess.run("pacman -Suy")
|
||||
|
||||
# Install PyGObject Development Environment
|
||||
subprocess.run(
|
||||
"pacman -S --needed --noconfirm"
|
||||
"base-devel"
|
||||
"mingw-w64-x68_64-toolchain"
|
||||
"git"
|
||||
"mingw-w64-x68_64-python3"
|
||||
"mingw-w64-x68_64-python3-cairo"
|
||||
"mingw-w64-x68_64-gobject-gobject"
|
||||
"mingw-w64-x68_64-python3-pip"
|
||||
"mingw-w64-x68_64-setuptools"
|
||||
)
|
||||
|
||||
# Install Gaphor dependencies
|
||||
subprocess.run("pip3 install --user -U" "gaphas" "zope.component" "pycairo" "PyGObject")
|
17
win-installer/build.py
Normal file
17
win-installer/build.py
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright 2016 Christoph Reiter, 2019 Dan Yeaw
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
"""This file gets edited at build time to add build specific data"""
|
||||
|
||||
BUILD_TYPE = u"default"
|
||||
"""Either 'windows', 'windows-portable', 'osx-gaphor', or 'default'"""
|
||||
|
||||
BUILD_INFO = u""
|
||||
"""Additional build info like git revision etc"""
|
||||
|
||||
BUILD_VERSION = 0
|
||||
"""1.2.3 with a BUILD_VERSION of 1 results in 1.2.3.1"""
|
44
win-installer/build.sh
Normal file
44
win-installer/build.sh
Normal file
@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright 2016 Christoph Reiter, 2019 Dan Yeaw
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
DIR="$( cd "$( dirname "$0" )" && pwd )"
|
||||
source "$DIR"/_base.sh
|
||||
|
||||
function main {
|
||||
local GIT_TAG=${1:-"master"}
|
||||
|
||||
if [[ -d "${BUILD_ROOT}" ]]; then
|
||||
echo "Removing ${BUILD_ROOT}"
|
||||
rm -rf "${BUILD_ROOT}"
|
||||
fi
|
||||
|
||||
# started from the wrong env -> switch
|
||||
if [ $(echo "$MSYSTEM" | tr '[A-Z]' '[a-z]') != "$MINGW" ]; then
|
||||
"/${MINGW}.exe" "$0"
|
||||
exit $?
|
||||
fi
|
||||
|
||||
echo "install pre-dependencies"
|
||||
install_pre_deps
|
||||
echo "create root"
|
||||
create_root
|
||||
echo "install dependencies"
|
||||
install_deps
|
||||
echo "cleanup before installing gaphor"
|
||||
cleanup_before
|
||||
echo "install gaphor"
|
||||
install_gaphor "$GIT_TAG"
|
||||
echo "cleanup"
|
||||
cleanup_after
|
||||
echo "build installer"
|
||||
build_installer
|
||||
echo "build portable installer"
|
||||
build_portable_installer
|
||||
}
|
||||
|
||||
main "$@";
|
17
win-installer/misc/README-PORTABLE.txt
Normal file
17
win-installer/misc/README-PORTABLE.txt
Normal file
@ -0,0 +1,17 @@
|
||||
===============
|
||||
Gaphor Portable
|
||||
===============
|
||||
|
||||
Content
|
||||
-------
|
||||
|
||||
* 'config' contains all user configuration
|
||||
* 'data' contains the program
|
||||
|
||||
|
||||
How to update to a newer version?
|
||||
---------------------------------
|
||||
|
||||
1) Download and extract the new version
|
||||
2) Replace the 'config' folder in the new version with the 'config' folder
|
||||
of the older version.
|
5
win-installer/misc/build-ico.sh
Normal file
5
win-installer/misc/build-ico.sh
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
../_build_root/mingw64/bin/magick convert ../../gaphor/ui/pixmaps/gaphor-48x48.png gaphor2.ico
|
232
win-installer/misc/create-launcher.py
Normal file
232
win-installer/misc/create-launcher.py
Normal file
@ -0,0 +1,232 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 Christoph Reiter, 2019 Dan Yeaw
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
"""Creates simple Python .exe launchers for gui and cli apps
|
||||
|
||||
./create-launcher.py "3.8.0" <target-dir>
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
import shlex
|
||||
import tempfile
|
||||
import shutil
|
||||
import struct
|
||||
|
||||
|
||||
def build_resource(rc_path, out_path):
|
||||
"""Raises subprocess.CalledProcessError"""
|
||||
|
||||
def is_64bit():
|
||||
return struct.calcsize("P") == 8
|
||||
|
||||
subprocess.check_call(
|
||||
[
|
||||
"windres",
|
||||
"-O",
|
||||
"coff",
|
||||
"-F",
|
||||
"pe-x86-64" if is_64bit() else "pe-i386",
|
||||
rc_path,
|
||||
"-o",
|
||||
out_path,
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def get_build_args():
|
||||
python_name = os.path.splitext(os.path.basename(sys.executable))[0]
|
||||
python_config = os.path.join(
|
||||
os.path.dirname(sys.executable), python_name + "-config"
|
||||
)
|
||||
|
||||
cflags = subprocess.check_output(["sh", python_config, "--cflags"]).strip()
|
||||
libs = subprocess.check_output(["sh", python_config, "--libs"]).strip()
|
||||
|
||||
cflags = os.fsdecode(cflags)
|
||||
libs = os.fsdecode(libs)
|
||||
return shlex.split(cflags) + shlex.split(libs)
|
||||
|
||||
|
||||
def build_exe(source_path, resource_path, is_gui, out_path):
|
||||
args = ["gcc", "-s"]
|
||||
if is_gui:
|
||||
args.append("-mwindows")
|
||||
args.append("-municode")
|
||||
args.extend(["-o", out_path, source_path, resource_path])
|
||||
args.extend(get_build_args())
|
||||
subprocess.check_call(args)
|
||||
|
||||
|
||||
def get_launcher_code(entry_point):
|
||||
module, func = entry_point.split(":", 1)
|
||||
|
||||
template = """\
|
||||
#include "Python.h"
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
PWSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
int result;
|
||||
|
||||
Py_NoUserSiteDirectory = 1;
|
||||
Py_IgnoreEnvironmentFlag = 1;
|
||||
Py_DontWriteBytecodeFlag = 1;
|
||||
Py_Initialize();
|
||||
PySys_SetArgvEx(__argc, __wargv, 0);
|
||||
result = PyRun_SimpleString("%s");
|
||||
Py_Finalize();
|
||||
return result;
|
||||
}
|
||||
"""
|
||||
|
||||
launch_code = "import sys; from %s import %s; sys.exit(%s())" % (module, func, func)
|
||||
return template % launch_code
|
||||
|
||||
|
||||
def get_resouce_code(
|
||||
filename,
|
||||
file_version,
|
||||
file_desc,
|
||||
icon_path,
|
||||
product_name,
|
||||
product_version,
|
||||
company_name,
|
||||
):
|
||||
|
||||
template = """\
|
||||
1 ICON "%(icon_path)s"
|
||||
1 VERSIONINFO
|
||||
FILEVERSION %(file_version_list)s
|
||||
PRODUCTVERSION %(product_version_list)s
|
||||
FILEOS 0x4
|
||||
FILETYPE 0x1
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "%(company_name)s"
|
||||
VALUE "FileDescription", "%(file_desc)s"
|
||||
VALUE "FileVersion", "%(file_version)s"
|
||||
VALUE "InternalName", "%(internal_name)s"
|
||||
VALUE "OriginalFilename", "%(filename)s"
|
||||
VALUE "ProductName", "%(product_name)s"
|
||||
VALUE "ProductVersion", "%(product_version)s"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1252
|
||||
END
|
||||
END
|
||||
"""
|
||||
|
||||
def to_ver_list(v):
|
||||
v = re.sub(r"rc\d", "", v)
|
||||
return ",".join(map(str, (list(map(int, v.split("."))) + [0] * 4)[:4]))
|
||||
|
||||
file_version_list = to_ver_list(file_version)
|
||||
product_version_list = to_ver_list(product_version)
|
||||
|
||||
return template % {
|
||||
"icon_path": icon_path,
|
||||
"file_version_list": file_version_list,
|
||||
"product_version_list": product_version_list,
|
||||
"file_version": file_version,
|
||||
"product_version": product_version,
|
||||
"company_name": company_name,
|
||||
"filename": filename,
|
||||
"internal_name": os.path.splitext(filename)[0],
|
||||
"product_name": product_name,
|
||||
"file_desc": file_desc,
|
||||
}
|
||||
|
||||
|
||||
def build_launcher(
|
||||
out_path,
|
||||
icon_path,
|
||||
file_desc,
|
||||
product_name,
|
||||
product_version,
|
||||
company_name,
|
||||
entry_point,
|
||||
is_gui,
|
||||
):
|
||||
|
||||
src_ico = os.path.abspath(icon_path)
|
||||
target = os.path.abspath(out_path)
|
||||
|
||||
file_version = product_version
|
||||
|
||||
dir_ = os.getcwd()
|
||||
temp = tempfile.mkdtemp()
|
||||
try:
|
||||
os.chdir(temp)
|
||||
with open("launcher.c", "w") as h:
|
||||
h.write(get_launcher_code(entry_point))
|
||||
shutil.copyfile(src_ico, "launcher.ico")
|
||||
with open("launcher.rc", "w") as h:
|
||||
h.write(
|
||||
get_resouce_code(
|
||||
os.path.basename(target),
|
||||
file_version,
|
||||
file_desc,
|
||||
"launcher.ico",
|
||||
product_name,
|
||||
product_version,
|
||||
company_name,
|
||||
)
|
||||
)
|
||||
|
||||
build_resource("launcher.rc", "launcher.res")
|
||||
build_exe("launcher.c", "launcher.res", is_gui, target)
|
||||
finally:
|
||||
os.chdir(dir_)
|
||||
shutil.rmtree(temp)
|
||||
|
||||
|
||||
def main():
|
||||
argv = sys.argv
|
||||
|
||||
version = argv[1]
|
||||
target = argv[2]
|
||||
|
||||
company_name = "Gaphor Community"
|
||||
misc = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
build_launcher(
|
||||
os.path.join(target, "gaphor.exe"),
|
||||
os.path.join(misc, "gaphor.ico"),
|
||||
"Gaphor",
|
||||
"Gaphor",
|
||||
version,
|
||||
company_name,
|
||||
"gaphor:main",
|
||||
True,
|
||||
)
|
||||
|
||||
build_launcher(
|
||||
os.path.join(target, "gaphor-cmd.exe"),
|
||||
os.path.join(misc, "gaphor.ico"),
|
||||
"Gaphor",
|
||||
"Gaphor",
|
||||
version,
|
||||
company_name,
|
||||
"gaphor:main",
|
||||
False,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
143
win-installer/misc/depcheck.py
Normal file
143
win-installer/misc/depcheck.py
Normal file
@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016,2017 Christoph Reiter
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
"""
|
||||
Deletes unneeded DLLs and checks DLL dependencies.
|
||||
Execute with the build python, will figure out the rest.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
from multiprocessing import Process, Queue
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("GIRepository", "2.0")
|
||||
from gi.repository import GIRepository
|
||||
|
||||
|
||||
def _get_shared_libraries(q, namespace, version):
|
||||
repo = GIRepository.Repository()
|
||||
repo.require(namespace, version, 0)
|
||||
lib = repo.get_shared_library(namespace)
|
||||
q.put(lib)
|
||||
|
||||
|
||||
def get_shared_libraries(namespace, version):
|
||||
# we have to start a new process because multiple versions can't be loaded
|
||||
# in the same process
|
||||
q = Queue()
|
||||
p = Process(target=_get_shared_libraries, args=(q, namespace, version))
|
||||
p.start()
|
||||
result = q.get()
|
||||
p.join()
|
||||
return result
|
||||
|
||||
|
||||
def get_required_by_typelibs():
|
||||
deps = set()
|
||||
repo = GIRepository.Repository()
|
||||
for tl in os.listdir(repo.get_search_path()[0]):
|
||||
namespace, version = os.path.splitext(tl)[0].split("-", 1)
|
||||
lib = get_shared_libraries(namespace, version)
|
||||
if lib:
|
||||
libs = lib.lower().split(",")
|
||||
else:
|
||||
libs = []
|
||||
for lib in libs:
|
||||
deps.add((namespace, version, lib))
|
||||
return deps
|
||||
|
||||
|
||||
def get_dependencies(filename):
|
||||
deps = []
|
||||
try:
|
||||
data = subprocess.check_output(
|
||||
["objdump", "-p", filename], stderr=subprocess.STDOUT
|
||||
)
|
||||
except subprocess.CalledProcessError:
|
||||
# can happen with wrong arch binaries
|
||||
return []
|
||||
data = data.decode("utf-8")
|
||||
for line in data.splitlines():
|
||||
line = line.strip()
|
||||
if line.startswith("DLL Name:"):
|
||||
deps.append(line.split(":", 1)[-1].strip().lower())
|
||||
return deps
|
||||
|
||||
|
||||
def find_lib(root, name):
|
||||
system_search_path = os.path.join("C:", os.sep, "Windows", "System32")
|
||||
if get_lib_path(root, name):
|
||||
return True
|
||||
elif os.path.exists(os.path.join(system_search_path, name)):
|
||||
return True
|
||||
elif name in ["gdiplus.dll"]:
|
||||
return True
|
||||
elif name.startswith("msvcr"):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_lib_path(root, name):
|
||||
search_path = os.path.join(root, "bin")
|
||||
if os.path.exists(os.path.join(search_path, name)):
|
||||
return os.path.join(search_path, name)
|
||||
|
||||
|
||||
def get_things_to_delete(root):
|
||||
extensions = [".exe", ".pyd", ".dll"]
|
||||
|
||||
all_libs = set()
|
||||
needed = set()
|
||||
for base, dirs, files in os.walk(root):
|
||||
for f in files:
|
||||
lib = f.lower()
|
||||
path = os.path.join(base, f)
|
||||
ext_lower = os.path.splitext(f)[-1].lower()
|
||||
if ext_lower in extensions:
|
||||
if ext_lower == ".exe":
|
||||
# we use .exe as dependency root
|
||||
needed.add(lib)
|
||||
all_libs.add(f.lower())
|
||||
for lib in get_dependencies(path):
|
||||
all_libs.add(lib)
|
||||
needed.add(lib)
|
||||
if not find_lib(root, lib):
|
||||
print("MISSING:", path, lib)
|
||||
|
||||
for namespace, version, lib in get_required_by_typelibs():
|
||||
all_libs.add(lib)
|
||||
needed.add(lib)
|
||||
if not find_lib(root, lib):
|
||||
print("MISSING:", namespace, version, lib)
|
||||
|
||||
to_delete = []
|
||||
for not_depended_on in all_libs - needed:
|
||||
path = get_lib_path(root, not_depended_on)
|
||||
if path:
|
||||
to_delete.append(path)
|
||||
|
||||
return to_delete
|
||||
|
||||
|
||||
def main(argv):
|
||||
libs = get_things_to_delete(sys.prefix)
|
||||
|
||||
if "--delete" in argv[1:]:
|
||||
while libs:
|
||||
for l in libs:
|
||||
print("DELETE:", l)
|
||||
os.unlink(l)
|
||||
libs = get_things_to_delete(sys.prefix)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
BIN
win-installer/misc/gaphor.ico
Normal file
BIN
win-installer/misc/gaphor.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.4 KiB |
BIN
win-installer/misc/gaphor.lnk
Normal file
BIN
win-installer/misc/gaphor.lnk
Normal file
Binary file not shown.
185
win-installer/misc/win_installer.nsi
Normal file
185
win-installer/misc/win_installer.nsi
Normal file
@ -0,0 +1,185 @@
|
||||
; Copyright 2016 Christoph Reiter, 2019 Dan Yeaw
|
||||
;
|
||||
; This program is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation; either version 2 of the License, or
|
||||
; (at your option) any later version.
|
||||
|
||||
Unicode true
|
||||
|
||||
!define NAME "Gaphor"
|
||||
!define ID "gaphor"
|
||||
!define DESC "Modeling Tool"
|
||||
|
||||
!define WEBSITE "https://gaphor.readthedocs.io"
|
||||
|
||||
!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}"
|
||||
!define INSTDIR_KEY "Software\${NAME}"
|
||||
!define INSTDIR_VALUENAME "InstDir"
|
||||
|
||||
!define MUI_CUSTOMFUNCTION_GUIINIT custom_gui_init
|
||||
!include "MUI2.nsh"
|
||||
!include "FileFunc.nsh"
|
||||
|
||||
Name "${NAME} (${VERSION})"
|
||||
OutFile "gaphor-LATEST.exe"
|
||||
SetCompressor /SOLID /FINAL lzma
|
||||
SetCompressorDictSize 32
|
||||
InstallDir "$PROGRAMFILES\${NAME}"
|
||||
RequestExecutionLevel admin
|
||||
|
||||
Var INST_BIN
|
||||
Var UNINST_BIN
|
||||
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_ICON "..\gaphor.ico"
|
||||
|
||||
!insertmacro MUI_PAGE_LICENSE "..\gaphor\LICENSE.txt"
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
!insertmacro MUI_LANGUAGE "Catalan"
|
||||
!insertmacro MUI_LANGUAGE "Dutch"
|
||||
!insertmacro MUI_LANGUAGE "French"
|
||||
!insertmacro MUI_LANGUAGE "PortugueseBR"
|
||||
!insertmacro MUI_LANGUAGE "Russian"
|
||||
!insertmacro MUI_LANGUAGE "Spanish"
|
||||
!insertmacro MUI_LANGUAGE "Swedish"
|
||||
|
||||
|
||||
Section "Install"
|
||||
SetShellVarContext all
|
||||
|
||||
; Use this to make things faster for testing installer changes
|
||||
;~ SetOutPath "$INSTDIR\bin"
|
||||
;~ File /r "mingw32\bin\*.exe"
|
||||
|
||||
SetOutPath "$INSTDIR"
|
||||
File /r "*.*"
|
||||
|
||||
StrCpy $INST_BIN "$INSTDIR\bin\gaphor.exe"
|
||||
StrCpy $UNINST_BIN "$INSTDIR\uninstall.exe"
|
||||
|
||||
; Store installation folder
|
||||
WriteRegStr HKLM "${INSTDIR_KEY}" "${INSTDIR_VALUENAME}" $INSTDIR
|
||||
|
||||
; Set up an entry for the uninstaller
|
||||
WriteRegStr HKLM "${UNINST_KEY}" \
|
||||
"DisplayName" "${NAME} - ${DESC}"
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "DisplayIcon" "$\"$INST_BIN$\""
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" \
|
||||
"$\"$UNINST_BIN$\""
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "QuietUninstallString" \
|
||||
"$\"$UNINST_BIN$\" /S"
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "InstallLocation" "$INSTDIR"
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "HelpLink" "${WEBSITE}"
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "Publisher" "${NAME} Community"
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${VERSION}"
|
||||
WriteRegDWORD HKLM "${UNINST_KEY}" "NoModify" 0x1
|
||||
WriteRegDWORD HKLM "${UNINST_KEY}" "NoRepair" 0x1
|
||||
; Installation size
|
||||
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
|
||||
IntFmt $0 "0x%08X" $0
|
||||
WriteRegDWORD HKLM "${UNINST_KEY}" "EstimatedSize" "$0"
|
||||
|
||||
; Register a default entry for file extension
|
||||
WriteRegStr HKLM "Software\Classes\${NAME}.ModelFile\open\command" "" "$\"$INST_BIN$\""
|
||||
WriteRegStr HKLM "Software\Classes\${NAME}.ModelFile\DefaultIcon" "" "$\"$INST_BIN$\""
|
||||
|
||||
; Register supported file extension
|
||||
WriteRegStr HKLM "Software\Classes\.${ID}" ".gaphor" "${NAME}.ModelFile"
|
||||
|
||||
; Add application entry
|
||||
WriteRegStr HKLM "Software\${NAME}\${ID}\Capabilities" "ApplicationDescription" "${DESC}"
|
||||
WriteRegStr HKLM "Software\${NAME}\${ID}\Capabilities" "ApplicationName" "${NAME}"
|
||||
|
||||
; Register application entry
|
||||
WriteRegStr HKLM "Software\RegisteredApplications" "${NAME}" "Software\${NAME}\${ID}\Capabilities"
|
||||
|
||||
; Register app paths
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\gaphor.exe" "" "$INST_BIN"
|
||||
|
||||
; Create uninstaller
|
||||
WriteUninstaller "$UNINST_BIN"
|
||||
|
||||
; Create start menu shortcuts
|
||||
CreateDirectory "$SMPROGRAMS\${NAME}"
|
||||
CreateShortCut "$SMPROGRAMS\${NAME}\${NAME}.lnk" "$INST_BIN"
|
||||
SectionEnd
|
||||
|
||||
Function custom_gui_init
|
||||
BringToFront
|
||||
|
||||
; Read the install dir and set it
|
||||
Var /GLOBAL instdir_temp
|
||||
Var /GLOBAL uninst_bin_temp
|
||||
|
||||
SetRegView 32
|
||||
ReadRegStr $instdir_temp HKLM "${INSTDIR_KEY}" "${INSTDIR_VALUENAME}"
|
||||
SetRegView lastused
|
||||
StrCmp $instdir_temp "" skip 0
|
||||
StrCpy $INSTDIR $instdir_temp
|
||||
skip:
|
||||
|
||||
SetRegView 64
|
||||
ReadRegStr $instdir_temp HKLM "${INSTDIR_KEY}" "${INSTDIR_VALUENAME}"
|
||||
SetRegView lastused
|
||||
StrCmp $instdir_temp "" skip2 0
|
||||
StrCpy $INSTDIR $instdir_temp
|
||||
skip2:
|
||||
|
||||
StrCpy $uninst_bin_temp "$INSTDIR\uninstall.exe"
|
||||
|
||||
; try to un-install existing installations first
|
||||
IfFileExists "$INSTDIR" do_uninst do_continue
|
||||
do_uninst:
|
||||
; instdir exists
|
||||
IfFileExists "$uninst_bin_temp" exec_uninst rm_instdir
|
||||
exec_uninst:
|
||||
; uninstall.exe exists, execute it and
|
||||
; if it returns success proceede, otherwise abort the
|
||||
; installer (uninstall aborted by user for example)
|
||||
ExecWait '"$uninst_bin_temp" _?=$INSTDIR' $R1
|
||||
; uninstall suceeded, since the uninstall.exe is still there
|
||||
; goto rm_instdir as well
|
||||
StrCmp $R1 0 rm_instdir
|
||||
; uninstall failed
|
||||
Abort
|
||||
rm_instdir:
|
||||
; either the uninstaller was sucessfull or
|
||||
; the uninstaller.exe wasn't found
|
||||
RMDir /r "$INSTDIR"
|
||||
do_continue:
|
||||
; the instdir shouldn't exist from here on
|
||||
|
||||
BringToFront
|
||||
FunctionEnd
|
||||
|
||||
Section "Uninstall"
|
||||
SetShellVarContext all
|
||||
SetAutoClose true
|
||||
|
||||
; Remove start menu entries
|
||||
Delete "$SMPROGRAMS\${NAME}\${NAME}.lnk"
|
||||
RMDir "$SMPROGRAMS\${NAME}"
|
||||
|
||||
; Remove application registration and file assocs
|
||||
DeleteRegKey HKLM "Software\Classes\${NAME}.ModelFile"
|
||||
DeleteRegKey HKLM "Software\.${ID}"
|
||||
DeleteRegKey HKLM "Software\${NAME}"
|
||||
DeleteRegValue HKLM "Software\RegisteredApplications" "${NAME}"
|
||||
|
||||
; Remove app paths
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\gaphor.exe"
|
||||
|
||||
; Delete installation related keys
|
||||
DeleteRegKey HKLM "${UNINST_KEY}"
|
||||
DeleteRegKey HKLM "${INSTDIR_KEY}"
|
||||
|
||||
; Delete files
|
||||
RMDir /r "$INSTDIR"
|
||||
SectionEnd
|
44
win-installer/rebuild.sh
Normal file
44
win-installer/rebuild.sh
Normal file
@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright 2016 Christoph Reiter, 2019 Dan Yeaw
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
DIR="$( cd "$( dirname "$0" )" && pwd )"
|
||||
source "$DIR"/_base.sh
|
||||
|
||||
set_build_root "${DIR}/_rebuild_root"
|
||||
|
||||
function main {
|
||||
local INSTALLER_PATH=${1}
|
||||
local GIT_TAG=${2:-"master"}
|
||||
|
||||
[[ -d "${BUILD_ROOT}" ]] && (echo "${BUILD_ROOT} already exists"; exit 1)
|
||||
|
||||
# started from the wrong env -> switch
|
||||
if [ $(echo "$MSYSTEM" | tr '[A-Z]' '[a-z]') != "$MINGW" ]; then
|
||||
"/${MINGW}.exe" "$0"
|
||||
exit $?
|
||||
fi
|
||||
|
||||
echo "install pre-dependencies"
|
||||
install_pre_deps
|
||||
echo "create root"
|
||||
create_root
|
||||
echo "extract installer"
|
||||
extract_installer "$INSTALLER_PATH"
|
||||
echo "cleanup before installing gaphor"
|
||||
cleanup_before
|
||||
echo "install gaphor"
|
||||
install_gaphor "$GIT_TAG"
|
||||
echo "cleanup"
|
||||
cleanup_after
|
||||
echo "build installer"
|
||||
build_installer
|
||||
echo "build portable installer"
|
||||
build_portable_installer
|
||||
}
|
||||
|
||||
main "$@";
|
Loading…
x
Reference in New Issue
Block a user