Giter VIP home page Giter VIP logo

repolib's Introduction

RepoLib

RepoLib is a Python library and CLI tool-set for managing your software system software repositories. It's currently set up to handle APT repositories on Debian-based linux distributions.

RepoLib is intended to operate on DEB822-format sources. It aims to provide feature parity with software-properties for most commonly used functions.

Documentation

Documentation is available online at Read The Docs.

Basic CLI Usage

RepoLib includes a CLI program for managing software repositories, apt-manage .

Usage is divided into subcommands for most tasks. Currently implemented commands are:

apt-manage add # Adds repositories to the system apt-manage list # Lists configuration details of repositories

Additional information is available with the built-in help:

apt-manage --help

Add

Apt-manage allows entering a URL for a repository, a complete debian line, or a Launchpad PPA shortcut (e.g. "ppa:user/repo"). It also adds signing keys for PPA style repositories automatically.

List

With no options, it outputs a list of the currently configured repositories on the system (all those found in /etc/apt/sources.list.d/ . With a configured repository as an argument, it outputs the configuration details of the specified repository.

Remove

Accepts one repository as an argument. Removes the specified repository.

NOTE: The system repository (/etc/at/sources.list.d/system.sources) cannot be removed.

Source

Allows enabling or disabling source code for the given repository.

Modify

Allows changing configuration details of a given repository

Installation

From System Repository

If your operating system packages repolib, you can install it by running:

sudo apt install python3-repolib

From Pre-Compiled .deb Package

If your distro does not yet supply the package, you can download and install the .deb package from the latest release. A script to do this automatically can be found in quick_install.sh.

Uninstall

To uninstall, simply do:

sudo apt remove python3-repolib

From PyPI

Repolib is available on PyPI. You can install it for your current user with:

pip3 install repolib

Alternatively, you can install it system-wide using:

sudo pip3 install repolib

Uninstall

To uninstall, simply do:

sudo pip3 uninstall repolib

From Git

First, clone the git repository onto your local system:

git clone https://github.com/isantop/repolib
cd repolib

Debian

On debian based distributions, you can build a .deb package locally and install it onto your system. You will need the following build-dependencies:

  • debhelper (>=11)
  • dh-python
  • python3-all
  • python3-dbus
  • python3-debian
  • python3-distro
  • python3-distutils
  • python3-gnupg
  • python3-launchpadlib
  • python3-lazr.restfulclient
  • python3-pytest
  • python3-setuptools

You can use this command to install these all in one go:

sudo apt install debhelper dh-python python3-all python3-dbus python3-debian python3-distro python3-distutils python3-gnupg python3-launchpadlib python3-lazr.restfulclient python3-pytest python3-setuptools

Then build and install the package:

debuild -us -uc
cd ..
sudo dpkg -i python3-repolib_*.deb

Uninstall

To uninstall, simply do:

sudo apt remove python3-repolib

setuptools setup.py

You can build and install the package using python3-setuptools. First, install the dependencies:

sudo apt install python3-all python3-setuptools

Then build and install the package:

sudo python3 ./setup.py install

Uninstall

You can uninstall RepoLib by removing the following files/directories:

  • /usr/local/lib/python3.7/dist-packages/repolib/
  • /usr/local/lib/python3.7/dist-packages/repolib-*.egg-info
  • /usr/local/bin/apt-manage

This command will remove all of these for you:

sudo rm -r /usr/local/lib/python3.7/dist-packages/repolib* /usr/local/bin/apt-manage

repolib's People

Contributors

13r0ck avatar benharri avatar chessmango avatar drnextgis avatar gozzarda avatar isantop avatar jacobgkau avatar leviport avatar lockszmith-gh avatar solt87 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

repolib's Issues

Helper method to get the system repository

Presently applications have to manually attempt to get the system repository and try to fallback if it's not available. It would be good to have a method in repolib that will automatically get a system source object and return that or a fallback if the system sources can't be found or don't exist.

Missing dependencies while installing from PyPI

$ pip install repolib
Collecting repolib
  Using cached repolib-1.5.1-py3-none-any.whl (65 kB)
Installing collected packages: repolib
Successfully installed repolib-1.5.1
$ pip freeze
repolib==1.5.1

Repolib does not skip empty files

Repolib should skip empty files, as they are syntactically valid and contain no sources. Currently it fails to parse them because the lack of sources causes issues generating a default name.

Substring "arch" being replaced with "Architectures" in signed-by path

Hi,

Hopefully I have diagnosed this right and come to the right place. Please do redirect me if this should be raised elsewhere.

I just upgraded to 22.04, and was sorting out my sources. I used the Pop Shop extra sources GUI to give them nice names because why not. After doing this I noticed I could no lunger update from the github cli source. I noticed that the paths in the file (/etc/apt/sources.list.d/github-cli.list) had changed.

I fixed the errors, and successfully reporduced the bug by opening and saving the source (without making any changes).

The contents of the file are initially:

## Added/managed by repolib ##
#
## X-Repolib-Name: GItHub CLI
deb [arch=amd64 signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main
# deb-src [arch=amd64 signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main

If I then go to Pop Shop, Settings, Extra Sources, select "GitHub CLI", click the pencil button, and click Save in the window that opens, the contents of the file are changed to this:

## Added/managed by repolib ##
#
## X-Repolib-Name: GitHub CLI
deb [arch=amd64 signed-by=/usr/share/keyrings/githubcli-Architecturesive-keyring.gpg] https://cli.github.com/packages stable main
# deb-src [arch=amd64 signed-by=/usr/share/keyrings/githubcli-Architecturesive-keyring.gpg] https://cli.github.com/packages stable main

It would appear that every occurence of "arch" in at least the signed-by paths is being expanded to the full string "Architectures", and clobbering the path. This causes APT to give the following warning:

...
Err:1 https://cli.github.com/packages stable InRelease                                                                      
  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY C99B11DEB97541F0
...
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: https://cli.github.com/packages stable InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY C99B11DEB97541F0
W: Failed to fetch https://cli.github.com/packages/dists/stable/InRelease  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY C99B11DEB97541F0
W: Some index files failed to download. They have been ignored, or old ones used instead.

This error propagates through to Pop Shop itself when it is next opened, resulting in a "Failed to Fetch Updates" pop-up that gives the same warning in its details.

I have found no fix other than to correct the sources file by hand after any edit made using the GUI.

In case it helps, here are the results of apt-cache show pop-shop:

Package: pop-shop
Architecture: amd64
Version: 3.4.2pop0~1650311375~22.04~b2e7dbb
Priority: extra
Section: utils
Maintainer: System76 <[email protected]>
Installed-Size: 3020
Depends: appstream (>= 0.12), apt-config-icons, apt-config-icons-hidpi, apt-config-icons-large, apt-config-icons-large-hidpi, libgranite6 (>= 6.0.0), libhandy-1-0 (>= 1.0.3), packagekit, repoman, dconf-gsettings-backend | gsettings-backend, libappstream4 (>= 0.11.0), libc6 (>= 2.34), libflatpak0 (>= 1.1.3), libgdk-pixbuf-2.0-0 (>= 2.22.0), libgee-0.8-2 (>= 0.10.1), libglib2.0-0 (>= 2.49.2), libgtk-3-0 (>= 3.22.29), libjson-glib-1.0-0 (>= 1.5.2), libpackagekit-glib2-18 (>= 1.1.0), libpolkit-gobject-1-0 (>= 0.99), libsoup2.4-1 (>= 2.41.90), libxml2 (>= 2.7.4)
Recommends: appstream-data-pop
Filename: pool/jammy/shop/b2e7dbbb0594705dd6a3ab8b07925372de4da543/pop-shop_3.4.2pop0~1650311375~22.04~b2e7dbb_amd64.deb
Size: 1212322
MD5sum: 634bc6b2d7bdbc71fed12debbcd94e2c
SHA1: d0f6aae35b15f1452a947378d17f0e28f77898d6
SHA256: 6c21895126b6c078b82c40ed5af0eba5315047f2a22f71b45ac676b6dfe9572e
SHA512: cb3e90d45c293f2a4a033f3670ba6e875d31e45bb750d153d5b9302626e3045d080c672b2cf7e8f4877c5c87a28958ac3ce0861c53d84531b613c470748d9304
Homepage: https://github.com/pop-os/shop
Description: Fast application store
 Install, update and remove apps with ease.
 Helps independent developers.
Description-md5: d622a5467319aa9b68e9f4f792be6615

and apt-cache show python3-repolib:

Package: python3-repolib
Architecture: all
Version: 1.5.2~1630340924~22.04~3d11f10
Priority: optional
Section: python
Source: repolib
Maintainer: Ian Santopietro <[email protected]>
Installed-Size: 190
Depends: python3:any, apt, lsb-release, python3-dbus, python3-debian
Recommends: python3-lazr.restfulclient, python3-launchpadlib
Filename: pool/jammy/repolib/3d11f107f4a5737569183516784287d8e646043f/python3-repolib_1.5.2~1630340924~22.04~3d11f10_all.deb
Size: 30856
MD5sum: dc14228d0c4bef351e92bfae17625bb5
SHA1: 891e199cbfedd04873fbc1f388feaffce09eb2ac
SHA256: d64722c5a411b4310a6827fc5d2788dd1234b73ba69817264d47a0aa6e450557
SHA512: f38e4bf32db17ee605252b817429af4afbbcbc4c6bd4c401e2238d0a881db6f65294e47faacdcd7579035c8e13e9a1be8f41fa7fb379662180bb124b470feec2
Homepage: https://github.com/isantop/repolib
Description: Repository Management for APT in Python (Python 3)
 RepoLib is a Python library and CLI tool-set for managing your software
 system software repositories. It's currently set up to handle APT repositories
 on Debian-based linux distributions.
 .
 RepoLib is intended to operate on DEB822-format sources. It aims to provide
 feature parity with software-properties for most commonly used functions.
 .
 This package installs the library for Python 3.
Description-md5: 7a658d23a491e459ba210f05732d8668

I have tried to provide as much detail as possible in this issue, but please do let me know if you need anything more from me.

Cheers,
Gozz

[22.04] updates and upgrades failing on `python3-repolib` package

We're seeing a number of customer systems that have had failed update and/or upgrade attempts since Friday. Customer systems are sometimes ending up in a half-upgraded state where the system boots but many things are broken. It's unclear what the root cause is.

This may be related to the commit that was merged on Thursday (e2261d9) but I'm not really seeing how it could cause the issue, unless it triggered something in an earlier commit.

Customers are seeing something like this when running apt full-upgrade:

Setting up python3-repolib (1.5.2~1651157034~22.04~e2261d9) ...
ln: failed to create symbolic link '/usr/bin/add-apt-repository': File exists
ln: failed to create symbolic link '/usr/bin/apt-add-repository': File exists
dpkg: error processing package python3-repolib (--configure):
installed python3-repolib package post-installation script subprocess returned error exit status 1
Errors were encountered while processing:
python3-repolib
E: Sub-process /usr/bin/dpkg returned an error code (1)

/usr/bin/apt-add-repository is provided by the software-properties-common package from Ubuntu, and on a default system it is not symlinked to /usr/lib/repolib/add-apt-repository, which is provided by our own python3-repolib. This output is from a fresh VM that was installed with v21.10 and then upgraded to v22.04, which failed to replicate the problem:

ckw@pop-os:~$ ls -la /usr/lib/repolib/add-apt-repository
-rwxr-xr-x 1 root root 4650 Apr 28 09:43 /usr/lib/repolib/add-apt-repository
ckw@pop-os:~$ ls -la /usr/bin/add-apt-repository
-rwxr-xr-x 1 root root 14478 Apr  1 13:48 /usr/bin/add-apt-repository

Here are some public threads on Ubuntu forums and Reddit:
https://askubuntu.com/questions/1405650/cannot-upgrade-any-applications-python3-repolib-error-pop-os
https://www.reddit.com/r/pop_os/comments/uff16m/unable_to_update_packages_post_2204_upgrade/
https://www.reddit.com/r/pop_os/comments/ues9ru/updating_error_2204/

Users have reported various fixes but they all seem like workarounds which might lead to further package problems later. For example:

I have fixed the error I was getting.
  "Setting up python3-repolib (1.5.2~1651157034~22.04~e2261d9) ...
ln: failed to create symbolic link '/usr/bin/add-apt-repository': File exists"

I went into the directory /usr/bin/ and deleted the file @add-apt-repository.
After I deleted the file Pop Shop updates are working now.

Remove ppa:teward/znc from repolib docs/examples

It has come to my attention through various sources that my ZNC repository I haven't updated in a long eternity is in your documentation as an example of a 'disabled' repository in the deb822 formatting documentation.

In Launchpad, that PPA is disabled, does not publish, and is actually scheduled for deletion on the PPA system because I am not maintaining it anymore.

To that end, you might want to use a different example for your repos. Disabled or not, it isn't necessarily a positive to be using old/obsolete links in documentation.

Repoman won't launch Pop OS 22.04

As outlined in this Reddit post
Some users are unable to launch repoman. This is the output from running it in the terminal:
(repoman:790729): Gtk-CRITICAL **: 03:14:48.404: gtk_widget_grab_default: assertion 'gtk_widget_get_can_default (widget)' failed
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/repoman/main.py", line 37, in do_activate
self.win = Window()
File "/usr/lib/python3/dist-packages/repoman/window.py", line 43, in init
self.stack = Stack(self)
File "/usr/lib/python3/dist-packages/repoman/stack.py", line 59, in init
self.list_all = List(self)
File "/usr/lib/python3/dist-packages/repoman/list.py", line 128, in init
self.generate_entries()
File "/usr/lib/python3/dist-packages/repoman/list.py", line 299, in generate_entries
[source.name, source.uris[0], source.ident]
File "/usr/lib/python3/dist-packages/repolib/source.py", line 341, in name
self.generate_default_name()
File "/usr/lib/python3/dist-packages/repolib/source.py", line 229, in generate_default_name
if not self['X-Repolib-Name']:
File "/usr/lib/python3/dist-packages/debian/deb822.py", line 491, in getitem
value = self.__dict[keyi]
KeyError: 'X-Repolib-Name'

Repolib adds Apt Preferences files with dots

If a popdev staging branch contains dots (e.g. popdev:linux-6.0.0) then the resultant preferences file filename will contain dots, which are invalid characters in the filename of an Apt preferences file, causing the following error:

N: Ignoring file 'pop-os-staging-linux-6.0.0' in directory '/etc/apt/preferences.d/' as it has an invalid filename extension

Apt preferences file filenames should be scrubbed to remove dots and other invalid character names

Command crashes when trying to add a malformed source

system76@pop-os:~$ apt-manage add pop-dev:isolate-workspaces
Fetching repository information...
Traceback (most recent call last):
  File "/usr/bin/apt-manage", line 82, in <module>
    main()
  File "/usr/bin/apt-manage", line 76, in main
    result = command.run()
  File "/usr/lib/python3/dist-packages/repolib/command/add.py", line 155, in run
    new_source.load_from_data([self.deb_line])
UnboundLocalError: local variable 'new_source' referenced before assignment

Don't warn about spelling error when removing a `popdev:` source

It's not intuitive to need to use different syntax for apt-manage add and apt-manage remove. If we're pretending that popdev: is a protocol, then it should be accepted (without suggesting a different syntax) for both adding and removing, not just adding.

Versions and compatibility issues

TL;DR: Are you willing to accept a few PRs to improve packaging and compatibility?

First of all, congrats for such an amazing library! It's been a while I've wanted for an apt-add-repository that did the right thing regarding signing keys: to store them in /etc/apt/keyrings and add the corresponding Signed-By entry to the deb line/stanza. Turns out Repolib does that and much, much more! Huge thanks!

So, I've noticed the version in PopOS PPA for Ubuntu Focal is very outdated, and tried to make current 2.1.1 works there. So I started hacking and researching the dependencies and versions to map all incompatibilities, and as it turns out I've managed not only to get 2.1.1 working on Focal but also on Bionic! Yes, using the ancient python 3.6!

The main incompatibilities to current master are:

  • httplib2.error was added in httplib2 0.19.0, released in 2021-02-07, so not available to Focal.
  • Path.unlink(missing_ok) requires Python 3.8, available to Bionic but not the default (so debian/control should require it)
  • distro.codename()'s semantic changed in distro 1.4.0, released in 2019-02-04, so cannot be used as an lsb_release drop-in replacement in Bionic.

While researching all this, I've also noticed many packages and dependencies are not properly configured in debian/control, either not listed at all (such as python3-distro) or missing/wrong minimum version requirement. I was also able to fix a few lintian warnings and errors.

That said, how do you feel about a few PRs to improve DEB and Python packaging, and possibly make current releases compatible with Focal (and maybe even Bionic)?

Won't parse neovim-ppa-ubuntu-stable-mantic.sources with error: KeyError: 'X-Repolib-Name'

I added neovim unstable PPA on Ubuntu Mantic with command:

add-apt-repository ppa:neovim-ppa/unstable

resulted a file /etc/apt/sources.list.d/neovim-ppa-ubuntu-stable-mantic.sources which had gpg key in it.

   1   | Types: deb
   2   │ URIs: https://ppa.launchpadcontent.net/neovim-ppa/unstable/ubuntu/
   3   │ Suites: mantic
   4   │ Components: main
   5   │ Signed-By: 
   6   │  -----BEGIN PGP PUBLIC KEY BLOCK-----
   7   │  .
   8   │  mQINBFSJzaMBEACxpSOtdO1I0N1Ett33RszDCmK7erP77pcABb6c/7fHhkqoaOq0

When I use apt-manage list command, it report error as "KeyError: 'X-Repolib-Name'".

I figure out this could be the cause, by removing the file and re-add with "apt-manage add" command and fixed it.

Though would like to raise this, as somebody else may encounter same issue like this.
Better way maybe to add "compatibility" with add-apt-repository command from Ubuntu.

Install Works KeyError: 'list'

Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-56-generic x86_64)

Python 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

Cloning into 'repolib'...
remote: Enumerating objects: 567, done.
remote: Counting objects: 100% (122/122), done.
remote: Compressing objects: 100% (95/95), done.
remote: Total 567 (delta 71), reused 55 (delta 25), pack-reused 445
Receiving objects: 100% (567/567), 141.83 KiB | 5.25 MiB/s, done.
Resolving deltas: 100% (353/353), done.

apt install python3-all python3-setuptools
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
python3-setuptools is already the newest version (59.6.0-1.2).
python3-all is already the newest version (3.10.6-1~22.04).
0 upgraded, 0 newly installed, 0 to remove and 6 not upgraded.

cd repolib
repolib# python3 ./setup.py install
/root/repolib/./setup.py:31: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives
from distutils.core import setup
/usr/lib/python3.10/distutils/dist.py:274: UserWarning: Unknown distribution option: 'tests_require'
warnings.warn(msg)
running install
running build
running build_py
creating build
creating build/lib
creating build/lib/repolib
copying repolib/deb.py -> build/lib/repolib
copying repolib/system_test.py -> build/lib/repolib
copying repolib/system.py -> build/lib/repolib
copying repolib/source.py -> build/lib/repolib
copying repolib/version.py -> build/lib/repolib
copying repolib/util.py -> build/lib/repolib
copying repolib/legacy_deb_test.py -> build/lib/repolib
copying repolib/ppa.py -> build/lib/repolib
copying repolib/legacy_deb.py -> build/lib/repolib
copying repolib/source_test.py -> build/lib/repolib
copying repolib/deb_test.py -> build/lib/repolib
copying repolib/ppa_test.py -> build/lib/repolib
copying repolib/init.py -> build/lib/repolib
creating build/lib/repolib/command
copying repolib/command/add.py -> build/lib/repolib/command
copying repolib/command/argparser.py -> build/lib/repolib/command
copying repolib/command/command.py -> build/lib/repolib/command
copying repolib/command/init.py -> build/lib/repolib/command
running build_scripts
creating build/scripts-3.10
copying and adjusting bin/apt-manage -> build/scripts-3.10
changing mode of build/scripts-3.10/apt-manage from 644 to 755
running install_lib
creating /usr/local/lib/python3.10/dist-packages/repolib
creating /usr/local/lib/python3.10/dist-packages/repolib/command
copying build/lib/repolib/command/add.py -> /usr/local/lib/python3.10/dist-packages/repolib/command
copying build/lib/repolib/command/argparser.py -> /usr/local/lib/python3.10/dist-packages/repolib/command
copying build/lib/repolib/command/command.py -> /usr/local/lib/python3.10/dist-packages/repolib/command
copying build/lib/repolib/command/init.py -> /usr/local/lib/python3.10/dist-packages/repolib/command
copying build/lib/repolib/deb.py -> /usr/local/lib/python3.10/dist-packages/repolib
copying build/lib/repolib/system_test.py -> /usr/local/lib/python3.10/dist-packages/repolib
copying build/lib/repolib/system.py -> /usr/local/lib/python3.10/dist-packages/repolib
copying build/lib/repolib/source.py -> /usr/local/lib/python3.10/dist-packages/repolib
copying build/lib/repolib/version.py -> /usr/local/lib/python3.10/dist-packages/repolib
copying build/lib/repolib/util.py -> /usr/local/lib/python3.10/dist-packages/repolib
copying build/lib/repolib/legacy_deb_test.py -> /usr/local/lib/python3.10/dist-packages/repolib
copying build/lib/repolib/ppa.py -> /usr/local/lib/python3.10/dist-packages/repolib
copying build/lib/repolib/legacy_deb.py -> /usr/local/lib/python3.10/dist-packages/repolib
copying build/lib/repolib/source_test.py -> /usr/local/lib/python3.10/dist-packages/repolib
copying build/lib/repolib/deb_test.py -> /usr/local/lib/python3.10/dist-packages/repolib
copying build/lib/repolib/ppa_test.py -> /usr/local/lib/python3.10/dist-packages/repolib
copying build/lib/repolib/init.py -> /usr/local/lib/python3.10/dist-packages/repolib
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/command/add.py to add.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/command/argparser.py to argparser.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/command/command.py to command.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/command/init.py to init.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/deb.py to deb.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/system_test.py to system_test.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/system.py to system.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/source.py to source.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/version.py to version.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/util.py to util.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/legacy_deb_test.py to legacy_deb_test.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/ppa.py to ppa.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/legacy_deb.py to legacy_deb.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/source_test.py to source_test.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/deb_test.py to deb_test.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/ppa_test.py to ppa_test.cpython-310.pyc
byte-compiling /usr/local/lib/python3.10/dist-packages/repolib/init.py to init.cpython-310.pyc
running install_scripts
copying build/scripts-3.10/apt-manage -> /usr/local/bin
changing mode of /usr/local/bin/apt-manage to 755
running install_data
copying data/apt-manage -> /usr/local/share/bash-completion/completions
running install_egg_info
Writing /usr/local/lib/python3.10/dist-packages/repolib-1.2.0.egg-info

apt-manage -h
usage: apt-manage [-h] COMMAND ...

Manage software sources and repositories

positional arguments:
COMMAND ...
add Add a new repository to the system.
remove Remove a configured repository.
modify Change a configured repository.
list List configured repositories. If a repository name is provided, show details about
that repository.
source Enable/disable source code packages for repositories

options:
-h, --help show this help message and exit

apt-manage version: 1.2.0

apt-manage list
Traceback (most recent call last):
File "/usr/local/bin/apt-manage", line 90, in
main()
File "/usr/local/bin/apt-manage", line 86, in main
action[args.action](log, args, parser)
KeyError: 'list'

apt list --installed
Listing... Done

python-apt-common/jammy-updates,now 2.3.0ubuntu2.1 all [installed,automatic]
python-babel-localedata/jammy,now 2.8.0+dfsg.1-7 all [installed,automatic]
python3-acme/jammy,now 1.21.0-1 all [installed,automatic]
python3-all/jammy-updates,now 3.10.6-122.04 amd64 [installed]
python3-apport/jammy-updates,now 2.20.11-0ubuntu82.3 all [installed,automatic]
python3-apt/jammy-updates,now 2.3.0ubuntu2.1 amd64 [installed,automatic]
python3-attr/jammy,now 21.2.0-1 all [installed,automatic]
python3-augeas/jammy,now 0.5.0-1.1 all [installed,automatic]
python3-automat/jammy,now 20.2.0-1 all [installed,automatic]
python3-babel/jammy,now 2.8.0+dfsg.1-7 all [installed,automatic]
python3-bcrypt/jammy,now 3.2.0-1build1 amd64 [installed,automatic]
python3-blinker/jammy,now 1.4+dfsg1-0.4 all [installed,automatic]
python3-certbot-apache/jammy,now 1.21.0-1 all [installed]
python3-certbot/jammy,now 1.21.0-1build1 all [installed,automatic]
python3-certifi/jammy,now 2020.6.20-1 all [installed,automatic]
python3-cffi-backend/jammy,now 1.15.0-1build2 amd64 [installed,automatic]
python3-chardet/jammy,now 4.0.0-1 all [installed,automatic]
python3-click/jammy,now 8.0.3-1 all [installed,automatic]
python3-colorama/jammy,now 0.4.4-1 all [installed,automatic]
python3-commandnotfound/jammy,now 22.04.0 all [installed,automatic]
python3-configargparse/jammy,now 1.5.3-1 all [installed,automatic]
python3-configobj/jammy,now 5.0.6-5 all [installed,automatic]
python3-constantly/jammy,now 15.1.0-2 all [installed,automatic]
python3-cryptography/jammy,now 3.4.8-1ubuntu2 amd64 [installed,automatic]
python3-dbus/jammy,now 1.2.18-3build1 amd64 [installed,automatic]
python3-debconf/jammy,now 1.5.79ubuntu1 all [installed,automatic]
python3-debian/jammy,now 0.1.43ubuntu1 all [installed,automatic]
python3-dev/jammy-updates,now 3.10.6-1
22.04 amd64 [installed,automatic]
python3-distro-info/jammy,now 1.1build1 all [installed,automatic]
python3-distro/jammy,now 1.7.0-1 all [installed,automatic]
python3-distupgrade/jammy-updates,now 1:22.04.15 all [installed,automatic]
python3-distutils/jammy-updates,now 3.10.6-122.04 all [installed]
python3-gdbm/jammy-updates,now 3.10.6-1
22.04 amd64 [installed,automatic]
python3-gi/jammy-updates,now 3.42.1-0ubuntu1 amd64 [installed,automatic]
python3-hamcrest/jammy,now 2.0.2-2 all [installed,automatic]
python3-httplib2/jammy,now 0.20.2-2 all [installed,automatic]
python3-hyperlink/jammy,now 21.0.0-3 all [installed,automatic]
python3-icu/jammy,now 2.8.1-0ubuntu2 amd64 [installed,automatic]
python3-idna/jammy,now 3.3-1 all [installed,automatic]
python3-importlib-metadata/jammy,now 4.6.4-1 all [installed]
python3-incremental/jammy,now 21.3.0-1 all [installed,automatic]
python3-jeepney/jammy,now 0.7.1-3 all [installed,automatic]
python3-jinja2/jammy,now 3.0.3-1 all [installed]
python3-josepy/jammy,now 1.10.0-1 all [installed,automatic]
python3-json-pointer/jammy,now 2.0-0ubuntu1 all [installed]
python3-jsonpatch/jammy,now 1.32-2 all [installed]
python3-jsonschema/jammy,now 3.2.0-0ubuntu2 all [installed]
python3-jwt/jammy-updates,jammy-security,now 2.3.0-1ubuntu0.2 all [installed,automatic]
python3-keyring/jammy,now 23.5.0-1 all [installed,automatic]
python3-launchpadlib/jammy,now 1.10.16-1 all [installed,automatic]
python3-lazr.restfulclient/jammy,now 0.14.4-1 all [installed,automatic]
python3-lazr.uri/jammy,now 1.0.6-2 all [installed,automatic]
python3-lib2to3/jammy-updates,now 3.10.6-122.04 all [installed]
python3-magic/jammy,now 2:0.4.24-2 all [installed,automatic]
python3-markupsafe/jammy,now 2.0.1-2build1 amd64 [installed]
python3-minimal/jammy-updates,now 3.10.6-1
22.04 amd64 [installed,automatic]
python3-more-itertools/jammy,now 8.10.0-2 all [installed]
python3-nacl/jammy,now 1.5.0-2 amd64 [installed]
python3-netifaces/jammy,now 0.11.0-1build2 amd64 [installed,automatic]
python3-newt/jammy,now 0.52.21-5ubuntu2 amd64 [installed,automatic]
python3-oauthlib/jammy-updates,jammy-security,now 3.2.0-1ubuntu0.1 all [installed,automatic]
python3-openssl/jammy,now 21.0.0-1 all [installed,automatic]
python3-parsedatetime/jammy,now 2.6-2 all [installed,automatic]
python3-pcp/jammy,now 5.3.6-1build1 amd64 [installed,automatic]
python3-pexpect/jammy,now 4.8.0-2ubuntu1 all [installed,automatic]
python3-pip/jammy,now 22.0.2+dfsg-1 all [installed]
python3-pkg-resources/jammy,now 59.6.0-1.2 all [installed,automatic]
python3-problem-report/jammy-updates,now 2.20.11-0ubuntu82.3 all [installed,automatic]
python3-ptyprocess/jammy,now 0.7.0-3 all [installed,automatic]
python3-pyasn1-modules/jammy,now 0.2.1-1 all [installed,automatic]
python3-pyasn1/jammy,now 0.4.8-1 all [installed,automatic]
python3-pyinotify/jammy,now 0.9.6-1.3 all [installed,automatic]
python3-pymacaroons/jammy,now 0.13.0-4 all [installed]
python3-pyparsing/jammy,now 2.4.7-1 all [installed,automatic]
python3-pyrsistent/jammy,now 0.18.1-1build1 amd64 [installed]
python3-requests-toolbelt/jammy,now 0.9.1-1 all [installed,automatic]
python3-requests/jammy,now 2.25.1+dfsg-2 all [installed,automatic]
python3-rfc3339/jammy,now 1.1-3 all [installed,automatic]
python3-secretstorage/jammy,now 3.3.1-1 all [installed,automatic]
python3-serial/jammy,now 3.5-1 all [installed]
python3-service-identity/jammy,now 18.1.0-6 all [installed,automatic]
python3-setuptools/jammy,now 59.6.0-1.2 all [installed]
python3-six/jammy,now 1.16.0-3ubuntu1 all [installed,automatic]
python3-software-properties/jammy-updates,now 0.99.22.3 all [installed,automatic]
python3-systemd/jammy,now 234-3ubuntu2 amd64 [installed,automatic]
python3-twisted/jammy-updates,jammy-security,now 22.1.0-2ubuntu2.3 all [installed,automatic]
python3-tz/jammy-updates,now 2022.1-1ubuntu0.22.04.0 all [installed,automatic]
python3-update-manager/jammy,now 1:22.04.9 all [installed,upgradable to: 1:22.04.10]
python3-urllib3/jammy,now 1.26.5-1exp1 all [installed,automatic]
python3-wadllib/jammy,now 1.3.6-1 all [installed,automatic]
python3-wheel/jammy,now 0.37.1-2 all [installed,automatic]
python3-yaml/jammy,now 5.4.1-1ubuntu1 amd64 [installed,automatic]
python3-zipp/jammy,now 1.0.0-3 all [installed]
python3-zope.component/jammy,now 4.3.0-3 all [installed,automatic]
python3-zope.event/jammy,now 4.4-3 all [installed,automatic]
python3-zope.hookable/jammy,now 5.1.0-1build1 amd64 [installed,automatic]
python3-zope.interface/jammy,now 5.4.0-1build1 amd64 [installed,automatic]
python3.10-dev/jammy-updates,jammy-security,now 3.10.6-1
22.04.2 amd64 [installed,automatic]
python3.10-minimal/jammy-updates,jammy-security,now 3.10.6-122.04.2 amd64 [installed,automatic]
python3.10/jammy-updates,jammy-security,now 3.10.6-1
22.04.2 amd64 [installed,automatic]
python3/jammy-updates,now 3.10.6-1~22.04 amd64 [installed,automatic]

apt-key list
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
/etc/apt/trusted.gpg

pub rsa4096 2021-06-22 [SC] [expires: 2031-06-20]
84FA A998 3B24 AEF2 4D6C 87F1 FEBB 7D18 1257 6482
uid [ unknown] CISOfy software signing [email protected]
sub rsa4096 2021-06-22 [S] [expires: 2031-06-20]
sub rsa4096 2021-06-22 [E] [expires: 2031-06-20]

pub rsa2048 2013-11-27 [SC]
6CCE A47B 2281 732D F5D5 04D0 0C54 D189 F4BA 284D
uid [ unknown] Collabora Productivity [email protected]
uid [ unknown] LibreOffice-from-Collabora [email protected]
uid [ unknown] Collabora LibreOffice [email protected]

pub rsa2048 2016-02-17 [SC]
9FE3 B226 BD77 5196 D8C2 E599 DE88 104A A4C6 383F
uid [ unknown] DigitalOcean Insights Engineering [email protected]
sub rsa2048 2016-02-17 [E]

pub rsa4096 2022-11-09 [SC]
902C 44B4 2EA9 A17F 8578 5109 77B7 9B3F FAF7 EF65
uid [ unknown] DigitalOcean Insights Engineering [email protected]

/etc/apt/trusted.gpg.d/ondrej_ubuntu_apache2.gpg

pub rsa1024 2009-01-26 [SC]
14AA 40EC 0831 7567 56D7 F66C 4F4E A0AA E526 7A6C
uid [ unknown] Launchpad PPA for Ondřej Surý

/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-cdimage.gpg

pub rsa4096 2012-05-11 [SC]
8439 38DF 228D 22F7 B374 2BC0 D94A A3F0 EFE2 1092
uid [ unknown] Ubuntu CD Image Automatic Signing Key (2012) [email protected]

/etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg

pub rsa4096 2018-09-17 [SC]
F6EC B376 2474 EDA9 D21B 7022 8719 20D1 991B C93C
uid [ unknown] Ubuntu Archive Automatic Signing Key (2018) [email protected]

~# apt-manage list ondrej_ubuntu_apache2.gpg
Traceback (most recent call last):
File "/usr/local/bin/apt-manage", line 90, in
main()
File "/usr/local/bin/apt-manage", line 86, in main
action[args.action](log, args, parser)
KeyError: 'list'

Typo in removal warning text

There is a typo in the remove subcommand warning text:

sudo apt-manage remove ppa-system76-pop -y
This will remzove the source ppa-system76-pop
          ^^^^^^^

This should read remove instead of remzove.

Repolib has issues with teamviewer source definition

While having teamviewer installed, repolib has issues parsing the file. apt does not have any issues with it.

The content of teamviewer.list

###   TeamViewer DEB repository list

### NOTE: Manual changes to this file
###        - prevent it from being updated by TeamViewer package updates
###        - will be lost after using the 'teamviewer repo' command
###       The original file can be restored with this command:
###       cp /opt/teamviewer/tv_bin/script/teamviewer.list /etc/apt/sources.list.d/teamviewer.list
###       which has the same effect as 'teamviewer repo default'

### NOTE: It is preferred to use the following commands to edit this file:
###       teamviewer repo                - show current repository configuration
###       teamviewer repo default        - restore default configuration
###       teamviewer repo disable        - disable the repository
###       teamviewer repo stable         - make all regular TeamViewer packages available (default)
###       teamviewer repo preview        - additionally, make feature preview packages available
###       teamviewer repo development    - additionally, make the latest development packages available


deb https://linux.teamviewer.com/deb stable main

# deb https://linux.teamviewer.com/deb preview main
# deb https://linux.teamviewer.com/deb development main

The stack-trace of repolib outputed by apt-manage -b:

Stack Trace:
  File "/usr/lib/python3/dist-packages/repolib/__init__.py", line 81, in get_all_sources
    source.load_from_file()
  File "/usr/lib/python3/dist-packages/repolib/legacy_deb.py", line 135, in load_from_file
    deb_src = deb.DebLine(line)
  File "/usr/lib/python3/dist-packages/repolib/deb.py", line 54, in __init__
    self._parse_debline(self.deb_line)
  File "/usr/lib/python3/dist-packages/repolib/deb.py", line 82, in _parse_debline
    self._validate(line)
  File "/usr/lib/python3/dist-packages/repolib/deb.py", line 133, in _validate
    raise util.RepoError(

add-apt-repository not available after removing software-properties-common

Based on the behavior observed while testing #43, it would make sense to conflict with software-properties-common since we provide our own versions of the tools that software-properties-common would provide.

Sidestepping the package manager and installing a link from /usr/lib/repolib/add-apt-repository to /usr/bin/add-apt-repository in a postinst script creates corner cases such as the command not being available if software-properties-common was installed when repolib was installed but is later removed.

Does not handle `sources.list` comments containing URLs

Issue

I like to put references inside my sources.list(5) files to the webpage that gave the installation instructions or other related references.

If I add any comment line containing a URL apt-manage considers the file to have a formatting error.

How to reproduce

Create a source.list(5) file with a URL as a comment, for example:

# /etc/apt/sources.list.d/github-cli.list
#
# GitHub CLI
#
# https://github.com/cli/cli/blob/trunk/docs/install_linux.md
#

deb [arch=amd64 signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main

Run apt-manage -bb:

apt-manage: DEBUG: Logging set up!
apt-manage: DEBUG: Arguments passed: Namespace(debug=2, action='list', repository=['x-repolib-all-sources'], verbose=False, legacy=False, names=False)
apt-manage: DEBUG: Got command: list
apt-manage: INFO: Debug mode set, not-saving any changes.
Configured sources:
apt-manage: DEBUG: Found source file system.sources
system - Pop_OS System Sources
apt-manage: DEBUG: Found source file winehq-jammy.sources
winehq-jammy -
apt-manage: DEBUG: Found source file pop-os-release.sources
pop-os-release - Pop_OS Release Sources
apt-manage: DEBUG: Found source file pop-os-apps.sources
pop-os-apps - Pop_OS Apps

The following files have formatting errors:
/etc/apt/sources.list.d/github-cli.list

Details for the failing files:
/etc/apt/sources.list.d/github-cli.list:
#
# GitHub CLI
#
# https://github.com/cli/cli/blob/trunk/docs/install_linux.md
#

deb [arch=amd64 signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main

Stack Trace:
  File "/usr/lib/python3/dist-packages/repolib/__init__.py", line 81, in get_all_sources
    source.load_from_file()
  File "/usr/lib/python3/dist-packages/repolib/legacy_deb.py", line 137, in load_from_file
    deb_src = deb.DebLine(line)
  File "/usr/lib/python3/dist-packages/repolib/deb.py", line 54, in __init__
    self._parse_debline(self.deb_line)
  File "/usr/lib/python3/dist-packages/repolib/deb.py", line 82, in _parse_debline
    self._validate(line)
  File "/usr/lib/python3/dist-packages/repolib/deb.py", line 133, in _validate
    raise util.RepoError

Remove the commented line with the URL and apt-manage exits normally.

Expected Behavior

Comments should be able to contain anything the user wants.

Additional info

apt-manage version: 1.5.2
$ cat /etc/os-release
NAME="Pop!_OS"
VERSION="22.04 LTS"
ID=pop
ID_LIKE="ubuntu debian"
PRETTY_NAME="Pop!_OS 22.04 LTS"
VERSION_ID="22.04"
HOME_URL="https://pop.system76.com"
SUPPORT_URL="https://support.system76.com"
BUG_REPORT_URL="https://github.com/pop-os/pop/issues"
PRIVACY_POLICY_URL="https://system76.com/privacy"
VERSION_CODENAME=jammy
UBUNTU_CODENAME=jammy
LOGO=distributor-logo-pop-os

Unable to run Edit Software Sources from Pop!_Shop

**Distribution (run cat /etc/os-release):
NAME="Pop!_OS"
VERSION="20.10"
ID=pop
ID_LIKE="ubuntu debian"
PRETTY_NAME="Pop!_OS 20.10"
VERSION_ID="20.10"
HOME_URL="https://pop.system76.com"
SUPPORT_URL="https://support.system76.com"
BUG_REPORT_URL="https://github.com/pop-os/pop/issues"
PRIVACY_POLICY_URL="https://system76.com/privacy"
VERSION_CODENAME=groovy
UBUNTU_CODENAME=groovy
LOGO=distributor-logo-pop-os

Related Application and/or Package Version (run apt policy $PACKAGE NAME):
Pop!_Shop - Edit Software Sources

Issue/Bug Description:
I try to open Edit Software Sources but when I click on the Edit Software Sources icon, the wheel spins and then stops.

Steps to reproduce (if you know):
I click on the Edit Software Sources icon, the wheel spins and then stops.

Expected behavior:
Open software sources

Other Notes:
I just upgraded from 19.10 to 20.10

Running Repoman from terminal gives the following:

(repoman:8883): Gtk-CRITICAL **: 08:42:20.952: gtk_widget_grab_default: assertion 'gtk_widget_get_can_default (widget)' failed
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/repoman/main.py", line 37, in do_activate
    self.win = Window()
  File "/usr/lib/python3/dist-packages/repoman/window.py", line 36, in __init__
    self.stack = Stack(self)
  File "/usr/lib/python3/dist-packages/repoman/stack.py", line 58, in __init__
    self.list_all = List(self)
  File "/usr/lib/python3/dist-packages/repoman/list.py", line 134, in __init__
    self.generate_entries()
  File "/usr/lib/python3/dist-packages/repoman/list.py", line 211, in generate_entries
    self.sources = repo.get_all_sources()
  File "/usr/lib/python3/dist-packages/repoman/repo.py", line 157, in get_all_sources
    source.load_from_file()
  File "/usr/lib/python3/dist-packages/repolib/legacy_deb.py", line 134, in load_from_file
    self.load_from_sources()
  File "/usr/lib/python3/dist-packages/repolib/legacy_deb.py", line 110, in load_from_sources
    self.make_names()
  File "/usr/lib/python3/dist-packages/repolib/legacy_deb.py", line 80, in make_names
    self.name = self.sources[0].make_

CI failing due to bionic build

The build failure on bionic seems to be in PPATestCase.test_suite(), and caused by 0f74753:

    def test_suite(self):
>       self.assertEqual(self.source.suites, [util.DISTRO_CODENAME])
E       AssertionError: Lists differ: ['Bionic', 'Beaver'] != ['Bionic Beaver']
E       
E       First differing element 0:
E       'Bionic'
E       'Bionic Beaver'
E       
E       First list contains 1 additional elements.
E       First extra element 1:
E       'Beaver'
E       
E       - ['Bionic', 'Beaver']
E       ?         ^^^^
E       
E       + ['Bionic Beaver']
E       ?         

I'm not sure if we're concerned about packaging this for Bionic. But if so, the build failure should probably be fixed. If not, Bionic builds should probably be disabled by adding a master_bionic branch without a debian directory.

Repolib doesn't error when adding an invalid popdev: shortcut

Adding a popdev staging branch shortcut doesn't cause an error if the shortcut is malformed. As an example:

apt-manage add popdev/linux-6.0.0

This will cause the shortcut to be truncated at the slash, causing Repolib to add the following (invalid) repository:

Name: Pop Development Branch
Enabled: yes
Types: deb
URIs: http://apt.pop-os.org/staging/
Suites: jammy
Components: main
Signed-By: /etc/apt/keyrings/popdev-archive-keyring.gpg

Instead, this should cause an error and not add the invalid repository.

Adding new PPAs causes Pubkey errors.

Distribution (run cat /etc/os-release):
Pop!_OS 20.10

Related Application and/or Package Version (run apt policy $PACKAGE NAME):
Tested the issue with Howdy : https://github.com/boltgolt/howdy
And Ubuntu Mainline :

Issue/Bug Description:
Adding 3rd party PPAs causes Pubkey errors.
The error message is as follows.

paul@pop-os:~$ sudo apt update
[sudo] password for paul: 
Hit:1 http://apt.pop-os.org/proprietary groovy InRelease
Hit:2 http://us.archive.ubuntu.com/ubuntu groovy InRelease                     
Get:3 http://ppa.launchpad.net/boltgolt/howdy/ubuntu groovy InRelease [18.0 kB]
Hit:4 http://us.archive.ubuntu.com/ubuntu groovy-security InRelease
Hit:5 http://us.archive.ubuntu.com/ubuntu groovy-updates InRelease
Err:3 http://ppa.launchpad.net/boltgolt/howdy/ubuntu groovy InRelease
  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 8CEBC97F3E9E1D58
Hit:6 http://us.archive.ubuntu.com/ubuntu groovy-backports InRelease
Reading package lists... Done
W: GPG error: http://ppa.launchpad.net/boltgolt/howdy/ubuntu groovy InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 8CEBC97F3E9E1D58
E: The repository 'http://ppa.launchpad.net/boltgolt/howdy/ubuntu groovy InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.

Steps to reproduce (if you know):
Add Howdy PPA via the Terminal or under extra sources in Pop Shop
Update the catalog by restarting Pop Shop or by typing
sudo apt update

Expected behavior:
Repo is updated and I can install Howdy

Other Notes:
I am certain this is a Pop!_OS issue and not an issue with the packages as this issue only happens with Pop!_OS. I cannot replicate this issue when using Ubuntu 20.10 and it's variants.

Quick install script or 'more complete' installation details

I have an answer in askubunu which is based on my success of installing apt-manage on Debian and Ubuntu systems in varied situations.

I think something more detailed about how to install would be a good thing to maintain in the project.
Maybe even a 'quick-install' script that can be invoked with curl.

Would the mintainers be open to such a PR?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.